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