mirror of https://github.com/grpc/grpc.git
commit
4dd536866e
89 changed files with 14737 additions and 2647 deletions
@ -0,0 +1,49 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __GRPC_SUPPORT_STRING_WIN32_H__ |
||||||
|
#define __GRPC_SUPPORT_STRING_WIN32_H__ |
||||||
|
|
||||||
|
#include <grpc/support/port_platform.h> |
||||||
|
|
||||||
|
#ifdef GPR_WIN32 |
||||||
|
|
||||||
|
#include <windows.h> |
||||||
|
|
||||||
|
/* These allocate new strings using gpr_malloc to convert from and to utf-8. */ |
||||||
|
LPTSTR gpr_char_to_tchar(LPCSTR input); |
||||||
|
LPSTR gpr_tchar_to_char(LPCTSTR input); |
||||||
|
|
||||||
|
#endif /* GPR_WIN32 */ |
||||||
|
|
||||||
|
#endif /* __GRPC_SUPPORT_STRING_WIN32_H__ */ |
@ -0,0 +1,13 @@ |
|||||||
|
#include <grpc/grpc.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
void grpc_call_details_init(grpc_call_details *cd) { |
||||||
|
memset(cd, 0, sizeof(*cd)); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_call_details_destroy(grpc_call_details *cd) { |
||||||
|
gpr_free(cd->method); |
||||||
|
gpr_free(cd->host); |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
#include <grpc/grpc.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
void grpc_metadata_array_init(grpc_metadata_array *array) { |
||||||
|
memset(array, 0, sizeof(*array)); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_metadata_array_destroy(grpc_metadata_array *array) { |
||||||
|
gpr_free(array->metadata); |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
using System; |
||||||
|
|
||||||
|
namespace Google.GRPC.Core |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// For serializing and deserializing messages. |
||||||
|
/// </summary> |
||||||
|
public interface IMarshaller<T> |
||||||
|
{ |
||||||
|
byte[] Serialize(T value); |
||||||
|
|
||||||
|
T Deserialize(byte[] payload); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// UTF-8 Marshalling for string. Useful for testing. |
||||||
|
/// </summary> |
||||||
|
internal class StringMarshaller : IMarshaller<string> { |
||||||
|
|
||||||
|
public byte[] Serialize(string value) |
||||||
|
{ |
||||||
|
return System.Text.Encoding.UTF8.GetBytes(value); |
||||||
|
} |
||||||
|
|
||||||
|
public string Deserialize(byte[] payload) |
||||||
|
{ |
||||||
|
return System.Text.Encoding.UTF8.GetString(payload); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,38 @@ |
|||||||
|
using System; |
||||||
|
using Google.GRPC.Core.Internal; |
||||||
|
|
||||||
|
namespace Google.GRPC.Core.Internal |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// Observer that writes all arriving messages to a call abstraction (in blocking fashion) |
||||||
|
/// and then halfcloses the call. Used for server-side call handling. |
||||||
|
/// </summary> |
||||||
|
internal class ServerWritingObserver<TWrite, TRead> : IObserver<TWrite> |
||||||
|
{ |
||||||
|
readonly AsyncCall<TWrite, TRead> call; |
||||||
|
|
||||||
|
public ServerWritingObserver(AsyncCall<TWrite, TRead> call) |
||||||
|
{ |
||||||
|
this.call = call; |
||||||
|
} |
||||||
|
|
||||||
|
public void OnCompleted() |
||||||
|
{ |
||||||
|
// TODO: how bad is the Wait here? |
||||||
|
call.WriteStatusAsync(new Status(StatusCode.GRPC_STATUS_OK, "")).Wait(); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnError(Exception error) |
||||||
|
{ |
||||||
|
// TODO: handle this... |
||||||
|
throw new InvalidOperationException("This should never be called."); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnNext(TWrite value) |
||||||
|
{ |
||||||
|
// TODO: how bad is the Wait here? |
||||||
|
call.WriteAsync(value).Wait(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,64 @@ |
|||||||
|
using System; |
||||||
|
|
||||||
|
namespace Google.GRPC.Core |
||||||
|
{ |
||||||
|
public enum MethodType |
||||||
|
{ |
||||||
|
Unary, |
||||||
|
ClientStreaming, |
||||||
|
ServerStreaming, |
||||||
|
DuplexStreaming |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// A description of a service method. |
||||||
|
/// </summary> |
||||||
|
public class Method<TRequest, TResponse> |
||||||
|
{ |
||||||
|
readonly MethodType type; |
||||||
|
readonly string name; |
||||||
|
readonly IMarshaller<TRequest> requestMarshaller; |
||||||
|
readonly IMarshaller<TResponse> responseMarshaller; |
||||||
|
|
||||||
|
public Method(MethodType type, string name, IMarshaller<TRequest> requestMarshaller, IMarshaller<TResponse> responseMarshaller) |
||||||
|
{ |
||||||
|
this.type = type; |
||||||
|
this.name = name; |
||||||
|
this.requestMarshaller = requestMarshaller; |
||||||
|
this.responseMarshaller = responseMarshaller; |
||||||
|
} |
||||||
|
|
||||||
|
public MethodType Type |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this.type; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public string Name |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this.name; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public IMarshaller<TRequest> RequestMarshaller |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this.requestMarshaller; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public IMarshaller<TResponse> ResponseMarshaller |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this.responseMarshaller; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,93 @@ |
|||||||
|
using System; |
||||||
|
using Google.GRPC.Core.Internal; |
||||||
|
|
||||||
|
namespace Google.GRPC.Core |
||||||
|
{ |
||||||
|
internal interface IServerCallHandler |
||||||
|
{ |
||||||
|
void StartCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq); |
||||||
|
} |
||||||
|
|
||||||
|
internal class UnaryRequestServerCallHandler<TRequest, TResponse> : IServerCallHandler |
||||||
|
{ |
||||||
|
readonly Method<TRequest, TResponse> method; |
||||||
|
readonly UnaryRequestServerMethod<TRequest, TResponse> handler; |
||||||
|
|
||||||
|
public UnaryRequestServerCallHandler(Method<TRequest, TResponse> method, UnaryRequestServerMethod<TRequest, TResponse> handler) |
||||||
|
{ |
||||||
|
this.method = method; |
||||||
|
this.handler = handler; |
||||||
|
} |
||||||
|
|
||||||
|
public void StartCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq) |
||||||
|
{ |
||||||
|
var asyncCall = new AsyncCall<TResponse, TRequest>( |
||||||
|
(msg) => method.ResponseMarshaller.Serialize(msg), |
||||||
|
(payload) => method.RequestMarshaller.Deserialize(payload)); |
||||||
|
|
||||||
|
asyncCall.InitializeServer(call); |
||||||
|
asyncCall.Accept(cq); |
||||||
|
|
||||||
|
var request = asyncCall.ReadAsync().Result; |
||||||
|
|
||||||
|
var responseObserver = new ServerWritingObserver<TResponse, TRequest>(asyncCall); |
||||||
|
handler(request, responseObserver); |
||||||
|
|
||||||
|
asyncCall.Halfclosed.Wait(); |
||||||
|
// TODO: wait until writing is finished |
||||||
|
|
||||||
|
asyncCall.WriteStatusAsync(new Status(StatusCode.GRPC_STATUS_OK, "")).Wait(); |
||||||
|
asyncCall.Finished.Wait(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class StreamingRequestServerCallHandler<TRequest, TResponse> : IServerCallHandler |
||||||
|
{ |
||||||
|
readonly Method<TRequest, TResponse> method; |
||||||
|
readonly StreamingRequestServerMethod<TRequest, TResponse> handler; |
||||||
|
|
||||||
|
public StreamingRequestServerCallHandler(Method<TRequest, TResponse> method, StreamingRequestServerMethod<TRequest, TResponse> handler) |
||||||
|
{ |
||||||
|
this.method = method; |
||||||
|
this.handler = handler; |
||||||
|
} |
||||||
|
|
||||||
|
public void StartCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq) |
||||||
|
{ |
||||||
|
var asyncCall = new AsyncCall<TResponse, TRequest>( |
||||||
|
(msg) => method.ResponseMarshaller.Serialize(msg), |
||||||
|
(payload) => method.RequestMarshaller.Deserialize(payload)); |
||||||
|
|
||||||
|
asyncCall.InitializeServer(call); |
||||||
|
asyncCall.Accept(cq); |
||||||
|
|
||||||
|
var responseObserver = new ServerWritingObserver<TResponse, TRequest>(asyncCall); |
||||||
|
var requestObserver = handler(responseObserver); |
||||||
|
|
||||||
|
// feed the requests |
||||||
|
asyncCall.StartReadingToStream(requestObserver); |
||||||
|
|
||||||
|
asyncCall.Halfclosed.Wait(); |
||||||
|
|
||||||
|
asyncCall.WriteStatusAsync(new Status(StatusCode.GRPC_STATUS_OK, "")).Wait(); |
||||||
|
asyncCall.Finished.Wait(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class NoSuchMethodCallHandler : IServerCallHandler |
||||||
|
{ |
||||||
|
public void StartCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq) |
||||||
|
{ |
||||||
|
// We don't care about the payload type here. |
||||||
|
AsyncCall<byte[], byte[]> asyncCall = new AsyncCall<byte[], byte[]>( |
||||||
|
(payload) => payload, (payload) => payload); |
||||||
|
|
||||||
|
asyncCall.InitializeServer(call); |
||||||
|
asyncCall.Accept(cq); |
||||||
|
asyncCall.WriteStatusAsync(new Status(StatusCode.GRPC_STATUS_UNIMPLEMENTED, "No such method.")).Wait(); |
||||||
|
|
||||||
|
asyncCall.Finished.Wait(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,25 @@ |
|||||||
|
using System; |
||||||
|
|
||||||
|
namespace Google.GRPC.Core |
||||||
|
{ |
||||||
|
// TODO: perhaps add also serverSideStreaming and clientSideStreaming |
||||||
|
|
||||||
|
public delegate void UnaryRequestServerMethod<TRequest, TResponse> (TRequest request, IObserver<TResponse> responseObserver); |
||||||
|
|
||||||
|
public delegate IObserver<TRequest> StreamingRequestServerMethod<TRequest, TResponse> (IObserver<TResponse> responseObserver); |
||||||
|
|
||||||
|
internal static class ServerCalls { |
||||||
|
|
||||||
|
public static IServerCallHandler UnaryRequestCall<TRequest, TResponse>(Method<TRequest, TResponse> method, UnaryRequestServerMethod<TRequest, TResponse> handler) |
||||||
|
{ |
||||||
|
return new UnaryRequestServerCallHandler<TRequest, TResponse>(method, handler); |
||||||
|
} |
||||||
|
|
||||||
|
public static IServerCallHandler StreamingRequestCall<TRequest, TResponse>(Method<TRequest, TResponse> method, StreamingRequestServerMethod<TRequest, TResponse> handler) |
||||||
|
{ |
||||||
|
return new StreamingRequestServerCallHandler<TRequest, TResponse>(method, handler); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,167 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
#include "test/core/end2end/tests/cancel_test_helpers.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Cancel after accept with a writes closed, no payload */ |
||||||
|
static void test_cancel_after_accept_and_writes_closed( |
||||||
|
grpc_end2end_test_config config, cancellation_mode mode) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(4))); |
||||||
|
cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(101))); |
||||||
|
cq_expect_empty_read(v_server, tag(101)); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c)); |
||||||
|
|
||||||
|
cq_expect_finished_with_status(v_client, tag(3), mode.expect_status, |
||||||
|
mode.expect_details, NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finished_with_status(v_server, tag(102), GRPC_STATUS_CANCELLED, |
||||||
|
NULL, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
unsigned i; |
||||||
|
|
||||||
|
for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) { |
||||||
|
test_cancel_after_accept_and_writes_closed(config, cancellation_modes[i]); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,159 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
#include "test/core/end2end/tests/cancel_test_helpers.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Cancel after accept, no payload */ |
||||||
|
static void test_cancel_after_accept(grpc_end2end_test_config config, |
||||||
|
cancellation_mode mode) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c)); |
||||||
|
|
||||||
|
cq_expect_finished_with_status(v_client, tag(3), mode.expect_status, |
||||||
|
mode.expect_details, NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finished_with_status(v_server, tag(102), GRPC_STATUS_CANCELLED, |
||||||
|
NULL, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
unsigned i; |
||||||
|
|
||||||
|
for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) { |
||||||
|
test_cancel_after_accept(config, cancellation_modes[i]); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,141 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
#include "test/core/end2end/tests/cancel_test_helpers.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Cancel after invoke, no payload */ |
||||||
|
static void test_cancel_after_invoke(grpc_end2end_test_config config, |
||||||
|
cancellation_mode mode) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c)); |
||||||
|
|
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), mode.expect_status, |
||||||
|
mode.expect_details, NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
unsigned i; |
||||||
|
|
||||||
|
for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) { |
||||||
|
test_cancel_after_invoke(config, cancellation_modes[i]); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,134 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Cancel before invoke */ |
||||||
|
static void test_cancel_before_invoke(grpc_end2end_test_config config) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_cancel(c)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_CANCELLED, NULL, |
||||||
|
NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_cancel_before_invoke(config); |
||||||
|
} |
@ -0,0 +1,131 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
#include "test/core/end2end/tests/cancel_test_helpers.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Cancel and do nothing */ |
||||||
|
static void test_cancel_in_a_vacuum(grpc_end2end_test_config config, |
||||||
|
cancellation_mode mode) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c)); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
unsigned i; |
||||||
|
|
||||||
|
for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) { |
||||||
|
test_cancel_in_a_vacuum(config, cancellation_modes[i]); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,178 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include "src/core/support/string.h" |
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, n_seconds_time(5)); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static void test_body(grpc_end2end_test_fixture f) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_timespec deadline = n_seconds_time(10); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
tag(1); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(4))); |
||||||
|
cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(5))); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(5), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_invoke_request_with_census( |
||||||
|
grpc_end2end_test_config config, const char *name, |
||||||
|
void (*body)(grpc_end2end_test_fixture f)) { |
||||||
|
char *fullname; |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
grpc_arg client_arg, server_arg; |
||||||
|
grpc_channel_args client_args, server_args; |
||||||
|
|
||||||
|
client_arg.type = GRPC_ARG_INTEGER; |
||||||
|
client_arg.key = GRPC_ARG_ENABLE_CENSUS; |
||||||
|
client_arg.value.integer = 1; |
||||||
|
|
||||||
|
client_args.num_args = 1; |
||||||
|
client_args.args = &client_arg; |
||||||
|
|
||||||
|
server_arg.type = GRPC_ARG_INTEGER; |
||||||
|
server_arg.key = GRPC_ARG_ENABLE_CENSUS; |
||||||
|
server_arg.value.integer = 1; |
||||||
|
server_args.num_args = 1; |
||||||
|
server_args.args = &server_arg; |
||||||
|
|
||||||
|
gpr_asprintf(&fullname, "%s/%s", __FUNCTION__, name); |
||||||
|
f = begin_test(config, fullname, &client_args, &server_args); |
||||||
|
body(f); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
gpr_free(fullname); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_invoke_request_with_census(config, "census_simple_request", test_body); |
||||||
|
} |
@ -0,0 +1,168 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f, |
||||||
|
cq_verifier *v_client, |
||||||
|
cq_verifier *v_server) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f->client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f->client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(4))); |
||||||
|
cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f->server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
/* should be able to shut down the server early
|
||||||
|
- and still complete the request */ |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(5))); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(5), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
} |
||||||
|
|
||||||
|
static void disappearing_server_test(grpc_end2end_test_config config) { |
||||||
|
grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
gpr_log(GPR_INFO, "%s/%s", __FUNCTION__, config.name); |
||||||
|
|
||||||
|
config.init_client(&f, NULL); |
||||||
|
config.init_server(&f, NULL); |
||||||
|
|
||||||
|
do_request_and_shutdown_server(&f, v_client, v_server); |
||||||
|
|
||||||
|
/* now destroy and recreate the server */ |
||||||
|
config.init_server(&f, NULL); |
||||||
|
|
||||||
|
do_request_and_shutdown_server(&f, v_client, v_server); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
if (config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION) { |
||||||
|
disappearing_server_test(config); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,159 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_early_server_shutdown_finishes_inflight_calls( |
||||||
|
grpc_end2end_test_config config) { |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(4))); |
||||||
|
cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
/* shutdown and destroy the server */ |
||||||
|
shutdown_server(&f); |
||||||
|
|
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNAVAILABLE, |
||||||
|
NULL, NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_early_server_shutdown_finishes_inflight_calls(config); |
||||||
|
} |
@ -0,0 +1,127 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_early_server_shutdown_finishes_tags( |
||||||
|
grpc_end2end_test_config config) { |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
grpc_call *s = (void *)1; |
||||||
|
|
||||||
|
/* upon shutdown, the server should finish all requested calls indicating
|
||||||
|
no new call */ |
||||||
|
grpc_server_request_call_old(f.server, tag(1000)); |
||||||
|
grpc_server_shutdown(f.server); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(1000), NULL, NULL, gpr_inf_past, |
||||||
|
NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
GPR_ASSERT(s == NULL); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_early_server_shutdown_finishes_tags(config); |
||||||
|
} |
@ -0,0 +1,160 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_early_server_shutdown_finishes_inflight_calls( |
||||||
|
grpc_end2end_test_config config) { |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(4))); |
||||||
|
cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
/* shutdown the server */ |
||||||
|
grpc_server_shutdown_and_notify(f.server, tag(0xdead)); |
||||||
|
cq_verify_empty(v_server); |
||||||
|
|
||||||
|
grpc_call_start_write_status_old(s, GRPC_STATUS_OK, NULL, tag(103)); |
||||||
|
grpc_call_destroy(s); |
||||||
|
cq_expect_finish_accepted(v_server, tag(103), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_expect_server_shutdown(v_server, tag(0xdead)); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_OK, NULL, NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_early_server_shutdown_finishes_inflight_calls(config); |
||||||
|
} |
@ -0,0 +1,183 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, n_seconds_time(5)); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_slice large_slice(void) { |
||||||
|
gpr_slice slice = gpr_slice_malloc(1000000); |
||||||
|
memset(GPR_SLICE_START_PTR(slice), 0xab, GPR_SLICE_LENGTH(slice)); |
||||||
|
return slice; |
||||||
|
} |
||||||
|
|
||||||
|
static void test_invoke_large_request(grpc_end2end_test_config config) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_slice request_payload_slice = large_slice(); |
||||||
|
grpc_byte_buffer *request_payload = |
||||||
|
grpc_byte_buffer_create(&request_payload_slice, 1); |
||||||
|
gpr_timespec deadline = n_seconds_time(30); |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
/* byte buffer holds the slice, we can unref it already */ |
||||||
|
gpr_slice_unref(request_payload_slice); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(c, request_payload, tag(4), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(request_payload); |
||||||
|
/* write should not be accepted until the server is willing to read the
|
||||||
|
request (as this request is very large) */ |
||||||
|
cq_verify_empty(v_client); |
||||||
|
|
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(5))); |
||||||
|
/* now the write can be accepted */ |
||||||
|
cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
cq_expect_read(v_server, tag(5), large_slice()); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(8))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(9))); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_client, tag(8), GRPC_OP_OK); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(9), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_invoke_large_request(config); |
||||||
|
} |
@ -0,0 +1,274 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static void simple_request_body(grpc_end2end_test_fixture f) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(4))); |
||||||
|
cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(5))); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(5), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_max_concurrent_streams(grpc_end2end_test_config config) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
grpc_arg server_arg; |
||||||
|
grpc_channel_args server_args; |
||||||
|
grpc_call *c1; |
||||||
|
grpc_call *c2; |
||||||
|
grpc_call *s1; |
||||||
|
grpc_call *s2; |
||||||
|
int live_call; |
||||||
|
gpr_timespec deadline; |
||||||
|
cq_verifier *v_client; |
||||||
|
cq_verifier *v_server; |
||||||
|
grpc_event *ev; |
||||||
|
|
||||||
|
server_arg.key = GRPC_ARG_MAX_CONCURRENT_STREAMS; |
||||||
|
server_arg.type = GRPC_ARG_INTEGER; |
||||||
|
server_arg.value.integer = 1; |
||||||
|
|
||||||
|
server_args.num_args = 1; |
||||||
|
server_args.args = &server_arg; |
||||||
|
|
||||||
|
f = begin_test(config, __FUNCTION__, NULL, &server_args); |
||||||
|
v_client = cq_verifier_create(f.client_cq); |
||||||
|
v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
/* perform a ping-pong to ensure that settings have had a chance to round
|
||||||
|
trip */ |
||||||
|
simple_request_body(f); |
||||||
|
/* perform another one to make sure that the one stream case still works */ |
||||||
|
simple_request_body(f); |
||||||
|
|
||||||
|
/* start two requests - ensuring that the second is not accepted until
|
||||||
|
the first completes */ |
||||||
|
deadline = five_seconds_time(); |
||||||
|
c1 = grpc_channel_create_call_old(f.client, "/alpha", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c1); |
||||||
|
c2 = grpc_channel_create_call_old(f.client, "/beta", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c1); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c1, f.client_cq, tag(301), tag(302), 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c2, f.client_cq, tag(401), tag(402), 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c1, tag(303))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c2, tag(303))); |
||||||
|
|
||||||
|
ev = grpc_completion_queue_next( |
||||||
|
f.client_cq, gpr_time_add(gpr_now(), gpr_time_from_seconds(10))); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
GPR_ASSERT(ev->type == GRPC_FINISH_ACCEPTED); |
||||||
|
GPR_ASSERT(ev->data.invoke_accepted == GRPC_OP_OK); |
||||||
|
/* The /alpha or /beta calls started above could be invoked (but NOT both);
|
||||||
|
* check this here */ |
||||||
|
/* We'll get tag 303 or 403, we want 300, 400 */ |
||||||
|
live_call = ((int)(gpr_intptr) ev->tag) - 3; |
||||||
|
grpc_event_finish(ev); |
||||||
|
|
||||||
|
cq_expect_server_rpc_new(v_server, &s1, tag(100), |
||||||
|
live_call == 300 ? "/alpha" : "/beta", |
||||||
|
"test.google.com", deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s1, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s1, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(live_call + 1), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_status_old(s1, GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", tag(103))); |
||||||
|
cq_expect_finish_accepted(v_server, tag(103), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
/* first request is finished, we should be able to start the second */ |
||||||
|
cq_expect_finished_with_status(v_client, tag(live_call + 2), |
||||||
|
GRPC_STATUS_UNIMPLEMENTED, "xyz", NULL); |
||||||
|
cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK); |
||||||
|
live_call = (live_call == 300) ? 400 : 300; |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(200))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s2, tag(200), |
||||||
|
live_call == 300 ? "/alpha" : "/beta", |
||||||
|
"test.google.com", deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s2, f.server_cq, tag(202))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s2, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(live_call + 1), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_status_old(s2, GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", tag(203))); |
||||||
|
cq_expect_finish_accepted(v_server, tag(203), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(202), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
cq_expect_finished_with_status(v_client, tag(live_call + 2), |
||||||
|
GRPC_STATUS_UNIMPLEMENTED, "xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c1); |
||||||
|
grpc_call_destroy(s1); |
||||||
|
grpc_call_destroy(c2); |
||||||
|
grpc_call_destroy(s2); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_max_concurrent_streams(config); |
||||||
|
} |
@ -0,0 +1,109 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_no_op(grpc_end2end_test_config config) { |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { test_no_op(config); } |
@ -0,0 +1,203 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Client pings and server pongs. Repeat messages rounds before finishing. */ |
||||||
|
static void test_pingpong_streaming(grpc_end2end_test_config config, |
||||||
|
int messages) { |
||||||
|
int i; |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s = NULL; |
||||||
|
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); |
||||||
|
gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); |
||||||
|
grpc_byte_buffer *request_payload = NULL; |
||||||
|
grpc_byte_buffer *response_payload = NULL; |
||||||
|
gpr_timespec deadline = n_seconds_time(messages * 5); |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
gpr_log(GPR_INFO, "testing with %d message pairs.", messages); |
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
|
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
|
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
for (i = 0; i < messages; i++) { |
||||||
|
request_payload = grpc_byte_buffer_create(&request_payload_slice, 1); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(c, request_payload, tag(2), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its
|
||||||
|
contents |
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(request_payload); |
||||||
|
cq_expect_write_accepted(v_client, tag(2), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(3))); |
||||||
|
cq_expect_read(v_server, tag(3), |
||||||
|
gpr_slice_from_copied_string("hello world")); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
response_payload = grpc_byte_buffer_create(&response_payload_slice, 1); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(s, response_payload, tag(4), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its
|
||||||
|
contents |
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(response_payload); |
||||||
|
cq_expect_write_accepted(v_server, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(c, tag(5))); |
||||||
|
cq_expect_read(v_client, tag(5), gpr_slice_from_copied_string("hello you")); |
||||||
|
cq_verify(v_client); |
||||||
|
} |
||||||
|
|
||||||
|
gpr_slice_unref(request_payload_slice); |
||||||
|
gpr_slice_unref(response_payload_slice); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(6))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(7))); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_client, tag(6), GRPC_OP_OK); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(7), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
int i; |
||||||
|
|
||||||
|
for (i = 1; i < 10; i++) { |
||||||
|
test_pingpong_streaming(config, i); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,222 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Request/response with metadata and payload.*/ |
||||||
|
static void test_request_response_with_metadata_and_payload( |
||||||
|
grpc_end2end_test_config config) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); |
||||||
|
gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); |
||||||
|
grpc_byte_buffer *request_payload = |
||||||
|
grpc_byte_buffer_create(&request_payload_slice, 1); |
||||||
|
grpc_byte_buffer *response_payload = |
||||||
|
grpc_byte_buffer_create(&response_payload_slice, 1); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
/* staggered lengths to ensure we hit various branches in base64 encode/decode
|
||||||
|
*/ |
||||||
|
grpc_metadata meta1 = { |
||||||
|
"key1-bin", "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", 13}; |
||||||
|
grpc_metadata meta2 = { |
||||||
|
"key2-bin", "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", |
||||||
|
14}; |
||||||
|
grpc_metadata meta3 = { |
||||||
|
"key3-bin", |
||||||
|
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee", 15}; |
||||||
|
grpc_metadata meta4 = { |
||||||
|
"key4-bin", |
||||||
|
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", 16}; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
|
||||||
|
/* byte buffer holds the slice, we can unref it already */ |
||||||
|
gpr_slice_unref(request_payload_slice); |
||||||
|
gpr_slice_unref(response_payload_slice); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
/* add multiple metadata */ |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(c, &meta1, 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(c, &meta2, 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(c, request_payload, tag(4), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(request_payload); |
||||||
|
cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_server_rpc_new( |
||||||
|
v_server, &s, tag(100), "/foo", "test.google.com", deadline, "key1-bin", |
||||||
|
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", "key2-bin", |
||||||
|
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102)); |
||||||
|
|
||||||
|
/* add multiple metadata */ |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(s, &meta3, 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(s, &meta4, 0)); |
||||||
|
|
||||||
|
grpc_call_server_end_initial_metadata_old(s, 0); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(5))); |
||||||
|
cq_expect_read(v_server, tag(5), gpr_slice_from_copied_string("hello world")); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(s, response_payload, tag(6), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(response_payload); |
||||||
|
cq_expect_write_accepted(v_server, tag(6), GRPC_OP_OK); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
/* fetch metadata.. */ |
||||||
|
cq_expect_client_metadata_read( |
||||||
|
v_client, tag(2), "key3-bin", |
||||||
|
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee", |
||||||
|
"key4-bin", |
||||||
|
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(c, tag(7))); |
||||||
|
cq_expect_read(v_client, tag(7), gpr_slice_from_copied_string("hello you")); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(8))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(9))); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_client, tag(8), GRPC_OP_OK); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(9), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_request_response_with_metadata_and_payload(config); |
||||||
|
} |
@ -0,0 +1,208 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Request/response with metadata and payload.*/ |
||||||
|
static void test_request_response_with_metadata_and_payload( |
||||||
|
grpc_end2end_test_config config) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); |
||||||
|
gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); |
||||||
|
grpc_byte_buffer *request_payload = |
||||||
|
grpc_byte_buffer_create(&request_payload_slice, 1); |
||||||
|
grpc_byte_buffer *response_payload = |
||||||
|
grpc_byte_buffer_create(&response_payload_slice, 1); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
grpc_metadata meta1 = {"key1", "val1", 4}; |
||||||
|
grpc_metadata meta2 = {"key2", "val2", 4}; |
||||||
|
grpc_metadata meta3 = {"key3", "val3", 4}; |
||||||
|
grpc_metadata meta4 = {"key4", "val4", 4}; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
|
||||||
|
/* byte buffer holds the slice, we can unref it already */ |
||||||
|
gpr_slice_unref(request_payload_slice); |
||||||
|
gpr_slice_unref(response_payload_slice); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
/* add multiple metadata */ |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(c, &meta1, 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(c, &meta2, 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(c, request_payload, tag(4), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(request_payload); |
||||||
|
cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, "key1", "val1", "key2", "val2", NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102)); |
||||||
|
|
||||||
|
/* add multiple metadata */ |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(s, &meta3, 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(s, &meta4, 0)); |
||||||
|
|
||||||
|
grpc_call_server_end_initial_metadata_old(s, 0); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(5))); |
||||||
|
cq_expect_read(v_server, tag(5), gpr_slice_from_copied_string("hello world")); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(s, response_payload, tag(6), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(response_payload); |
||||||
|
cq_expect_write_accepted(v_server, tag(6), GRPC_OP_OK); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
/* fetch metadata.. */ |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), "key3", "val3", "key4", |
||||||
|
"val4", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(c, tag(7))); |
||||||
|
cq_expect_read(v_client, tag(7), gpr_slice_from_copied_string("hello you")); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(8))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(9))); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_client, tag(8), GRPC_OP_OK); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(9), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_request_response_with_metadata_and_payload(config); |
||||||
|
} |
@ -0,0 +1,208 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static void request_response_with_payload(grpc_end2end_test_fixture f) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); |
||||||
|
gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); |
||||||
|
grpc_byte_buffer *request_payload = |
||||||
|
grpc_byte_buffer_create(&request_payload_slice, 1); |
||||||
|
grpc_byte_buffer *response_payload = |
||||||
|
grpc_byte_buffer_create(&response_payload_slice, 1); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
/* byte buffer holds the slice, we can unref it already */ |
||||||
|
gpr_slice_unref(request_payload_slice); |
||||||
|
gpr_slice_unref(response_payload_slice); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(c, request_payload, tag(4), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(request_payload); |
||||||
|
cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(5))); |
||||||
|
cq_expect_read(v_server, tag(5), gpr_slice_from_copied_string("hello world")); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(s, response_payload, tag(6), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(response_payload); |
||||||
|
cq_expect_write_accepted(v_server, tag(6), GRPC_OP_OK); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(c, tag(7))); |
||||||
|
cq_expect_read(v_client, tag(7), gpr_slice_from_copied_string("hello you")); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(8))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(9))); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_client, tag(8), GRPC_OP_OK); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(9), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
/* Client sends a request with payload, server reads then returns a response
|
||||||
|
payload and status. */ |
||||||
|
static void test_invoke_request_response_with_payload( |
||||||
|
grpc_end2end_test_config config) { |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
request_response_with_payload(f); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_invoke_10_request_response_with_payload( |
||||||
|
grpc_end2end_test_config config) { |
||||||
|
int i; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
for (i = 0; i < 10; i++) { |
||||||
|
request_response_with_payload(f); |
||||||
|
} |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_invoke_request_response_with_payload(config); |
||||||
|
test_invoke_10_request_response_with_payload(config); |
||||||
|
} |
@ -0,0 +1,213 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Request/response with metadata and payload.*/ |
||||||
|
static void test_request_response_with_metadata_and_payload( |
||||||
|
grpc_end2end_test_config config) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); |
||||||
|
gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); |
||||||
|
grpc_byte_buffer *request_payload = |
||||||
|
grpc_byte_buffer_create(&request_payload_slice, 1); |
||||||
|
grpc_byte_buffer *response_payload = |
||||||
|
grpc_byte_buffer_create(&response_payload_slice, 1); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
grpc_metadata meta1 = {"key1", "val1", 4}; |
||||||
|
grpc_metadata meta2 = {"key2", "val2", 4}; |
||||||
|
grpc_metadata meta3 = {"key3", "val3", 4}; |
||||||
|
grpc_metadata meta4 = {"key4", "val4", 4}; |
||||||
|
grpc_metadata meta5 = {"key5", "val5", 4}; |
||||||
|
grpc_metadata meta6 = {"key6", "val6", 4}; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
|
||||||
|
/* byte buffer holds the slice, we can unref it already */ |
||||||
|
gpr_slice_unref(request_payload_slice); |
||||||
|
gpr_slice_unref(response_payload_slice); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
/* add multiple metadata */ |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(c, &meta1, 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(c, &meta2, 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(c, request_payload, tag(4), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(request_payload); |
||||||
|
cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, "key1", "val1", "key2", "val2", NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102)); |
||||||
|
|
||||||
|
/* add multiple metadata */ |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(s, &meta3, 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(s, &meta4, 0)); |
||||||
|
|
||||||
|
grpc_call_server_end_initial_metadata_old(s, 0); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(s, &meta5, 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(s, &meta6, 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(5))); |
||||||
|
cq_expect_read(v_server, tag(5), gpr_slice_from_copied_string("hello world")); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(s, response_payload, tag(6), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(response_payload); |
||||||
|
cq_expect_write_accepted(v_server, tag(6), GRPC_OP_OK); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
/* fetch metadata.. */ |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), "key3", "val3", "key4", |
||||||
|
"val4", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(c, tag(7))); |
||||||
|
cq_expect_read(v_client, tag(7), gpr_slice_from_copied_string("hello you")); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(8))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(9))); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_client, tag(8), GRPC_OP_OK); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", "key5", "val5", "key6", "val6", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(9), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_request_response_with_metadata_and_payload(config); |
||||||
|
} |
@ -0,0 +1,172 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Request with a large amount of metadata.*/ |
||||||
|
static void test_request_with_large_metadata(grpc_end2end_test_config config) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
grpc_metadata meta; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
const int large_size = 64 * 1024; |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
|
||||||
|
meta.key = "key"; |
||||||
|
meta.value = gpr_malloc(large_size + 1); |
||||||
|
memset((char *)meta.value, 'a', large_size); |
||||||
|
((char*)meta.value)[large_size] = 0; |
||||||
|
meta.value_length = large_size; |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
/* add the metadata */ |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(c, &meta, 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, "key", meta.value, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
|
||||||
|
/* fetch metadata.. */ |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(8))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_status_old(s, GRPC_STATUS_OK, NULL, tag(9))); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_client, tag(8), GRPC_OP_OK); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_OK, NULL, NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(9), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
|
||||||
|
gpr_free((char *)meta.value); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_request_with_large_metadata(config); |
||||||
|
} |
@ -0,0 +1,172 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* Client sends a request with payload, server reads then returns status. */ |
||||||
|
static void test_invoke_request_with_payload(grpc_end2end_test_config config) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_slice payload_slice = gpr_slice_from_copied_string("hello world"); |
||||||
|
grpc_byte_buffer *payload = grpc_byte_buffer_create(&payload_slice, 1); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
/* byte buffer holds the slice, we can unref it already */ |
||||||
|
gpr_slice_unref(payload_slice); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_old(c, payload, tag(4), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(payload); |
||||||
|
cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(4))); |
||||||
|
cq_expect_read(v_server, tag(4), gpr_slice_from_copied_string("hello world")); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(5))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(6))); |
||||||
|
cq_expect_finish_accepted(v_client, tag(5), GRPC_OP_OK); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(6), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_invoke_request_with_payload(config); |
||||||
|
} |
@ -0,0 +1,175 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static void simple_delayed_request_body(grpc_end2end_test_config config, |
||||||
|
grpc_end2end_test_fixture *f, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args, |
||||||
|
long delay_us) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f->client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f->server_cq); |
||||||
|
|
||||||
|
config.init_client(f, client_args); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f->client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f->client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
config.init_server(f, server_args); |
||||||
|
|
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(4))); |
||||||
|
cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f->server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(5))); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(5), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_simple_delayed_request_short(grpc_end2end_test_config config) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
|
||||||
|
gpr_log(GPR_INFO, "%s/%s", __FUNCTION__, config.name); |
||||||
|
f = config.create_fixture(NULL, NULL); |
||||||
|
simple_delayed_request_body(config, &f, NULL, NULL, 100000); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_simple_delayed_request_long(grpc_end2end_test_config config) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
|
||||||
|
gpr_log(GPR_INFO, "%s/%s", __FUNCTION__, config.name); |
||||||
|
f = config.create_fixture(NULL, NULL); |
||||||
|
/* This timeout should be longer than a single retry */ |
||||||
|
simple_delayed_request_body(config, &f, NULL, NULL, 1500000); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
if (config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION) { |
||||||
|
test_simple_delayed_request_short(config); |
||||||
|
test_simple_delayed_request_long(config); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,232 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include "src/core/support/string.h" |
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
static void simple_request_body(grpc_end2end_test_fixture f) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(4))); |
||||||
|
cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(5))); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(5), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
/* an alternative ordering of the simple request body */ |
||||||
|
static void simple_request_body2(grpc_end2end_test_fixture f) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(4))); |
||||||
|
cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(5))); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(5), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_invoke_simple_request( |
||||||
|
grpc_end2end_test_config config, const char *name, |
||||||
|
void (*body)(grpc_end2end_test_fixture f)) { |
||||||
|
char *fullname; |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
|
||||||
|
gpr_asprintf(&fullname, "%s/%s", __FUNCTION__, name); |
||||||
|
|
||||||
|
f = begin_test(config, fullname, NULL, NULL); |
||||||
|
body(f); |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
gpr_free(fullname); |
||||||
|
} |
||||||
|
|
||||||
|
static void test_invoke_10_simple_requests(grpc_end2end_test_config config) { |
||||||
|
int i; |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
for (i = 0; i < 10; i++) { |
||||||
|
simple_request_body(f); |
||||||
|
gpr_log(GPR_INFO, "Passed simple request %d", i); |
||||||
|
} |
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_invoke_simple_request(config, "simple_request_body", |
||||||
|
simple_request_body); |
||||||
|
test_invoke_simple_request(config, "simple_request_body2", |
||||||
|
simple_request_body2); |
||||||
|
test_invoke_10_simple_requests(config); |
||||||
|
} |
@ -0,0 +1,324 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include "src/core/surface/event_string.h" |
||||||
|
#include "src/core/surface/completion_queue.h" |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/thd.h> |
||||||
|
|
||||||
|
#define SERVER_THREADS 16 |
||||||
|
#define CLIENT_THREADS 16 |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture g_fixture; |
||||||
|
static gpr_timespec g_test_end_time; |
||||||
|
static gpr_event g_client_done[CLIENT_THREADS]; |
||||||
|
static gpr_event g_server_done[SERVER_THREADS]; |
||||||
|
static gpr_mu g_mu; |
||||||
|
static int g_active_requests; |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
/* Drain pending events on a completion queue until it's ready to destroy.
|
||||||
|
Does some post-processing to safely release memory on some of the events. */ |
||||||
|
static void drain_cq(int client, grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
char *evstr; |
||||||
|
int done = 0; |
||||||
|
char *name = client ? "client" : "server"; |
||||||
|
while (!done) { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
if (!ev) { |
||||||
|
gpr_log(GPR_ERROR, "waiting for %s cq to drain", name); |
||||||
|
grpc_cq_dump_pending_ops(cq); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
evstr = grpc_event_string(ev); |
||||||
|
gpr_log(GPR_INFO, "got late %s event: %s", name, evstr); |
||||||
|
gpr_free(evstr); |
||||||
|
|
||||||
|
type = ev->type; |
||||||
|
switch (type) { |
||||||
|
case GRPC_SERVER_RPC_NEW: |
||||||
|
gpr_free(ev->tag); |
||||||
|
if (ev->call) { |
||||||
|
grpc_call_destroy(ev->call); |
||||||
|
} |
||||||
|
break; |
||||||
|
case GRPC_FINISHED: |
||||||
|
grpc_call_destroy(ev->call); |
||||||
|
break; |
||||||
|
case GRPC_QUEUE_SHUTDOWN: |
||||||
|
done = 1; |
||||||
|
break; |
||||||
|
case GRPC_READ: |
||||||
|
case GRPC_WRITE_ACCEPTED: |
||||||
|
if (!client && gpr_unref(ev->tag)) { |
||||||
|
gpr_free(ev->tag); |
||||||
|
} |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
grpc_event_finish(ev); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* Kick off a new request - assumes g_mu taken */ |
||||||
|
static void start_request(void) { |
||||||
|
gpr_slice slice = gpr_slice_malloc(100); |
||||||
|
grpc_byte_buffer *buf; |
||||||
|
grpc_call *call = grpc_channel_create_call_old( |
||||||
|
g_fixture.client, "/Foo", "test.google.com", g_test_end_time); |
||||||
|
|
||||||
|
memset(GPR_SLICE_START_PTR(slice), 1, GPR_SLICE_LENGTH(slice)); |
||||||
|
buf = grpc_byte_buffer_create(&slice, 1); |
||||||
|
gpr_slice_unref(slice); |
||||||
|
|
||||||
|
g_active_requests++; |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(call, g_fixture.client_cq, NULL, NULL, 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(call, NULL)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_old(call, buf, NULL, 0)); |
||||||
|
|
||||||
|
grpc_byte_buffer_destroy(buf); |
||||||
|
} |
||||||
|
|
||||||
|
/* Async client: handle sending requests, reading responses, and starting
|
||||||
|
new requests when old ones finish */ |
||||||
|
static void client_thread(void *p) { |
||||||
|
gpr_intptr id = (gpr_intptr)p; |
||||||
|
grpc_event *ev; |
||||||
|
char *estr; |
||||||
|
|
||||||
|
for (;;) { |
||||||
|
ev = grpc_completion_queue_next(g_fixture.client_cq, n_seconds_time(1)); |
||||||
|
if (ev) { |
||||||
|
switch (ev->type) { |
||||||
|
default: |
||||||
|
estr = grpc_event_string(ev); |
||||||
|
gpr_log(GPR_ERROR, "unexpected event: %s", estr); |
||||||
|
gpr_free(estr); |
||||||
|
break; |
||||||
|
case GRPC_READ: |
||||||
|
break; |
||||||
|
case GRPC_WRITE_ACCEPTED: |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(ev->call, NULL)); |
||||||
|
break; |
||||||
|
case GRPC_FINISH_ACCEPTED: |
||||||
|
break; |
||||||
|
case GRPC_CLIENT_METADATA_READ: |
||||||
|
break; |
||||||
|
case GRPC_FINISHED: |
||||||
|
/* kick off a new request if the test should still be running */ |
||||||
|
gpr_mu_lock(&g_mu); |
||||||
|
g_active_requests--; |
||||||
|
if (gpr_time_cmp(gpr_now(), g_test_end_time) < 0) { |
||||||
|
start_request(); |
||||||
|
} |
||||||
|
gpr_mu_unlock(&g_mu); |
||||||
|
grpc_call_destroy(ev->call); |
||||||
|
break; |
||||||
|
} |
||||||
|
grpc_event_finish(ev); |
||||||
|
} |
||||||
|
gpr_mu_lock(&g_mu); |
||||||
|
if (g_active_requests == 0) { |
||||||
|
gpr_mu_unlock(&g_mu); |
||||||
|
break; |
||||||
|
} |
||||||
|
gpr_mu_unlock(&g_mu); |
||||||
|
} |
||||||
|
|
||||||
|
gpr_event_set(&g_client_done[id], (void *)1); |
||||||
|
} |
||||||
|
|
||||||
|
/* Request a new server call. We tag them with a ref-count that starts at two,
|
||||||
|
and decrements after each of: a read completes and a write completes. |
||||||
|
When it drops to zero, we write status */ |
||||||
|
static void request_server_call(void) { |
||||||
|
gpr_refcount *rc = gpr_malloc(sizeof(gpr_refcount)); |
||||||
|
gpr_ref_init(rc, 2); |
||||||
|
grpc_server_request_call_old(g_fixture.server, rc); |
||||||
|
} |
||||||
|
|
||||||
|
static void maybe_end_server_call(grpc_call *call, gpr_refcount *rc) { |
||||||
|
if (gpr_unref(rc)) { |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
call, GRPC_STATUS_OK, NULL, NULL)); |
||||||
|
gpr_free(rc); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void server_thread(void *p) { |
||||||
|
int id = (gpr_intptr)p; |
||||||
|
gpr_slice slice = gpr_slice_malloc(100); |
||||||
|
grpc_byte_buffer *buf; |
||||||
|
grpc_event *ev; |
||||||
|
char *estr; |
||||||
|
|
||||||
|
memset(GPR_SLICE_START_PTR(slice), 1, GPR_SLICE_LENGTH(slice)); |
||||||
|
buf = grpc_byte_buffer_create(&slice, 1); |
||||||
|
gpr_slice_unref(slice); |
||||||
|
|
||||||
|
request_server_call(); |
||||||
|
|
||||||
|
for (;;) { |
||||||
|
ev = grpc_completion_queue_next(g_fixture.server_cq, n_seconds_time(1)); |
||||||
|
if (ev) { |
||||||
|
switch (ev->type) { |
||||||
|
default: |
||||||
|
estr = grpc_event_string(ev); |
||||||
|
gpr_log(GPR_ERROR, "unexpected event: %s", estr); |
||||||
|
gpr_free(estr); |
||||||
|
break; |
||||||
|
case GRPC_SERVER_RPC_NEW: |
||||||
|
if (ev->call) { |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old( |
||||||
|
ev->call, g_fixture.server_cq, ev->tag)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_end_initial_metadata_old(ev->call, 0)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_read_old(ev->call, ev->tag)); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(ev->call, buf, ev->tag, 0)); |
||||||
|
} else { |
||||||
|
gpr_free(ev->tag); |
||||||
|
} |
||||||
|
break; |
||||||
|
case GRPC_READ: |
||||||
|
if (ev->data.read) { |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_read_old(ev->call, ev->tag)); |
||||||
|
} else { |
||||||
|
maybe_end_server_call(ev->call, ev->tag); |
||||||
|
} |
||||||
|
break; |
||||||
|
case GRPC_WRITE_ACCEPTED: |
||||||
|
maybe_end_server_call(ev->call, ev->tag); |
||||||
|
break; |
||||||
|
case GRPC_FINISH_ACCEPTED: |
||||||
|
break; |
||||||
|
case GRPC_FINISHED: |
||||||
|
grpc_call_destroy(ev->call); |
||||||
|
request_server_call(); |
||||||
|
break; |
||||||
|
} |
||||||
|
grpc_event_finish(ev); |
||||||
|
} |
||||||
|
gpr_mu_lock(&g_mu); |
||||||
|
if (g_active_requests == 0) { |
||||||
|
gpr_mu_unlock(&g_mu); |
||||||
|
break; |
||||||
|
} |
||||||
|
gpr_mu_unlock(&g_mu); |
||||||
|
} |
||||||
|
|
||||||
|
grpc_byte_buffer_destroy(buf); |
||||||
|
gpr_event_set(&g_server_done[id], (void *)1); |
||||||
|
} |
||||||
|
|
||||||
|
static void run_test(grpc_end2end_test_config config, int requests_in_flight) { |
||||||
|
int i; |
||||||
|
gpr_thd_id thd_id; |
||||||
|
|
||||||
|
gpr_log(GPR_INFO, "thread_stress_test/%s @ %d requests", config.name, |
||||||
|
requests_in_flight); |
||||||
|
|
||||||
|
/* setup client, server */ |
||||||
|
g_fixture = config.create_fixture(NULL, NULL); |
||||||
|
config.init_client(&g_fixture, NULL); |
||||||
|
config.init_server(&g_fixture, NULL); |
||||||
|
|
||||||
|
/* schedule end time */ |
||||||
|
g_test_end_time = n_seconds_time(5); |
||||||
|
|
||||||
|
g_active_requests = 0; |
||||||
|
gpr_mu_init(&g_mu); |
||||||
|
|
||||||
|
/* kick off threads */ |
||||||
|
for (i = 0; i < CLIENT_THREADS; i++) { |
||||||
|
gpr_event_init(&g_client_done[i]); |
||||||
|
gpr_thd_new(&thd_id, client_thread, (void *)(gpr_intptr)i, NULL); |
||||||
|
} |
||||||
|
for (i = 0; i < SERVER_THREADS; i++) { |
||||||
|
gpr_event_init(&g_server_done[i]); |
||||||
|
gpr_thd_new(&thd_id, server_thread, (void *)(gpr_intptr)i, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
/* start requests */ |
||||||
|
gpr_mu_lock(&g_mu); |
||||||
|
for (i = 0; i < requests_in_flight; i++) { |
||||||
|
start_request(); |
||||||
|
} |
||||||
|
gpr_mu_unlock(&g_mu); |
||||||
|
|
||||||
|
/* await completion */ |
||||||
|
for (i = 0; i < CLIENT_THREADS; i++) { |
||||||
|
gpr_event_wait(&g_client_done[i], gpr_inf_future); |
||||||
|
} |
||||||
|
for (i = 0; i < SERVER_THREADS; i++) { |
||||||
|
gpr_event_wait(&g_server_done[i], gpr_inf_future); |
||||||
|
} |
||||||
|
|
||||||
|
/* shutdown the things */ |
||||||
|
grpc_server_shutdown(g_fixture.server); |
||||||
|
grpc_server_destroy(g_fixture.server); |
||||||
|
grpc_channel_destroy(g_fixture.client); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(g_fixture.server_cq); |
||||||
|
drain_cq(0, g_fixture.server_cq); |
||||||
|
grpc_completion_queue_destroy(g_fixture.server_cq); |
||||||
|
grpc_completion_queue_shutdown(g_fixture.client_cq); |
||||||
|
drain_cq(1, g_fixture.client_cq); |
||||||
|
grpc_completion_queue_destroy(g_fixture.client_cq); |
||||||
|
|
||||||
|
config.tear_down_data(&g_fixture); |
||||||
|
|
||||||
|
gpr_mu_destroy(&g_mu); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
run_test(config, 1000); |
||||||
|
} |
@ -0,0 +1,199 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2014, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/core/end2end/end2end_tests.h" |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/byte_buffer.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include "test/core/end2end/cq_verifier.h" |
||||||
|
|
||||||
|
enum { TIMEOUT = 200000 }; |
||||||
|
|
||||||
|
static void *tag(gpr_intptr t) { return (void *)t; } |
||||||
|
|
||||||
|
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||||
|
const char *test_name, |
||||||
|
grpc_channel_args *client_args, |
||||||
|
grpc_channel_args *server_args) { |
||||||
|
grpc_end2end_test_fixture f; |
||||||
|
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||||
|
f = config.create_fixture(client_args, server_args); |
||||||
|
config.init_client(&f, client_args); |
||||||
|
config.init_server(&f, server_args); |
||||||
|
return f; |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec n_seconds_time(int n) { |
||||||
|
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); |
||||||
|
} |
||||||
|
|
||||||
|
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||||
|
|
||||||
|
static void drain_cq(grpc_completion_queue *cq) { |
||||||
|
grpc_event *ev; |
||||||
|
grpc_completion_type type; |
||||||
|
do { |
||||||
|
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||||
|
GPR_ASSERT(ev); |
||||||
|
type = ev->type; |
||||||
|
grpc_event_finish(ev); |
||||||
|
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->server) return; |
||||||
|
grpc_server_shutdown(f->server); |
||||||
|
grpc_server_destroy(f->server); |
||||||
|
f->server = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||||
|
if (!f->client) return; |
||||||
|
grpc_channel_destroy(f->client); |
||||||
|
f->client = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void end_test(grpc_end2end_test_fixture *f) { |
||||||
|
shutdown_server(f); |
||||||
|
shutdown_client(f); |
||||||
|
|
||||||
|
grpc_completion_queue_shutdown(f->server_cq); |
||||||
|
drain_cq(f->server_cq); |
||||||
|
grpc_completion_queue_destroy(f->server_cq); |
||||||
|
grpc_completion_queue_shutdown(f->client_cq); |
||||||
|
drain_cq(f->client_cq); |
||||||
|
grpc_completion_queue_destroy(f->client_cq); |
||||||
|
} |
||||||
|
|
||||||
|
/* test the case when there is a pending message at the client side,
|
||||||
|
writes_done should not return a status without a start_read. |
||||||
|
Note: this test will last for 3s. Do not run in a loop. */ |
||||||
|
static void test_writes_done_hangs_with_pending_read( |
||||||
|
grpc_end2end_test_config config) { |
||||||
|
grpc_call *c; |
||||||
|
grpc_call *s; |
||||||
|
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); |
||||||
|
gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); |
||||||
|
grpc_byte_buffer *request_payload = |
||||||
|
grpc_byte_buffer_create(&request_payload_slice, 1); |
||||||
|
grpc_byte_buffer *response_payload = |
||||||
|
grpc_byte_buffer_create(&response_payload_slice, 1); |
||||||
|
gpr_timespec deadline = five_seconds_time(); |
||||||
|
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); |
||||||
|
cq_verifier *v_client = cq_verifier_create(f.client_cq); |
||||||
|
cq_verifier *v_server = cq_verifier_create(f.server_cq); |
||||||
|
|
||||||
|
/* byte buffer holds the slice, we can unref it already */ |
||||||
|
gpr_slice_unref(request_payload_slice); |
||||||
|
gpr_slice_unref(response_payload_slice); |
||||||
|
|
||||||
|
c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com", |
||||||
|
deadline); |
||||||
|
GPR_ASSERT(c); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(c, request_payload, tag(4), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(request_payload); |
||||||
|
cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); |
||||||
|
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", |
||||||
|
deadline, NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_server_accept_old(s, f.server_cq, tag(102))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_end_initial_metadata_old(s, 0)); |
||||||
|
cq_expect_client_metadata_read(v_client, tag(2), NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(5))); |
||||||
|
cq_expect_read(v_server, tag(5), gpr_slice_from_copied_string("hello world")); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == |
||||||
|
grpc_call_start_write_old(s, response_payload, tag(6), 0)); |
||||||
|
/* destroy byte buffer early to ensure async code keeps track of its contents
|
||||||
|
correctly */ |
||||||
|
grpc_byte_buffer_destroy(response_payload); |
||||||
|
cq_expect_write_accepted(v_server, tag(6), GRPC_OP_OK); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(6))); |
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status_old( |
||||||
|
s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(7))); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_client, tag(6), GRPC_OP_OK); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
/* does not return status because there is a pending message to be read */ |
||||||
|
cq_verify_empty(v_client); |
||||||
|
|
||||||
|
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(c, tag(8))); |
||||||
|
cq_expect_read(v_client, tag(8), gpr_slice_from_copied_string("hello you")); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED, |
||||||
|
"xyz", NULL); |
||||||
|
cq_verify(v_client); |
||||||
|
|
||||||
|
cq_expect_finish_accepted(v_server, tag(7), GRPC_OP_OK); |
||||||
|
cq_expect_finished(v_server, tag(102), NULL); |
||||||
|
cq_verify(v_server); |
||||||
|
|
||||||
|
grpc_call_destroy(c); |
||||||
|
grpc_call_destroy(s); |
||||||
|
|
||||||
|
end_test(&f); |
||||||
|
config.tear_down_data(&f); |
||||||
|
|
||||||
|
cq_verifier_destroy(v_client); |
||||||
|
cq_verifier_destroy(v_server); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||||
|
test_writes_done_hangs_with_pending_read(config); |
||||||
|
} |
Loading…
Reference in new issue