merge with head

pull/1464/head
Yang Gao 10 years ago
commit ea13af73e0
  1. 3
      .travis.yml
  2. 6
      BUILD
  3. 7136
      Makefile
  4. 49
      build.json
  5. 138
      include/grpc/grpc.h
  6. 2
      src/core/iomgr/pollset_posix.c
  7. 20
      src/core/iomgr/tcp_posix.c
  8. 41
      src/core/profiling/basic_timers.c
  9. 6
      src/core/profiling/stap_probes.d
  10. 57
      src/core/profiling/stap_timers.c
  11. 90
      src/core/profiling/timers.h
  12. 12
      src/core/support/cpu_windows.c
  13. 333
      src/core/surface/call.c
  14. 7
      src/core/surface/channel.c
  15. 96
      src/core/surface/completion_queue.c
  16. 41
      src/core/surface/completion_queue.h
  17. 45
      src/core/surface/event_string.c
  18. 4
      src/core/surface/init.c
  19. 64
      src/core/surface/server.c
  20. 10
      src/core/transport/chttp2/stream_encoder.c
  21. 6
      src/cpp/client/channel.cc
  22. 8
      src/cpp/common/call.cc
  23. 2
      src/cpp/common/completion_queue.cc
  24. 1
      src/cpp/proto/proto_utils.cc
  25. 8
      src/cpp/server/server.cc
  26. 10
      src/csharp/ext/grpc_csharp_ext.c
  27. 3
      src/php/composer.json
  28. 302
      src/php/composer.lock
  29. 89
      src/php/tests/interop/interop_client.php
  30. 2
      src/python/src/grpc/_adapter/_call.h
  31. 2
      src/python/src/grpc/_adapter/_channel.h
  32. 2
      src/python/src/grpc/_adapter/_client_credentials.h
  33. 4
      src/python/src/grpc/_adapter/_completion_queue.c
  34. 2
      src/python/src/grpc/_adapter/_completion_queue.h
  35. 2
      src/python/src/grpc/_adapter/_server_credentials.h
  36. 2
      src/python/src/grpc/_adapter/_tag.h
  37. 2
      src/python/src/setup.py
  38. 66
      templates/Makefile.template
  39. 4
      templates/vsprojects/Grpc.mak.template
  40. 42
      test/build/systemtap.c
  41. 138
      test/core/echo/client.c
  42. 135
      test/core/echo/echo_test.c
  43. 223
      test/core/echo/server.c
  44. 220
      test/core/end2end/cq_verifier.c
  45. 13
      test/core/end2end/cq_verifier.h
  46. 96
      test/core/end2end/dualstack_socket_test.c
  47. 27
      test/core/end2end/gen_build_json.py
  48. 34
      test/core/end2end/no_server_test.c
  49. 8
      test/core/end2end/tests/cancel_after_accept.c
  50. 110
      test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
  51. 167
      test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c
  52. 159
      test/core/end2end/tests/cancel_after_accept_legacy.c
  53. 141
      test/core/end2end/tests/cancel_after_invoke_legacy.c
  54. 134
      test/core/end2end/tests/cancel_before_invoke_legacy.c
  55. 131
      test/core/end2end/tests/cancel_in_a_vacuum_legacy.c
  56. 94
      test/core/end2end/tests/census_simple_request.c
  57. 178
      test/core/end2end/tests/census_simple_request_legacy.c
  58. 95
      test/core/end2end/tests/disappearing_server.c
  59. 168
      test/core/end2end/tests/disappearing_server_legacy.c
  60. 85
      test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
  61. 159
      test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c
  62. 13
      test/core/end2end/tests/early_server_shutdown_finishes_tags.c
  63. 127
      test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c
  64. 97
      test/core/end2end/tests/graceful_server_shutdown.c
  65. 160
      test/core/end2end/tests/graceful_server_shutdown_legacy.c
  66. 139
      test/core/end2end/tests/invoke_large_request.c
  67. 183
      test/core/end2end/tests/invoke_large_request_legacy.c
  68. 272
      test/core/end2end/tests/max_concurrent_streams.c
  69. 274
      test/core/end2end/tests/max_concurrent_streams_legacy.c
  70. 109
      test/core/end2end/tests/no_op_legacy.c
  71. 165
      test/core/end2end/tests/ping_pong_streaming.c
  72. 203
      test/core/end2end/tests/ping_pong_streaming_legacy.c
  73. 231
      test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c
  74. 208
      test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c
  75. 208
      test/core/end2end/tests/request_response_with_payload_legacy.c
  76. 213
      test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c
  77. 172
      test/core/end2end/tests/request_with_large_metadata_legacy.c
  78. 172
      test/core/end2end/tests/request_with_payload_legacy.c
  79. 175
      test/core/end2end/tests/simple_delayed_request_legacy.c
  80. 232
      test/core/end2end/tests/simple_request_legacy.c
  81. 325
      test/core/end2end/tests/thread_stress.c
  82. 325
      test/core/end2end/tests/thread_stress_legacy.c
  83. 199
      test/core/end2end/tests/writes_done_hangs_with_pending_read.c
  84. 199
      test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c
  85. 11
      test/core/fling/server.c
  86. 40
      test/core/profiling/mark_timings.stp
  87. 4
      test/core/profiling/timers_test.c
  88. 118
      test/core/surface/completion_queue_test.c
  89. 39
      test/core/surface/lame_client_test.c
  90. 14
      test/cpp/end2end/end2end_test.cc
  91. 3157
      tools/run_tests/tests.json
  92. 812
      vsprojects/Grpc.mak
  93. 4
      vsprojects/grpc/grpc.vcxproj
  94. 5
      vsprojects/grpc/grpc.vcxproj.filters
  95. 4
      vsprojects/grpc_unsecure/grpc_unsecure.vcxproj
  96. 5
      vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters

@ -18,13 +18,12 @@ env:
- NUGET="mono nuget.exe"
matrix:
- CONFIG=opt TEST=sanity
- CONFIG=dbg TEST="c c++"
- CONFIG=gcov TEST="c c++"
- CONFIG=opt TEST="c c++"
- CONFIG=opt TEST=node
- CONFIG=opt TEST=ruby
- CONFIG=opt TEST=python
- CONFIG=opt TEST=csharp
- CONFIG=gcov TEST="c c++"
- USE_GCC=4.4 CONFIG=opt TEST=build
- USE_GCC=4.5 CONFIG=opt TEST=build
script:

@ -296,7 +296,8 @@ cc_library(
"src/core/json/json_reader.c",
"src/core/json/json_string.c",
"src/core/json/json_writer.c",
"src/core/profiling/timers.c",
"src/core/profiling/basic_timers.c",
"src/core/profiling/stap_timers.c",
"src/core/statistics/census_init.c",
"src/core/statistics/census_log.c",
"src/core/statistics/census_rpc_stats.c",
@ -503,7 +504,8 @@ cc_library(
"src/core/json/json_reader.c",
"src/core/json/json_string.c",
"src/core/json/json_writer.c",
"src/core/profiling/timers.c",
"src/core/profiling/basic_timers.c",
"src/core/profiling/stap_timers.c",
"src/core/statistics/census_init.c",
"src/core/statistics/census_log.c",
"src/core/statistics/census_rpc_stats.c",

7136
Makefile

File diff suppressed because one or more lines are too long

@ -6,7 +6,7 @@
"#": "The public version number of the library.",
"version": {
"major": 0,
"minor": 6,
"minor": 7,
"micro": 0,
"build": 0
}
@ -231,7 +231,8 @@
"src/core/json/json_reader.c",
"src/core/json/json_string.c",
"src/core/json/json_writer.c",
"src/core/profiling/timers.c",
"src/core/profiling/basic_timers.c",
"src/core/profiling/stap_timers.c",
"src/core/statistics/census_init.c",
"src/core/statistics/census_log.c",
"src/core/statistics/census_rpc_stats.c",
@ -982,50 +983,6 @@
"posix"
]
},
{
"name": "echo_client",
"build": "test",
"run": false,
"language": "c",
"src": [
"test/core/echo/client.c"
],
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
{
"name": "echo_server",
"build": "test",
"run": false,
"language": "c",
"src": [
"test/core/echo/server.c"
],
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
{
"name": "echo_test",
"build": "test",
"language": "c",
"src": [
"test/core/echo/echo_test.c"
],
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
{
"name": "fd_posix_test",
"build": "test",

@ -198,15 +198,6 @@ typedef struct grpc_metadata {
typedef enum grpc_completion_type {
GRPC_QUEUE_SHUTDOWN, /* Shutting down */
GRPC_OP_COMPLETE, /* operation completion */
GRPC_READ, /* A read has completed */
GRPC_WRITE_ACCEPTED, /* A write has been accepted by
flow control */
GRPC_FINISH_ACCEPTED, /* writes_done or write_status has been accepted */
GRPC_CLIENT_METADATA_READ, /* The metadata array sent by server received at
client */
GRPC_FINISHED, /* An RPC has finished. The event contains status.
On the server this will be OK or Cancelled. */
GRPC_SERVER_RPC_NEW, /* A new RPC has arrived at the server */
GRPC_SERVER_SHUTDOWN, /* The server has finished shutting down */
GRPC_COMPLETION_DO_NOT_USE /* must be last, forces users to include
a default: case */
@ -219,30 +210,7 @@ typedef struct grpc_event {
/* Data associated with the completion type. Field names match the type of
completion as listed in grpc_completion_type. */
union {
/* Contains a pointer to the buffer that was read, or NULL at the end of a
stream. */
grpc_byte_buffer *read;
grpc_op_error write_accepted;
grpc_op_error finish_accepted;
grpc_op_error invoke_accepted;
grpc_op_error op_complete;
struct {
size_t count;
grpc_metadata *elements;
} client_metadata_read;
struct {
grpc_status_code status;
const char *details;
size_t metadata_count;
grpc_metadata *metadata_elements;
} finished;
struct {
const char *method;
const char *host;
gpr_timespec deadline;
size_t metadata_count;
grpc_metadata *metadata_elements;
} server_rpc_new;
} data;
} grpc_event;
@ -413,13 +381,6 @@ void grpc_completion_queue_shutdown(grpc_completion_queue *cq);
drained and no threads are executing grpc_completion_queue_next */
void grpc_completion_queue_destroy(grpc_completion_queue *cq);
/* Create a call given a grpc_channel, in order to call 'method'. The request
is not sent until grpc_call_invoke is called. All completions are sent to
'completion_queue'. */
grpc_call *grpc_channel_create_call_old(grpc_channel *channel,
const char *method, const char *host,
gpr_timespec deadline);
/* Create a call given a grpc_channel, in order to call 'method'. The request
is not sent until grpc_call_invoke is called. All completions are sent to
'completion_queue'. */
@ -475,48 +436,6 @@ void grpc_channel_destroy(grpc_channel *channel);
If a grpc_call fails, it's guaranteed that no change to the call state
has been made. */
/* Add a single metadata element to the call, to be sent upon invocation.
flags is a bit-field combination of the write flags defined above.
REQUIRES: grpc_call_start_invoke/grpc_call_server_end_initial_metadata have
not been called on this call.
Produces no events. */
grpc_call_error grpc_call_add_metadata_old(grpc_call *call,
grpc_metadata *metadata,
gpr_uint32 flags);
/* Invoke the RPC. Starts sending metadata and request headers on the wire.
flags is a bit-field combination of the write flags defined above.
REQUIRES: Can be called at most once per call.
Can only be called on the client.
Produces a GRPC_CLIENT_METADATA_READ event with metadata_read_tag when
the servers initial metadata has been read.
Produces a GRPC_FINISHED event with finished_tag when the call has been
completed (there may be other events for the call pending at this
time) */
grpc_call_error grpc_call_invoke_old(grpc_call *call, grpc_completion_queue *cq,
void *metadata_read_tag,
void *finished_tag, gpr_uint32 flags);
/* Accept an incoming RPC, binding a completion queue to it.
To be called before sending or receiving messages.
REQUIRES: Can be called at most once per call.
Can only be called on the server.
Produces a GRPC_FINISHED event with finished_tag when the call has been
completed (there may be other events for the call pending at this
time) */
grpc_call_error grpc_call_server_accept_old(grpc_call *call,
grpc_completion_queue *cq,
void *finished_tag);
/* Start sending metadata.
To be called before sending messages.
flags is a bit-field combination of the write flags defined above.
REQUIRES: Can be called at most once per call.
Can only be called on the server.
Must be called after grpc_call_server_accept */
grpc_call_error grpc_call_server_end_initial_metadata_old(grpc_call *call,
gpr_uint32 flags);
/* Called by clients to cancel an RPC on the server.
Can be called multiple times, from any thread. */
grpc_call_error grpc_call_cancel(grpc_call *call);
@ -531,66 +450,9 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call *call,
grpc_status_code status,
const char *description);
/* Queue a byte buffer for writing.
flags is a bit-field combination of the write flags defined above.
A write with byte_buffer null is allowed, and will not send any bytes on the
wire. If this is performed without GRPC_WRITE_BUFFER_HINT flag it provides
a mechanism to flush any previously buffered writes to outgoing flow control.
REQUIRES: No other writes are pending on the call. It is only safe to
start the next write after the corresponding write_accepted event
is received.
GRPC_INVOKE_ACCEPTED must have been received by the application
prior to calling this on the client. On the server,
grpc_call_server_end_of_initial_metadata must have been called
successfully.
Produces a GRPC_WRITE_ACCEPTED event. */
grpc_call_error grpc_call_start_write_old(grpc_call *call,
grpc_byte_buffer *byte_buffer,
void *tag, gpr_uint32 flags);
/* Queue a status for writing.
REQUIRES: No other writes are pending on the call.
grpc_call_server_end_initial_metadata must have been called on the
call prior to calling this.
Only callable on the server.
Produces a GRPC_FINISH_ACCEPTED event when the status is sent. */
grpc_call_error grpc_call_start_write_status_old(grpc_call *call,
grpc_status_code status_code,
const char *status_message,
void *tag);
/* No more messages to send.
REQUIRES: No other writes are pending on the call.
Only callable on the client.
Produces a GRPC_FINISH_ACCEPTED event when all bytes for the call have passed
outgoing flow control. */
grpc_call_error grpc_call_writes_done_old(grpc_call *call, void *tag);
/* Initiate a read on a call. Output event contains a byte buffer with the
result of the read.
REQUIRES: No other reads are pending on the call. It is only safe to start
the next read after the corresponding read event is received.
On the client:
GRPC_INVOKE_ACCEPTED must have been received by the application
prior to calling this.
On the server:
grpc_call_server_accept must be called before calling this.
Produces a single GRPC_READ event. */
grpc_call_error grpc_call_start_read_old(grpc_call *call, void *tag);
/* Destroy a call. */
void grpc_call_destroy(grpc_call *call);
/* Request a call on a server.
Allows the server to create a single GRPC_SERVER_RPC_NEW event, with tag
tag_new.
If the call is subsequently cancelled, the cancellation will occur with tag
tag_cancel.
REQUIRES: Server must not have been shutdown.
NOTE: calling this is the only way to obtain GRPC_SERVER_RPC_NEW events. */
grpc_call_error grpc_server_request_call_old(grpc_server *server,
void *tag_new);
/* Request notification of a new call */
grpc_call_error grpc_server_request_call(
grpc_server *server, grpc_call **call, grpc_call_details *details,

@ -411,7 +411,7 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset,
pfd[1].events = grpc_fd_begin_poll(fd, pollset, POLLIN, POLLOUT, &fd_watcher);
r = poll(pfd, GPR_ARRAY_SIZE(pfd), timeout);
GRPC_TIMER_MARK(POLL_FINISHED, r);
GRPC_TIMER_MARK(GRPC_PTAG_POLL_FINISHED, r);
grpc_fd_end_poll(&fd_watcher);

@ -327,7 +327,7 @@ static void grpc_tcp_handle_read(void *arg /* grpc_tcp */, int success) {
gpr_slice *final_slices;
size_t final_nslices;
GRPC_TIMER_MARK(HANDLE_READ_BEGIN, 0);
GRPC_TIMER_BEGIN(GRPC_PTAG_HANDLE_READ, 0);
slice_state_init(&read_state, static_read_slices, INLINE_SLICE_BUFFER_SIZE,
0);
@ -350,11 +350,11 @@ static void grpc_tcp_handle_read(void *arg /* grpc_tcp */, int success) {
msg.msg_controllen = 0;
msg.msg_flags = 0;
GRPC_TIMER_MARK(RECVMSG_BEGIN, 0);
GRPC_TIMER_BEGIN(GRPC_PTAG_RECVMSG, 0);
do {
read_bytes = recvmsg(tcp->fd, &msg, 0);
} while (read_bytes < 0 && errno == EINTR);
GRPC_TIMER_MARK(RECVMSG_END, 0);
GRPC_TIMER_END(GRPC_PTAG_RECVMSG, 0);
if (read_bytes < allocated_bytes) {
/* TODO(klempner): Consider a second read first, in hopes of getting a
@ -406,7 +406,7 @@ static void grpc_tcp_handle_read(void *arg /* grpc_tcp */, int success) {
++iov_size;
}
}
GRPC_TIMER_MARK(HANDLE_READ_END, 0);
GRPC_TIMER_END(GRPC_PTAG_HANDLE_READ, 0);
}
static void grpc_tcp_notify_on_read(grpc_endpoint *ep, grpc_endpoint_read_cb cb,
@ -438,12 +438,12 @@ static grpc_endpoint_write_status grpc_tcp_flush(grpc_tcp *tcp) {
msg.msg_controllen = 0;
msg.msg_flags = 0;
GRPC_TIMER_MARK(SENDMSG_BEGIN, 0);
GRPC_TIMER_BEGIN(GRPC_PTAG_SENDMSG, 0);
do {
/* TODO(klempner): Cork if this is a partial write */
sent_length = sendmsg(tcp->fd, &msg, 0);
} while (sent_length < 0 && errno == EINTR);
GRPC_TIMER_MARK(SENDMSG_END, 0);
GRPC_TIMER_END(GRPC_PTAG_SENDMSG, 0);
if (sent_length < 0) {
if (errno == EAGAIN) {
@ -479,7 +479,7 @@ static void grpc_tcp_handle_write(void *arg /* grpc_tcp */, int success) {
return;
}
GRPC_TIMER_MARK(CB_WRITE_BEGIN, 0);
GRPC_TIMER_BEGIN(GRPC_PTAG_TCP_CB_WRITE, 0);
write_status = grpc_tcp_flush(tcp);
if (write_status == GRPC_ENDPOINT_WRITE_PENDING) {
grpc_fd_notify_on_write(tcp->em_fd, &tcp->write_closure);
@ -495,7 +495,7 @@ static void grpc_tcp_handle_write(void *arg /* grpc_tcp */, int success) {
cb(tcp->write_user_data, cb_status);
grpc_tcp_unref(tcp);
}
GRPC_TIMER_MARK(CB_WRITE_END, 0);
GRPC_TIMER_END(GRPC_PTAG_TCP_CB_WRITE, 0);
}
static grpc_endpoint_write_status grpc_tcp_write(grpc_endpoint *ep,
@ -518,7 +518,7 @@ static grpc_endpoint_write_status grpc_tcp_write(grpc_endpoint *ep,
}
}
GRPC_TIMER_MARK(WRITE_BEGIN, 0);
GRPC_TIMER_BEGIN(GRPC_PTAG_TCP_WRITE, 0);
GPR_ASSERT(tcp->write_cb == NULL);
slice_state_init(&tcp->write_state, slices, nslices, nslices);
@ -532,7 +532,7 @@ static grpc_endpoint_write_status grpc_tcp_write(grpc_endpoint *ep,
grpc_fd_notify_on_write(tcp->em_fd, &tcp->write_closure);
}
GRPC_TIMER_MARK(WRITE_END, 0);
GRPC_TIMER_END(GRPC_PTAG_TCP_WRITE, 0);
return status;
}

@ -31,7 +31,9 @@
*
*/
#ifdef GRPC_LATENCY_PROFILER
#include <grpc/support/port_platform.h>
#ifdef GRPC_BASIC_PROFILER
#include "src/core/profiling/timers.h"
#include "src/core/profiling/timers_preciseclock.h"
@ -46,7 +48,7 @@
typedef struct grpc_timer_entry {
grpc_precise_clock tm;
gpr_thd_id thd;
const char* tag;
int tag;
void* id;
const char* file;
int line;
@ -63,7 +65,7 @@ struct grpc_timers_log {
grpc_timers_log* grpc_timers_log_global = NULL;
grpc_timers_log* grpc_timers_log_create(int capacity_limit, FILE* dump) {
static grpc_timers_log* grpc_timers_log_create(int capacity_limit, FILE* dump) {
grpc_timers_log* log = gpr_malloc(sizeof(*log));
/* TODO (vpai): Allow allocation below limit */
@ -87,15 +89,15 @@ static void log_report_locked(grpc_timers_log* log) {
grpc_timer_entry* entry = &(log->log[i]);
fprintf(fp, "GRPC_LAT_PROF ");
grpc_precise_clock_print(&entry->tm, fp);
fprintf(fp, " %p %s %p %s %d\n", (void*)(gpr_intptr)entry->thd, entry->tag, entry->id, entry->file,
entry->line);
fprintf(fp, " %p %d %p %s %d\n", (void*)(gpr_intptr)entry->thd, entry->tag,
entry->id, entry->file, entry->line);
}
/* Now clear out the log */
log->num_entries = 0;
}
void grpc_timers_log_destroy(grpc_timers_log* log) {
static void grpc_timers_log_destroy(grpc_timers_log* log) {
gpr_mu_lock(&log->mu);
log_report_locked(log);
gpr_mu_unlock(&log->mu);
@ -106,8 +108,8 @@ void grpc_timers_log_destroy(grpc_timers_log* log) {
gpr_free(log);
}
void grpc_timers_log_add(grpc_timers_log* log, const char* tag, void* id,
const char* file, int line) {
static void grpc_timers_log_add(grpc_timers_log* log, int tag, void* id,
const char* file, int line) {
grpc_timer_entry* entry;
/* TODO (vpai) : Improve concurrency */
@ -128,14 +130,25 @@ void grpc_timers_log_add(grpc_timers_log* log, const char* tag, void* id,
gpr_mu_unlock(&log->mu);
}
void grpc_timers_log_global_init(void) {
/* Latency profiler API implementation. */
void grpc_timer_add_mark(int tag, void* id, const char* file, int line) {
grpc_timers_log_add(grpc_timers_log_global, tag, id, file, line);
}
void grpc_timer_begin(int tag, void* id, const char *file, int line) {}
void grpc_timer_end(int tag, void* id, const char *file, int line) {}
/* Basic profiler specific API functions. */
void grpc_timers_global_init(void) {
grpc_timers_log_global = grpc_timers_log_create(100000, stdout);
}
void grpc_timers_log_global_destroy(void) {
void grpc_timers_global_destroy(void) {
grpc_timers_log_destroy(grpc_timers_log_global);
}
#else /* !GRPC_LATENCY_PROFILER */
void grpc_timers_log_global_init(void) {}
void grpc_timers_log_global_destroy(void) {}
#endif /* GRPC_LATENCY_PROFILER */
#else /* !GRPC_BASIC_PROFILER */
void grpc_timers_global_init(void) {}
void grpc_timers_global_destroy(void) {}
#endif /* GRPC_BASIC_PROFILER */

@ -0,0 +1,6 @@
provider _stap {
probe add_mark(int tag);
probe timing_ns_begin(int tag);
probe timing_ns_end(int tag);
};

@ -0,0 +1,57 @@
/*
*
* Copyright 2015, 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 <grpc/support/port_platform.h>
#ifdef GRPC_STAP_PROFILER
#include "src/core/profiling/timers.h"
#include <sys/sdt.h>
/* Generated from src/core/profiling/stap_probes.d */
#include "src/core/profiling/stap_probes.h"
/* Latency profiler API implementation. */
void grpc_timer_add_mark(int tag, void* id, const char *file, int line) {
_STAP_ADD_MARK(tag);
}
void grpc_timer_begin(int tag, void* id, const char *file, int line) {
_STAP_TIMING_NS_BEGIN(tag);
}
void grpc_timer_end(int tag, void* id, const char *file, int line) {
_STAP_TIMING_NS_END(tag);
}
#endif /* GRPC_STAP_PROFILER */

@ -34,35 +34,87 @@
#ifndef GRPC_CORE_PROFILING_TIMERS_H
#define GRPC_CORE_PROFILING_TIMERS_H
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef GRPC_LATENCY_PROFILER
void grpc_timers_global_init(void);
void grpc_timers_global_destroy(void);
typedef struct grpc_timers_log grpc_timers_log;
void grpc_timer_add_mark(int tag, void* id, const char *file, int line);
void grpc_timer_begin(int tag, void* id, const char *file, int line);
void grpc_timer_end(int tag, void* id, const char *file, int line);
grpc_timers_log* grpc_timers_log_create(int capacity_limit, FILE* dump);
void grpc_timers_log_add(grpc_timers_log*, const char* tag, void* id,
const char* file, int line);
void grpc_timers_log_destroy(grpc_timers_log *);
enum grpc_profiling_tags {
/* Any GRPC_PTAG_* >= than the threshold won't generate any profiling mark. */
GRPC_PTAG_IGNORE_THRESHOLD = 1000000,
extern grpc_timers_log *grpc_timers_log_global;
/* Re. Protos. */
GRPC_PTAG_PROTO_SERIALIZE = 100 + GRPC_PTAG_IGNORE_THRESHOLD,
GRPC_PTAG_PROTO_DESERIALIZE = 101 + GRPC_PTAG_IGNORE_THRESHOLD,
/* Re. sockets. */
GRPC_PTAG_HANDLE_READ = 200 + GRPC_PTAG_IGNORE_THRESHOLD,
GRPC_PTAG_SENDMSG = 201 + GRPC_PTAG_IGNORE_THRESHOLD,
GRPC_PTAG_RECVMSG = 202 + GRPC_PTAG_IGNORE_THRESHOLD,
GRPC_PTAG_POLL_FINISHED = 203 + GRPC_PTAG_IGNORE_THRESHOLD,
GRPC_PTAG_TCP_CB_WRITE = 204 + GRPC_PTAG_IGNORE_THRESHOLD,
GRPC_PTAG_TCP_WRITE = 205 + GRPC_PTAG_IGNORE_THRESHOLD,
/* C++ */
GRPC_PTAG_CPP_CALL_CREATED = 300 + GRPC_PTAG_IGNORE_THRESHOLD,
GRPC_PTAG_CPP_PERFORM_OPS = 301 + GRPC_PTAG_IGNORE_THRESHOLD,
#define GRPC_TIMER_MARK(x, s) \
grpc_timers_log_add(grpc_timers_log_global, #x, ((void *)(gpr_intptr)(s)), \
__FILE__, __LINE__)
/* > 1024 Unassigned reserved. For any miscellaneous use.
* Use addition to generate tags from this base or take advantage of the 10
* zero'd bits for OR-ing. */
GRPC_PTAG_OTHER_BASE = 1024
};
#else /* !GRPC_LATENCY_PROFILER */
#define GRPC_TIMER_MARK(x, s) \
do { \
} while (0)
#endif /* GRPC_LATENCY_PROFILER */
#if !(defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER))
/* No profiling. No-op all the things. */
#define GRPC_TIMER_MARK(tag, id) \
do {} while(0)
#define GRPC_TIMER_BEGIN(tag, id) \
do {} while(0)
#define GRPC_TIMER_END(tag, id) \
do {} while(0)
#else /* at least one profiler requested... */
/* ... hopefully only one. */
#if defined(GRPC_STAP_PROFILER) && defined(GRPC_BASIC_PROFILER)
#error "GRPC_STAP_PROFILER and GRPC_BASIC_PROFILER are mutually exclusive."
#endif
/* Generic profiling interface. */
#define GRPC_TIMER_MARK(tag, id) \
if (tag < GRPC_PTAG_IGNORE_THRESHOLD) { \
grpc_timer_add_mark(tag, ((void *)(gpr_intptr)(id)), __FILE__, __LINE__); \
}
#define GRPC_TIMER_BEGIN(tag, id) \
if (tag < GRPC_PTAG_IGNORE_THRESHOLD) { \
grpc_timer_begin(tag, ((void *)(gpr_intptr)(id)), __FILE__, __LINE__); \
}
#define GRPC_TIMER_END(tag, id) \
if (tag < GRPC_PTAG_IGNORE_THRESHOLD) { \
grpc_timer_end(tag, ((void *)(gpr_intptr)(id)), __FILE__, __LINE__); \
}
#ifdef GRPC_STAP_PROFILER
/* Empty placeholder for now. */
#endif /* GRPC_STAP_PROFILER */
#ifdef GRPC_BASIC_PROFILER
typedef struct grpc_timers_log grpc_timers_log;
extern grpc_timers_log *grpc_timers_log_global;
#endif /* GRPC_BASIC_PROFILER */
void grpc_timers_log_global_init(void);
void grpc_timers_log_global_destroy(void);
#endif /* at least one profiler requested. */
#ifdef __cplusplus
}

@ -34,19 +34,17 @@
#include <grpc/support/port_platform.h>
#ifdef GPR_WIN32
#include <windows.h>
#include <grpc/support/log.h>
unsigned gpr_cpu_num_cores(void) {
/* TODO(jtattermusch): implement */
gpr_log(GPR_ERROR, "Cannot determine number of CPUs: assuming 1");
return 1;
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwNumberOfProcessors;
}
unsigned gpr_cpu_current_cpu(void) {
/* TODO(jtattermusch): implement */
gpr_log(GPR_ERROR, "Cannot determine current CPU");
return 0;
return GetCurrentProcessorNumber();
}
#endif /* GPR_WIN32 */

@ -46,9 +46,6 @@
#include <stdlib.h>
#include <string.h>
typedef struct legacy_state legacy_state;
static void destroy_legacy_state(legacy_state *ls);
typedef enum { REQ_INITIAL = 0, REQ_READY, REQ_DONE } req_state;
typedef enum {
@ -225,10 +222,6 @@ struct grpc_call {
gpr_slice_buffer incoming_message;
gpr_uint32 incoming_message_length;
/* Data that the legacy api needs to track. To be deleted at some point
soon */
legacy_state *legacy_state;
};
#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1))
@ -352,9 +345,6 @@ static void destroy_call(void *call, int ignored_success) {
}
grpc_sopb_destroy(&c->send_ops);
grpc_sopb_destroy(&c->recv_ops);
if (c->legacy_state) {
destroy_legacy_state(c->legacy_state);
}
grpc_bbq_destroy(&c->incoming_queue);
gpr_slice_buffer_destroy(&c->incoming_message);
gpr_free(c);
@ -403,12 +393,6 @@ static void set_status_details(grpc_call *call, status_source source,
call->status[source].details = status;
}
static grpc_call_error bind_cq(grpc_call *call, grpc_completion_queue *cq) {
if (call->cq) return GRPC_CALL_ERROR_ALREADY_INVOKED;
call->cq = cq;
return GRPC_CALL_OK;
}
static int is_op_live(grpc_call *call, grpc_ioreq_op op) {
gpr_uint8 set = call->request_set[op];
reqinfo_master *master;
@ -727,6 +711,10 @@ static void call_on_done_recv(void *pc, int success) {
if (call->recv_state == GRPC_STREAM_CLOSED) {
GPR_ASSERT(call->read_state <= READ_STATE_STREAM_CLOSED);
call->read_state = READ_STATE_STREAM_CLOSED;
if (call->have_alarm) {
grpc_alarm_cancel(&call->alarm);
call->have_alarm = 0;
}
}
finish_read_ops(call);
} else {
@ -1154,7 +1142,7 @@ static void set_cancelled_value(grpc_status_code status, void *dest) {
}
static void finish_batch(grpc_call *call, grpc_op_error result, void *tag) {
grpc_cq_end_op_complete(call->cq, tag, call, do_nothing, NULL, GRPC_OP_OK);
grpc_cq_end_op(call->cq, tag, call, do_nothing, NULL, GRPC_OP_OK);
}
grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
@ -1169,7 +1157,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
if (nops == 0) {
grpc_cq_begin_op(call->cq, call, GRPC_OP_COMPLETE);
grpc_cq_end_op_complete(call->cq, tag, call, do_nothing, NULL, GRPC_OP_OK);
grpc_cq_end_op(call->cq, tag, call, do_nothing, NULL, GRPC_OP_OK);
return GRPC_CALL_OK;
}
@ -1265,312 +1253,3 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
return grpc_call_start_ioreq_and_call_back(call, reqs, out, finish_batch,
tag);
}
/*
* LEGACY API IMPLEMENTATION
* All this code will disappear as soon as wrappings are updated
*/
struct legacy_state {
gpr_uint8 md_out_buffer;
size_t md_out_count[2];
size_t md_out_capacity[2];
grpc_metadata *md_out[2];
grpc_byte_buffer *msg_out;
/* input buffers */
grpc_metadata_array initial_md_in;
grpc_metadata_array trailing_md_in;
size_t details_capacity;
char *details;
grpc_status_code status;
char *send_details;
size_t msg_in_read_idx;
grpc_byte_buffer *msg_in;
void *finished_tag;
};
static legacy_state *get_legacy_state(grpc_call *call) {
if (call->legacy_state == NULL) {
call->legacy_state = gpr_malloc(sizeof(legacy_state));
memset(call->legacy_state, 0, sizeof(legacy_state));
}
return call->legacy_state;
}
static void destroy_legacy_state(legacy_state *ls) {
size_t i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < ls->md_out_count[i]; j++) {
gpr_free((char *)ls->md_out[i][j].key);
gpr_free((char *)ls->md_out[i][j].value);
}
gpr_free(ls->md_out[i]);
}
gpr_free(ls->initial_md_in.metadata);
gpr_free(ls->trailing_md_in.metadata);
gpr_free(ls->details);
gpr_free(ls->send_details);
gpr_free(ls);
}
grpc_call_error grpc_call_add_metadata_old(grpc_call *call,
grpc_metadata *metadata,
gpr_uint32 flags) {
legacy_state *ls;
grpc_metadata *mdout;
lock(call);
ls = get_legacy_state(call);
if (ls->md_out_count[ls->md_out_buffer] ==
ls->md_out_capacity[ls->md_out_buffer]) {
ls->md_out_capacity[ls->md_out_buffer] =
GPR_MAX(ls->md_out_capacity[ls->md_out_buffer] * 3 / 2,
ls->md_out_capacity[ls->md_out_buffer] + 8);
ls->md_out[ls->md_out_buffer] = gpr_realloc(
ls->md_out[ls->md_out_buffer],
sizeof(grpc_metadata) * ls->md_out_capacity[ls->md_out_buffer]);
}
mdout = &ls->md_out[ls->md_out_buffer][ls->md_out_count[ls->md_out_buffer]++];
mdout->key = gpr_strdup(metadata->key);
mdout->value = gpr_malloc(metadata->value_length);
mdout->value_length = metadata->value_length;
memcpy((char *)mdout->value, metadata->value, metadata->value_length);
unlock(call);
return GRPC_CALL_OK;
}
static void finish_status(grpc_call *call, grpc_op_error status,
void *ignored) {
legacy_state *ls;
lock(call);
ls = get_legacy_state(call);
grpc_cq_end_finished(call->cq, ls->finished_tag, call, do_nothing, NULL,
ls->status, ls->details, ls->trailing_md_in.metadata,
ls->trailing_md_in.count);
unlock(call);
}
static void finish_recv_metadata(grpc_call *call, grpc_op_error status,
void *tag) {
legacy_state *ls;
lock(call);
ls = get_legacy_state(call);
if (status == GRPC_OP_OK) {
grpc_cq_end_client_metadata_read(call->cq, tag, call, do_nothing, NULL,
ls->initial_md_in.count,
ls->initial_md_in.metadata);
} else {
grpc_cq_end_client_metadata_read(call->cq, tag, call, do_nothing, NULL, 0,
NULL);
}
unlock(call);
}
static void finish_send_metadata(grpc_call *call, grpc_op_error status,
void *tag) {}
grpc_call_error grpc_call_invoke_old(grpc_call *call, grpc_completion_queue *cq,
void *metadata_read_tag,
void *finished_tag, gpr_uint32 flags) {
grpc_ioreq reqs[4];
legacy_state *ls;
grpc_call_error err;
grpc_cq_begin_op(cq, call, GRPC_CLIENT_METADATA_READ);
grpc_cq_begin_op(cq, call, GRPC_FINISHED);
lock(call);
ls = get_legacy_state(call);
err = bind_cq(call, cq);
if (err != GRPC_CALL_OK) goto done;
ls->finished_tag = finished_tag;
reqs[0].op = GRPC_IOREQ_SEND_INITIAL_METADATA;
reqs[0].data.send_metadata.count = ls->md_out_count[ls->md_out_buffer];
reqs[0].data.send_metadata.metadata = ls->md_out[ls->md_out_buffer];
ls->md_out_buffer++;
err = start_ioreq(call, reqs, 1, finish_send_metadata, NULL);
if (err != GRPC_CALL_OK) goto done;
reqs[0].op = GRPC_IOREQ_RECV_INITIAL_METADATA;
reqs[0].data.recv_metadata = &ls->initial_md_in;
err = start_ioreq(call, reqs, 1, finish_recv_metadata, metadata_read_tag);
if (err != GRPC_CALL_OK) goto done;
reqs[0].op = GRPC_IOREQ_RECV_TRAILING_METADATA;
reqs[0].data.recv_metadata = &ls->trailing_md_in;
reqs[1].op = GRPC_IOREQ_RECV_STATUS;
reqs[1].data.recv_status.user_data = &ls->status;
reqs[1].data.recv_status.set_value = set_status_value_directly;
reqs[2].op = GRPC_IOREQ_RECV_STATUS_DETAILS;
reqs[2].data.recv_status_details.details = &ls->details;
reqs[2].data.recv_status_details.details_capacity = &ls->details_capacity;
reqs[3].op = GRPC_IOREQ_RECV_CLOSE;
err = start_ioreq(call, reqs, 4, finish_status, NULL);
if (err != GRPC_CALL_OK) goto done;
done:
unlock(call);
return err;
}
grpc_call_error grpc_call_server_accept_old(grpc_call *call,
grpc_completion_queue *cq,
void *finished_tag) {
grpc_ioreq reqs[2];
grpc_call_error err;
legacy_state *ls;
/* inform the completion queue of an incoming operation (corresponding to
finished_tag) */
grpc_cq_begin_op(cq, call, GRPC_FINISHED);
lock(call);
ls = get_legacy_state(call);
err = bind_cq(call, cq);
if (err != GRPC_CALL_OK) {
unlock(call);
return err;
}
ls->finished_tag = finished_tag;
reqs[0].op = GRPC_IOREQ_RECV_STATUS;
reqs[0].data.recv_status.user_data = &ls->status;
reqs[0].data.recv_status.set_value = set_status_value_directly;
reqs[1].op = GRPC_IOREQ_RECV_CLOSE;
err = start_ioreq(call, reqs, 2, finish_status, NULL);
unlock(call);
return err;
}
static void finish_send_initial_metadata(grpc_call *call, grpc_op_error status,
void *tag) {}
grpc_call_error grpc_call_server_end_initial_metadata_old(grpc_call *call,
gpr_uint32 flags) {
grpc_ioreq req;
grpc_call_error err;
legacy_state *ls;
lock(call);
ls = get_legacy_state(call);
req.op = GRPC_IOREQ_SEND_INITIAL_METADATA;
req.data.send_metadata.count = ls->md_out_count[ls->md_out_buffer];
req.data.send_metadata.metadata = ls->md_out[ls->md_out_buffer];
err = start_ioreq(call, &req, 1, finish_send_initial_metadata, NULL);
unlock(call);
return err;
}
static void finish_read_event(void *p, grpc_op_error error) {
if (p) grpc_byte_buffer_destroy(p);
}
static void finish_read(grpc_call *call, grpc_op_error error, void *tag) {
legacy_state *ls;
grpc_byte_buffer *msg;
lock(call);
ls = get_legacy_state(call);
msg = ls->msg_in;
grpc_cq_end_read(call->cq, tag, call, finish_read_event, msg, msg);
unlock(call);
}
grpc_call_error grpc_call_start_read_old(grpc_call *call, void *tag) {
legacy_state *ls;
grpc_ioreq req;
grpc_call_error err;
grpc_cq_begin_op(call->cq, call, GRPC_READ);
lock(call);
ls = get_legacy_state(call);
req.op = GRPC_IOREQ_RECV_MESSAGE;
req.data.recv_message = &ls->msg_in;
err = start_ioreq(call, &req, 1, finish_read, tag);
unlock(call);
return err;
}
static void finish_write(grpc_call *call, grpc_op_error status, void *tag) {
lock(call);
grpc_byte_buffer_destroy(get_legacy_state(call)->msg_out);
unlock(call);
grpc_cq_end_write_accepted(call->cq, tag, call, do_nothing, NULL, status);
}
grpc_call_error grpc_call_start_write_old(grpc_call *call,
grpc_byte_buffer *byte_buffer,
void *tag, gpr_uint32 flags) {
grpc_ioreq req;
legacy_state *ls;
grpc_call_error err;
grpc_cq_begin_op(call->cq, call, GRPC_WRITE_ACCEPTED);
lock(call);
ls = get_legacy_state(call);
ls->msg_out = grpc_byte_buffer_copy(byte_buffer);
req.op = GRPC_IOREQ_SEND_MESSAGE;
req.data.send_message = ls->msg_out;
err = start_ioreq(call, &req, 1, finish_write, tag);
unlock(call);
return err;
}
static void finish_finish(grpc_call *call, grpc_op_error status, void *tag) {
grpc_cq_end_finish_accepted(call->cq, tag, call, do_nothing, NULL, status);
}
grpc_call_error grpc_call_writes_done_old(grpc_call *call, void *tag) {
grpc_ioreq req;
grpc_call_error err;
grpc_cq_begin_op(call->cq, call, GRPC_FINISH_ACCEPTED);
lock(call);
req.op = GRPC_IOREQ_SEND_CLOSE;
err = start_ioreq(call, &req, 1, finish_finish, tag);
unlock(call);
return err;
}
grpc_call_error grpc_call_start_write_status_old(grpc_call *call,
grpc_status_code status,
const char *details,
void *tag) {
grpc_ioreq reqs[3];
grpc_call_error err;
legacy_state *ls;
grpc_cq_begin_op(call->cq, call, GRPC_FINISH_ACCEPTED);
lock(call);
ls = get_legacy_state(call);
reqs[0].op = GRPC_IOREQ_SEND_TRAILING_METADATA;
reqs[0].data.send_metadata.count = ls->md_out_count[ls->md_out_buffer];
reqs[0].data.send_metadata.metadata = ls->md_out[ls->md_out_buffer];
reqs[1].op = GRPC_IOREQ_SEND_STATUS;
reqs[1].data.send_status.code = status;
reqs[1].data.send_status.details = ls->send_details = gpr_strdup(details);
reqs[2].op = GRPC_IOREQ_SEND_CLOSE;
err = start_ioreq(call, reqs, 3, finish_finish, tag);
unlock(call);
return err;
}

@ -128,13 +128,6 @@ static grpc_call *grpc_channel_create_call_internal(
GPR_ARRAY_SIZE(send_metadata), deadline);
}
grpc_call *grpc_channel_create_call_old(grpc_channel *channel,
const char *method, const char *host,
gpr_timespec absolute_deadline) {
return grpc_channel_create_call(channel, NULL, method, host,
absolute_deadline);
}
grpc_call *grpc_channel_create_call(grpc_channel *channel,
grpc_completion_queue *cq,
const char *method, const char *host,

@ -183,111 +183,17 @@ void grpc_cq_end_server_shutdown(grpc_completion_queue *cc, void *tag) {
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}
void grpc_cq_end_read(grpc_completion_queue *cc, void *tag, grpc_call *call,
grpc_event_finish_func on_finish, void *user_data,
grpc_byte_buffer *read) {
event *ev;
gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
ev = add_locked(cc, GRPC_READ, tag, call, on_finish, user_data);
ev->base.data.read = read;
end_op_locked(cc, GRPC_READ);
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}
void grpc_cq_end_write_accepted(grpc_completion_queue *cc, void *tag,
grpc_call *call,
grpc_event_finish_func on_finish,
void *user_data, grpc_op_error error) {
event *ev;
gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
ev = add_locked(cc, GRPC_WRITE_ACCEPTED, tag, call, on_finish, user_data);
ev->base.data.write_accepted = error;
end_op_locked(cc, GRPC_WRITE_ACCEPTED);
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}
void grpc_cq_end_op_complete(grpc_completion_queue *cc, void *tag,
grpc_call *call, grpc_event_finish_func on_finish,
void *user_data, grpc_op_error error) {
event *ev;
gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
ev = add_locked(cc, GRPC_OP_COMPLETE, tag, call, on_finish, user_data);
ev->base.data.write_accepted = error;
end_op_locked(cc, GRPC_OP_COMPLETE);
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}
void grpc_cq_end_op(grpc_completion_queue *cc, void *tag, grpc_call *call,
grpc_event_finish_func on_finish, void *user_data,
grpc_op_error error) {
event *ev;
gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
ev = add_locked(cc, GRPC_OP_COMPLETE, tag, call, on_finish, user_data);
ev->base.data.write_accepted = error;
ev->base.data.op_complete = error;
end_op_locked(cc, GRPC_OP_COMPLETE);
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}
void grpc_cq_end_finish_accepted(grpc_completion_queue *cc, void *tag,
grpc_call *call,
grpc_event_finish_func on_finish,
void *user_data, grpc_op_error error) {
event *ev;
gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
ev = add_locked(cc, GRPC_FINISH_ACCEPTED, tag, call, on_finish, user_data);
ev->base.data.finish_accepted = error;
end_op_locked(cc, GRPC_FINISH_ACCEPTED);
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}
void grpc_cq_end_client_metadata_read(grpc_completion_queue *cc, void *tag,
grpc_call *call,
grpc_event_finish_func on_finish,
void *user_data, size_t count,
grpc_metadata *elements) {
event *ev;
gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
ev = add_locked(cc, GRPC_CLIENT_METADATA_READ, tag, call, on_finish,
user_data);
ev->base.data.client_metadata_read.count = count;
ev->base.data.client_metadata_read.elements = elements;
end_op_locked(cc, GRPC_CLIENT_METADATA_READ);
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}
void grpc_cq_end_finished(grpc_completion_queue *cc, void *tag, grpc_call *call,
grpc_event_finish_func on_finish, void *user_data,
grpc_status_code status, const char *details,
grpc_metadata *metadata_elements,
size_t metadata_count) {
event *ev;
gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
ev = add_locked(cc, GRPC_FINISHED, tag, call, on_finish, user_data);
ev->base.data.finished.status = status;
ev->base.data.finished.details = details;
ev->base.data.finished.metadata_count = metadata_count;
ev->base.data.finished.metadata_elements = metadata_elements;
end_op_locked(cc, GRPC_FINISHED);
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}
void grpc_cq_end_new_rpc(grpc_completion_queue *cc, void *tag, grpc_call *call,
grpc_event_finish_func on_finish, void *user_data,
const char *method, const char *host,
gpr_timespec deadline, size_t metadata_count,
grpc_metadata *metadata_elements) {
event *ev;
gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
ev = add_locked(cc, GRPC_SERVER_RPC_NEW, tag, call, on_finish, user_data);
ev->base.data.server_rpc_new.method = method;
ev->base.data.server_rpc_new.host = host;
ev->base.data.server_rpc_new.deadline = deadline;
ev->base.data.server_rpc_new.metadata_count = metadata_count;
ev->base.data.server_rpc_new.metadata_elements = metadata_elements;
end_op_locked(cc, GRPC_SERVER_RPC_NEW);
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}
/* Create a GRPC_QUEUE_SHUTDOWN event without queuing it anywhere */
static event *create_shutdown_event(void) {
event *ev = gpr_malloc(sizeof(event));

@ -62,48 +62,7 @@ void grpc_cq_begin_op(grpc_completion_queue *cc, grpc_call *call,
Other parameters match the data member of grpc_event */
/* Queue a GRPC_READ operation */
void grpc_cq_end_read(grpc_completion_queue *cc, void *tag, grpc_call *call,
grpc_event_finish_func on_finish, void *user_data,
grpc_byte_buffer *read);
/* Queue a GRPC_INVOKE_ACCEPTED operation */
void grpc_cq_end_invoke_accepted(grpc_completion_queue *cc, void *tag,
grpc_call *call,
grpc_event_finish_func on_finish,
void *user_data, grpc_op_error error);
/* Queue a GRPC_WRITE_ACCEPTED operation */
void grpc_cq_end_write_accepted(grpc_completion_queue *cc, void *tag,
grpc_call *call,
grpc_event_finish_func on_finish,
void *user_data, grpc_op_error error);
/* Queue a GRPC_FINISH_ACCEPTED operation */
void grpc_cq_end_finish_accepted(grpc_completion_queue *cc, void *tag,
grpc_call *call,
grpc_event_finish_func on_finish,
void *user_data, grpc_op_error error);
/* Queue a GRPC_OP_COMPLETED operation */
void grpc_cq_end_op_complete(grpc_completion_queue *cc, void *tag,
grpc_call *call, grpc_event_finish_func on_finish,
void *user_data, grpc_op_error error);
/* Queue a GRPC_CLIENT_METADATA_READ operation */
void grpc_cq_end_client_metadata_read(grpc_completion_queue *cc, void *tag,
grpc_call *call,
grpc_event_finish_func on_finish,
void *user_data, size_t count,
grpc_metadata *elements);
void grpc_cq_end_finished(grpc_completion_queue *cc, void *tag, grpc_call *call,
grpc_event_finish_func on_finish, void *user_data,
grpc_status_code status, const char *details,
grpc_metadata *metadata_elements,
size_t metadata_count);
void grpc_cq_end_new_rpc(grpc_completion_queue *cc, void *tag, grpc_call *call,
grpc_event_finish_func on_finish, void *user_data,
const char *method, const char *host,
gpr_timespec deadline, size_t metadata_count,
grpc_metadata *metadata_elements);
void grpc_cq_end_op(grpc_completion_queue *cc, void *tag, grpc_call *call,
grpc_event_finish_func on_finish, void *user_data,
grpc_op_error error);

@ -62,7 +62,6 @@ static void adderr(gpr_strvec *buf, grpc_op_error err) {
char *grpc_event_string(grpc_event *ev) {
char *out;
char *tmp;
gpr_strvec buf;
if (ev == NULL) return gpr_strdup("null");
@ -76,55 +75,11 @@ char *grpc_event_string(grpc_event *ev) {
case GRPC_QUEUE_SHUTDOWN:
gpr_strvec_add(&buf, gpr_strdup("QUEUE_SHUTDOWN"));
break;
case GRPC_READ:
gpr_strvec_add(&buf, gpr_strdup("READ: "));
addhdr(&buf, ev);
if (ev->data.read) {
gpr_asprintf(&tmp, " %d bytes",
(int)grpc_byte_buffer_length(ev->data.read));
gpr_strvec_add(&buf, tmp);
} else {
gpr_strvec_add(&buf, gpr_strdup(" end-of-stream"));
}
break;
case GRPC_OP_COMPLETE:
gpr_strvec_add(&buf, gpr_strdup("OP_COMPLETE: "));
addhdr(&buf, ev);
adderr(&buf, ev->data.op_complete);
break;
case GRPC_WRITE_ACCEPTED:
gpr_strvec_add(&buf, gpr_strdup("WRITE_ACCEPTED: "));
addhdr(&buf, ev);
adderr(&buf, ev->data.write_accepted);
break;
case GRPC_FINISH_ACCEPTED:
gpr_strvec_add(&buf, gpr_strdup("FINISH_ACCEPTED: "));
addhdr(&buf, ev);
adderr(&buf, ev->data.write_accepted);
break;
case GRPC_CLIENT_METADATA_READ:
gpr_strvec_add(&buf, gpr_strdup("CLIENT_METADATA_READ: "));
addhdr(&buf, ev);
gpr_asprintf(&tmp, " %d elements",
(int)ev->data.client_metadata_read.count);
gpr_strvec_add(&buf, tmp);
break;
case GRPC_FINISHED:
gpr_strvec_add(&buf, gpr_strdup("FINISHED: "));
addhdr(&buf, ev);
gpr_asprintf(&tmp, " status=%d details='%s' %d metadata elements",
ev->data.finished.status, ev->data.finished.details,
(int)ev->data.finished.metadata_count);
gpr_strvec_add(&buf, tmp);
break;
case GRPC_SERVER_RPC_NEW:
gpr_strvec_add(&buf, gpr_strdup("SERVER_RPC_NEW: "));
addhdr(&buf, ev);
gpr_asprintf(&tmp, " method='%s' host='%s' %d metadata elements",
ev->data.server_rpc_new.method, ev->data.server_rpc_new.host,
(int)ev->data.server_rpc_new.metadata_count);
gpr_strvec_add(&buf, tmp);
break;
case GRPC_COMPLETION_DO_NOT_USE:
gpr_strvec_add(&buf, gpr_strdup("DO_NOT_USE (this is a bug)"));
addhdr(&buf, ev);

@ -64,7 +64,7 @@ void grpc_init(void) {
grpc_iomgr_init();
grpc_tracer_init("GRPC_TRACE");
census_init();
grpc_timers_log_global_init();
grpc_timers_global_init();
}
gpr_mu_unlock(&g_init_mu);
}
@ -74,7 +74,7 @@ void grpc_shutdown(void) {
if (--g_initializations == 0) {
grpc_iomgr_shutdown();
census_shutdown();
grpc_timers_log_global_destroy();
grpc_timers_global_destroy();
}
gpr_mu_unlock(&g_init_mu);
}

@ -69,7 +69,7 @@ typedef struct {
call_data *prev;
} call_link;
typedef enum { LEGACY_CALL, BATCH_CALL, REGISTERED_CALL } requested_call_type;
typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type;
typedef struct {
requested_call_type type;
@ -165,10 +165,6 @@ typedef enum {
ZOMBIED
} call_state;
typedef struct legacy_data {
grpc_metadata_array initial_metadata;
} legacy_data;
struct call_data {
grpc_call *call;
@ -178,7 +174,6 @@ struct call_data {
gpr_timespec deadline;
int got_initial_metadata;
legacy_data *legacy;
grpc_completion_queue *cq_new;
grpc_stream_op_buffer *recv_ops;
@ -557,11 +552,6 @@ static void destroy_call_elem(grpc_call_element *elem) {
grpc_mdstr_unref(calld->path);
}
if (calld->legacy) {
gpr_free(calld->legacy->initial_metadata.metadata);
gpr_free(calld->legacy);
}
server_unref(chand->server);
}
@ -998,7 +988,6 @@ static grpc_call_error queue_call_request(grpc_server *server,
return GRPC_CALL_OK;
}
switch (rc->type) {
case LEGACY_CALL:
case BATCH_CALL:
calld =
call_list_remove_head(&server->lists[PENDING_START], PENDING_START);
@ -1057,16 +1046,6 @@ grpc_call_error grpc_server_request_registered_call(
return queue_call_request(server, &rc);
}
grpc_call_error grpc_server_request_call_old(grpc_server *server,
void *tag_new) {
requested_call rc;
grpc_cq_begin_op(server->unregistered_cq, NULL, GRPC_SERVER_RPC_NEW);
rc.type = LEGACY_CALL;
rc.tag = tag_new;
return queue_call_request(server, &rc);
}
static void publish_legacy(grpc_call *call, grpc_op_error status, void *tag);
static void publish_registered_or_batch(grpc_call *call, grpc_op_error status,
void *tag);
static void publish_was_not_set(grpc_call *call, grpc_op_error status,
@ -1098,14 +1077,6 @@ static void begin_call(grpc_server *server, call_data *calld,
an ioreq op, that should complete immediately. */
switch (rc->type) {
case LEGACY_CALL:
calld->legacy = gpr_malloc(sizeof(legacy_data));
memset(calld->legacy, 0, sizeof(legacy_data));
r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
r->data.recv_metadata = &calld->legacy->initial_metadata;
r++;
publish = publish_legacy;
break;
case BATCH_CALL:
cpstr(&rc->data.batch.details->host,
&rc->data.batch.details->host_capacity, calld->host);
@ -1144,50 +1115,27 @@ static void begin_call(grpc_server *server, call_data *calld,
static void fail_call(grpc_server *server, requested_call *rc) {
switch (rc->type) {
case LEGACY_CALL:
grpc_cq_end_new_rpc(server->unregistered_cq, rc->tag, NULL, do_nothing,
NULL, NULL, NULL, gpr_inf_past, 0, NULL);
break;
case BATCH_CALL:
*rc->data.batch.call = NULL;
rc->data.batch.initial_metadata->count = 0;
grpc_cq_end_op_complete(server->unregistered_cq, rc->tag, NULL,
do_nothing, NULL, GRPC_OP_ERROR);
grpc_cq_end_op(server->unregistered_cq, rc->tag, NULL, do_nothing, NULL,
GRPC_OP_ERROR);
break;
case REGISTERED_CALL:
*rc->data.registered.call = NULL;
rc->data.registered.initial_metadata->count = 0;
grpc_cq_end_op_complete(rc->data.registered.registered_method->cq,
rc->tag, NULL, do_nothing, NULL, GRPC_OP_ERROR);
grpc_cq_end_op(rc->data.registered.registered_method->cq, rc->tag, NULL,
do_nothing, NULL, GRPC_OP_ERROR);
break;
}
}
static void publish_legacy(grpc_call *call, grpc_op_error status, void *tag) {
grpc_call_element *elem =
grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
grpc_server *server = chand->server;
if (status == GRPC_OP_OK) {
grpc_cq_end_new_rpc(server->unregistered_cq, tag, call, do_nothing, NULL,
grpc_mdstr_as_c_string(calld->path),
grpc_mdstr_as_c_string(calld->host), calld->deadline,
calld->legacy->initial_metadata.count,
calld->legacy->initial_metadata.metadata);
} else {
gpr_log(GPR_ERROR, "should never reach here");
abort();
}
}
static void publish_registered_or_batch(grpc_call *call, grpc_op_error status,
void *tag) {
grpc_call_element *elem =
grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
call_data *calld = elem->call_data;
grpc_cq_end_op_complete(calld->cq_new, tag, call, do_nothing, NULL, status);
grpc_cq_end_op(calld->cq_new, tag, call, do_nothing, NULL, status);
}
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {

@ -122,6 +122,12 @@ static void begin_frame(framer_state *st, frame_type type) {
st->output_length_at_start_of_frame = st->output->length;
}
static void begin_new_frame(framer_state *st, frame_type type) {
finish_frame(st, 1, 0);
st->last_was_header = 0;
begin_frame(st, type);
}
/* make sure that the current frame is of the type desired, and has sufficient
space to add at least about_to_add bytes -- finishes the current frame if
needed */
@ -571,6 +577,7 @@ void grpc_chttp2_encode(grpc_stream_op *ops, size_t ops_count, int eof,
a metadata element that needs to be unreffed back into the metadata
slot. THIS MAY NOT BE THE SAME ELEMENT (if a decoder table slot got
updated). After this loop, we'll do a batch unref of elements. */
begin_new_frame(&st, HEADER);
need_unref |= op->data.metadata.garbage.head != NULL;
grpc_metadata_batch_assert_ok(&op->data.metadata);
for (l = op->data.metadata.list.head; l; l = l->next) {
@ -580,9 +587,6 @@ void grpc_chttp2_encode(grpc_stream_op *ops, size_t ops_count, int eof,
if (gpr_time_cmp(op->data.metadata.deadline, gpr_inf_future) != 0) {
deadline_enc(compressor, op->data.metadata.deadline, &st);
}
ensure_frame_type(&st, HEADER, 0);
finish_frame(&st, 1, 0);
st.last_was_header = 0; /* force a new header frame */
curop++;
break;
case GRPC_OP_SLICE:

@ -70,7 +70,7 @@ Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
? target_.c_str()
: context->authority().c_str(),
context->raw_deadline());
GRPC_TIMER_MARK(CALL_CREATED, c_call);
GRPC_TIMER_MARK(GRPC_PTAG_CPP_CALL_CREATED, c_call);
context->set_call(c_call, shared_from_this());
return Call(c_call, this, cq);
}
@ -79,11 +79,11 @@ void Channel::PerformOpsOnCall(CallOpBuffer* buf, Call* call) {
static const size_t MAX_OPS = 8;
size_t nops = MAX_OPS;
grpc_op ops[MAX_OPS];
GRPC_TIMER_MARK(PERFORM_OPS_BEGIN, call->call());
GRPC_TIMER_BEGIN(GRPC_PTAG_CPP_PERFORM_OPS, call->call());
buf->FillOps(ops, &nops);
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_start_batch(call->call(), ops, nops, buf));
GRPC_TIMER_MARK(PERFORM_OPS_END, call->call());
GRPC_TIMER_END(GRPC_PTAG_CPP_PERFORM_OPS, call->call());
}
void* Channel::RegisterMethod(const char* method) {

@ -233,13 +233,13 @@ void CallOpBuffer::FillOps(grpc_op* ops, size_t* nops) {
}
if (send_message_ || send_message_buffer_) {
if (send_message_) {
GRPC_TIMER_MARK(SER_PROTO_BEGIN, 0);
GRPC_TIMER_BEGIN(GRPC_PTAG_PROTO_SERIALIZE, 0);
bool success = SerializeProto(*send_message_, &send_buf_);
if (!success) {
abort();
// TODO handle parse failure
}
GRPC_TIMER_MARK(SER_PROTO_END, 0);
GRPC_TIMER_END(GRPC_PTAG_PROTO_SERIALIZE, 0);
} else {
send_buf_ = send_message_buffer_->buffer();
}
@ -311,10 +311,10 @@ bool CallOpBuffer::FinalizeResult(void** tag, bool* status) {
if (recv_buf_) {
got_message = *status;
if (recv_message_) {
GRPC_TIMER_MARK(DESER_PROTO_BEGIN, 0);
GRPC_TIMER_BEGIN(GRPC_PTAG_PROTO_DESERIALIZE, 0);
*status = *status && DeserializeProto(recv_buf_, recv_message_, max_message_size_);
grpc_byte_buffer_destroy(recv_buf_);
GRPC_TIMER_MARK(DESER_PROTO_END, 0);
GRPC_TIMER_END(GRPC_PTAG_PROTO_DESERIALIZE, 0);
} else {
recv_message_buffer_->set_buffer(recv_buf_);
}

@ -92,7 +92,7 @@ bool CompletionQueue::Pluck(CompletionQueueTag* tag) {
void CompletionQueue::TryPluck(CompletionQueueTag* tag) {
std::unique_ptr<grpc_event, EventDeleter> ev;
ev.reset(grpc_completion_queue_pluck(cq_, tag, gpr_inf_past));
ev.reset(grpc_completion_queue_pluck(cq_, tag, gpr_time_0));
if (!ev) return;
bool ok = ev->data.op_complete == GRPC_OP_OK;
void* ignored = tag;

@ -160,6 +160,7 @@ bool SerializeProto(const grpc::protobuf::Message& msg, grpc_byte_buffer** bp) {
bool DeserializeProto(grpc_byte_buffer* buffer, grpc::protobuf::Message* msg,
int max_message_size) {
if (!buffer) return false;
GrpcBufferReader reader(buffer);
::grpc::protobuf::io::CodedInputStream decoder(&reader);
if (max_message_size > 0) {

@ -124,12 +124,12 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
std::unique_ptr<grpc::protobuf::Message> req;
std::unique_ptr<grpc::protobuf::Message> res;
if (has_request_payload_) {
GRPC_TIMER_MARK(DESER_PROTO_BEGIN, call_.call());
GRPC_TIMER_BEGIN(GRPC_PTAG_PROTO_DESERIALIZE, call_.call());
req.reset(method_->AllocateRequestProto());
if (!DeserializeProto(request_payload_, req.get(), call_.max_message_size())) {
abort(); // for now
}
GRPC_TIMER_MARK(DESER_PROTO_END, call_.call());
GRPC_TIMER_END(GRPC_PTAG_PROTO_DESERIALIZE, call_.call());
}
if (has_response_payload_) {
res.reset(method_->AllocateResponseProto());
@ -361,10 +361,10 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag {
bool orig_status = *status;
if (*status && request_) {
if (payload_) {
GRPC_TIMER_MARK(DESER_PROTO_BEGIN, call_);
GRPC_TIMER_BEGIN(GRPC_PTAG_PROTO_DESERIALIZE, call_);
*status = DeserializeProto(payload_, request_,
server_->max_message_size_);
GRPC_TIMER_MARK(DESER_PROTO_END, call_);
GRPC_TIMER_END(GRPC_PTAG_PROTO_DESERIALIZE, call_);
} else {
*status = false;
}

@ -415,16 +415,6 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_destroy(grpc_call *call) {
grpc_call_destroy(call);
}
GPR_EXPORT void GPR_CALLTYPE
grpcsharp_call_start_write_from_copied_buffer(grpc_call *call,
const char *buffer, size_t len,
void *tag, gpr_uint32 flags) {
grpc_byte_buffer *byte_buffer = string_to_byte_buffer(buffer, len);
GPR_ASSERT(grpc_call_start_write_old(call, byte_buffer, tag, flags) ==
GRPC_CALL_OK);
grpc_byte_buffer_destroy(byte_buffer);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_start_unary(grpc_call *call, callback_funcptr callback,
const char *send_buffer, size_t send_buffer_len,

@ -5,7 +5,8 @@
"homepage": "http://grpc.io",
"license": "BSD-3-Clause",
"require": {
"php": ">=5.5.0"
"php": ">=5.5.0",
"google/auth": "dev-master"
},
"autoload": {
"psr-4": {

302
src/php/composer.lock generated

@ -4,12 +4,308 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "65467a098f5fd8b8fe5f7f6e10226f8a",
"packages": [],
"hash": "bb81ea5f72ddea2f594a172ff0f3b44d",
"packages": [
{
"name": "firebase/php-jwt",
"version": "2.0.0",
"target-dir": "Firebase/PHP-JWT",
"source": {
"type": "git",
"url": "https://github.com/firebase/php-jwt.git",
"reference": "ffcfd888ce1e4f2d70cac2dc9b7301038332fe57"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/ffcfd888ce1e4f2d70cac2dc9b7301038332fe57",
"reference": "ffcfd888ce1e4f2d70cac2dc9b7301038332fe57",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"type": "library",
"autoload": {
"classmap": [
"Authentication/",
"Exceptions/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Neuman Vong",
"email": "neuman+pear@twilio.com",
"role": "Developer"
},
{
"name": "Anant Narayanan",
"email": "anant@php.net",
"role": "Developer"
}
],
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
"time": "2015-04-01 18:46:38"
},
{
"name": "google/auth",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/google/google-auth-library-php.git",
"reference": "35f87159b327fa6416266948c1747c585a4ae3ad"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/google/google-auth-library-php/zipball/35f87159b327fa6416266948c1747c585a4ae3ad",
"reference": "35f87159b327fa6416266948c1747c585a4ae3ad",
"shasum": ""
},
"require": {
"firebase/php-jwt": "2.0.0",
"guzzlehttp/guzzle": "5.2.*",
"php": ">=5.4"
},
"require-dev": {
"phplint/phplint": "0.0.1",
"phpunit/phpunit": "3.7.*"
},
"type": "library",
"autoload": {
"classmap": [
"src/"
],
"psr-4": {
"Google\\Auth\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"description": "Google Auth Library for PHP",
"homepage": "http://github.com/google/google-auth-library-php",
"keywords": [
"Authentication",
"google",
"oauth2"
],
"time": "2015-04-30 11:57:19"
},
{
"name": "guzzlehttp/guzzle",
"version": "5.2.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "475b29ccd411f2fa8a408e64576418728c032cfa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/475b29ccd411f2fa8a408e64576418728c032cfa",
"reference": "475b29ccd411f2fa8a408e64576418728c032cfa",
"shasum": ""
},
"require": {
"guzzlehttp/ringphp": "~1.0",
"php": ">=5.4.0"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "~4.0",
"psr/log": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"rest",
"web service"
],
"time": "2015-01-28 01:03:29"
},
{
"name": "guzzlehttp/ringphp",
"version": "1.0.7",
"source": {
"type": "git",
"url": "https://github.com/guzzle/RingPHP.git",
"reference": "52d868f13570a9a56e5fce6614e0ec75d0f13ac2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/RingPHP/zipball/52d868f13570a9a56e5fce6614e0ec75d0f13ac2",
"reference": "52d868f13570a9a56e5fce6614e0ec75d0f13ac2",
"shasum": ""
},
"require": {
"guzzlehttp/streams": "~3.0",
"php": ">=5.4.0",
"react/promise": "~2.0"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "~4.0"
},
"suggest": {
"ext-curl": "Guzzle will use specific adapters if cURL is present"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Ring\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
"time": "2015-03-30 01:43:20"
},
{
"name": "guzzlehttp/streams",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/streams.git",
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Stream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Provides a simple abstraction over streams of data",
"homepage": "http://guzzlephp.org/",
"keywords": [
"Guzzle",
"stream"
],
"time": "2014-10-12 19:18:40"
},
{
"name": "react/promise",
"version": "v2.2.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
"reference": "365fcee430dfa4ace1fbc75737ca60ceea7eeeef"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise/zipball/365fcee430dfa4ace1fbc75737ca60ceea7eeeef",
"reference": "365fcee430dfa4ace1fbc75737ca60ceea7eeeef",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
},
"autoload": {
"psr-4": {
"React\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jan Sorgalla",
"email": "jsorgalla@googlemail.com"
}
],
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
"time": "2014-12-30 13:32:42"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {
"google/auth": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {

@ -38,6 +38,7 @@ require 'empty.php';
require 'message_set.php';
require 'messages.php';
require 'test.php';
/**
* Assertion function that always exits with an error code if the assertion is
* falsy
@ -45,7 +46,7 @@ require 'test.php';
* @param $error_message Message to display if the assertion is false
*/
function hardAssert($value, $error_message) {
if(!$value) {
if (!$value) {
echo $error_message . "\n";
exit(1);
}
@ -53,7 +54,7 @@ function hardAssert($value, $error_message) {
/**
* Run the empty_unary test.
* Currently not tested against any server as of 2014-12-04
* Passes when run against the Node server as of 2015-04-30
* @param $stub Stub object that has service methods
*/
function emptyUnary($stub) {
@ -64,11 +65,20 @@ function emptyUnary($stub) {
/**
* Run the large_unary test.
* Passes when run against the C++ server as of 2014-12-04
* Not tested against any other server as of 2014-12-04
* Passes when run against the C++/Node server as of 2015-04-30
* @param $stub Stub object that has service methods
*/
function largeUnary($stub) {
performLargeUnary($stub);
}
/**
* Shared code between large unary test and auth test
* @param $stub Stub object that has service methods
* @param $fillUsername boolean whether to fill result with username
* @param $fillOauthScope boolean whether to fill result with oauth scope
*/
function performLargeUnary($stub, $fillUsername = false, $fillOauthScope = false) {
$request_len = 271828;
$response_len = 314159;
@ -79,6 +89,8 @@ function largeUnary($stub) {
$payload->setType(grpc\testing\PayloadType::COMPRESSABLE);
$payload->setBody(str_repeat("\0", $request_len));
$request->setPayload($payload);
$request->setFillUsername($fillUsername);
$request->setFillOauthScope($fillOauthScope);
list($result, $status) = $stub->UnaryCall($request)->wait();
hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully');
@ -90,11 +102,32 @@ function largeUnary($stub) {
'Payload had the wrong length');
hardAssert($payload->getBody() === str_repeat("\0", $response_len),
'Payload had the wrong content');
return $result;
}
/**
* Run the service account credentials auth test.
* Passes when run against the cloud server as of 2015-04-30
* @param $stub Stub object that has service methods
* @param $args array command line args
*/
function serviceAccountCreds($stub, $args) {
if (!array_key_exists('oauth_scope', $args)) {
throw new Exception('Missing oauth scope');
}
$jsonKey = json_decode(
file_get_contents(getenv(Google\Auth\CredentialsLoader::ENV_VAR)),
true);
$result = performLargeUnary($stub, $fillUsername=true, $fillOauthScope=true);
hardAssert($result->getUsername() == $jsonKey['client_email'],
'invalid email returned');
hardAssert(strpos($args['oauth_scope'], $result->getOauthScope()) !== false,
'invalid oauth scope returned');
}
/**
* Run the client_streaming test.
* Not tested against any server as of 2014-12-04.
* Passes when run against the Node server as of 2015-04-30
* @param $stub Stub object that has service methods
*/
function clientStreaming($stub) {
@ -117,7 +150,7 @@ function clientStreaming($stub) {
/**
* Run the server_streaming test.
* Not tested against any server as of 2014-12-04.
* Passes when run against the Node server as of 2015-04-30
* @param $stub Stub object that has service methods.
*/
function serverStreaming($stub) {
@ -148,7 +181,7 @@ function serverStreaming($stub) {
/**
* Run the ping_pong test.
* Not tested against any server as of 2014-12-04.
* Passes when run against the Node server as of 2015-04-30
* @param $stub Stub object that has service methods.
*/
function pingPong($stub) {
@ -182,6 +215,11 @@ function pingPong($stub) {
'Call did not complete successfully');
}
/**
* Run the cancel_after_first_response test.
* Passes when run against the Node server as of 2015-04-30
* @param $stub Stub object that has service methods.
*/
function cancelAfterFirstResponse($stub) {
$call = $stub->FullDuplexCall();
$request = new grpc\testing\StreamingOutputCallRequest();
@ -201,7 +239,8 @@ function cancelAfterFirstResponse($stub) {
'Call status was not CANCELLED');
}
$args = getopt('', array('server_host:', 'server_port:', 'test_case:'));
$args = getopt('', array('server_host:', 'server_port:', 'test_case:',
'server_host_override:', 'oauth_scope:'));
if (!array_key_exists('server_host', $args) ||
!array_key_exists('server_port', $args) ||
!array_key_exists('test_case', $args)) {
@ -210,20 +249,37 @@ if (!array_key_exists('server_host', $args) ||
$server_address = $args['server_host'] . ':' . $args['server_port'];
$credentials = Grpc\Credentials::createSsl(
file_get_contents(dirname(__FILE__) . '/../data/ca.pem'));
if (!array_key_exists('server_host_override', $args)) {
$args['server_host_override'] = 'foo.test.google.fr';
}
$ssl_cert_file = getenv('SSL_CERT_FILE');
if (!$ssl_cert_file) {
$ssl_cert_file = dirname(__FILE__) . '/../data/ca.pem';
}
$credentials = Grpc\Credentials::createSsl(file_get_contents($ssl_cert_file));
$opts = [
'grpc.ssl_target_name_override' => $args['server_host_override'],
'credentials' => $credentials,
];
if (array_key_exists('oauth_scope', $args)) {
$auth = Google\Auth\ApplicationDefaultCredentials::getCredentials(
$args['oauth_scope']);
$opts['update_metadata'] = $auth->getUpdateMetadataFunc();
}
$stub = new grpc\testing\TestServiceClient(
new Grpc\BaseStub(
$server_address,
[
'grpc.ssl_target_name_override' => 'foo.test.google.fr',
'credentials' => $credentials
]));
$opts));
echo "Connecting to $server_address\n";
echo "Running test case $args[test_case]\n";
switch($args['test_case']) {
switch ($args['test_case']) {
case 'empty_unary':
emptyUnary($stub);
break;
@ -242,6 +298,9 @@ switch($args['test_case']) {
case 'cancel_after_first_response':
cancelAfterFirstResponse($stub);
break;
case 'service_account_creds':
serviceAccountCreds($stub, $args);
break;
default:
exit(1);
}

@ -70,7 +70,7 @@ typedef struct {
grpc_call *c_call;
} Call;
PyTypeObject pygrpc_CallType;
extern PyTypeObject pygrpc_CallType;
int pygrpc_add_call(PyObject *module);

@ -42,7 +42,7 @@ typedef struct {
grpc_channel *c_channel;
} Channel;
PyTypeObject pygrpc_ChannelType;
extern PyTypeObject pygrpc_ChannelType;
int pygrpc_add_channel(PyObject *module);

@ -42,7 +42,7 @@ typedef struct {
grpc_credentials *c_client_credentials;
} ClientCredentials;
PyTypeObject pygrpc_ClientCredentialsType;
extern PyTypeObject pygrpc_ClientCredentialsType;
int pygrpc_add_client_credentials(PyObject *module);

@ -354,6 +354,8 @@ static PyObject *pygrpc_completion_queue_get(CompletionQueue *self,
PyObject *event_args;
PyObject *event;
pygrpc_tag *tag;
if (!(PyArg_ParseTuple(args, "O:get", &deadline))) {
return NULL;
}
@ -380,7 +382,7 @@ static PyObject *pygrpc_completion_queue_get(CompletionQueue *self,
Py_RETURN_NONE;
}
pygrpc_tag *tag = (pygrpc_tag *)c_event->tag;
tag = (pygrpc_tag *)c_event->tag;
switch (c_event->type) {
case GRPC_QUEUE_SHUTDOWN:

@ -42,7 +42,7 @@ typedef struct {
grpc_completion_queue *c_completion_queue;
} CompletionQueue;
PyTypeObject pygrpc_CompletionQueueType;
extern PyTypeObject pygrpc_CompletionQueueType;
int pygrpc_add_completion_queue(PyObject *module);

@ -42,7 +42,7 @@ typedef struct {
grpc_server_credentials *c_server_credentials;
} ServerCredentials;
PyTypeObject pygrpc_ServerCredentialsType;
extern PyTypeObject pygrpc_ServerCredentialsType;
int pygrpc_add_server_credentials(PyObject *module);

@ -51,7 +51,7 @@ typedef enum {
PYGRPC_FINISH_ACCEPTED = 4,
PYGRPC_CLIENT_METADATA_READ = 5,
PYGRPC_FINISHED_CLIENT = 6,
PYGRPC_FINISHED_SERVER = 7,
PYGRPC_FINISHED_SERVER = 7
} pygrpc_tag_type;
typedef struct {

@ -86,7 +86,7 @@ _PACKAGE_DIRECTORIES = {
setuptools.setup(
name='grpcio',
version='0.5.0a0',
version='0.5.0a2',
ext_modules=[_EXTENSION_MODULE],
packages=list(_PACKAGES),
package_dir=_PACKAGE_DIRECTORIES,

@ -101,14 +101,23 @@ CPPFLAGS_opt = -O2
LDFLAGS_opt =
DEFINES_opt = NDEBUG
VALID_CONFIG_latprof = 1
CC_latprof = $(DEFAULT_CC)
CXX_latprof = $(DEFAULT_CXX)
LD_latprof = $(DEFAULT_CC)
LDXX_latprof = $(DEFAULT_CXX)
CPPFLAGS_latprof = -O2 -DGRPC_LATENCY_PROFILER
LDFLAGS_latprof =
DEFINES_latprof = NDEBUG
VALID_CONFIG_basicprof = 1
CC_basicprof = $(DEFAULT_CC)
CXX_basicprof = $(DEFAULT_CXX)
LD_basicprof = $(DEFAULT_CC)
LDXX_basicprof = $(DEFAULT_CXX)
CPPFLAGS_basicprof = -O2 -DGRPC_BASIC_PROFILER
LDFLAGS_basicprof =
DEFINES_basicprof = NDEBUG
VALID_CONFIG_stapprof = 1
CC_stapprof = $(DEFAULT_CC)
CXX_stapprof = $(DEFAULT_CXX)
LD_stapprof = $(DEFAULT_CC)
LDXX_stapprof = $(DEFAULT_CXX)
CPPFLAGS_stapprof = -O2 -DGRPC_STAP_PROFILER
LDFLAGS_stapprof =
DEFINES_stapprof = NDEBUG
VALID_CONFIG_dbg = 1
CC_dbg = $(DEFAULT_CC)
@ -188,7 +197,7 @@ LD_gcov = gcc
LDXX_gcov = g++
CPPFLAGS_gcov = -O0 -fprofile-arcs -ftest-coverage
LDFLAGS_gcov = -fprofile-arcs -ftest-coverage
DEFINES_gcov = NDEBUG
DEFINES_gcov = _DEBUG DEBUG
# General settings.
@ -197,6 +206,7 @@ DEFINES_gcov = NDEBUG
prefix ?= /usr/local
PROTOC = protoc
DTRACE = dtrace
CONFIG ?= opt
CC = $(CC_$(CONFIG))
CXX = $(CXX_$(CONFIG))
@ -364,6 +374,8 @@ PERFTOOLS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/perfto
PROTOBUF_CHECK_CMD = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/protobuf.cc -lprotobuf $(LDFLAGS)
PROTOC_CHECK_CMD = which protoc > /dev/null
PROTOC_CHECK_VERSION_CMD = protoc --version | grep -q libprotoc.3
DTRACE_CHECK_CMD = which dtrace > /dev/null
SYSTEMTAP_HEADERS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/systemtap.c $(LDFLAGS)
ifeq ($(OPENSSL_REQUIRES_DL),true)
OPENSSL_ALPN_CHECK_CMD += -ldl
@ -396,6 +408,18 @@ else
HAS_VALID_PROTOC = false
endif
# Check for Systemtap (https://sourceware.org/systemtap/), first by making sure <sys/sdt.h> is present
# in the system and secondly by checking for the "dtrace" binary (on Linux, this is part of the Systemtap
# distribution. It's part of the base system on BSD/Solaris machines).
HAS_SYSTEMTAP_HEADERS = $(shell $(SYSTEMTAP_HEADERS_CHECK_CMD) 2> /dev/null && echo true || echo false)
HAS_DTRACE = $(shell $(DTRACE_CHECK_CMD) 2> /dev/null && echo true || echo false)
HAS_SYSTEMTAP = false
ifeq ($(HAS_SYSTEMTAP_HEADERS),true)
ifeq ($(HAS_DTRACE),true)
HAS_SYSTEMTAP = true
endif
endif
ifeq ($(wildcard third_party/openssl/ssl/ssl.h),)
HAS_EMBEDDED_OPENSSL_ALPN = false
else
@ -575,6 +599,17 @@ protoc_dep_message:
@echo " make run_dep_checks"
@echo
systemtap_dep_error:
@echo
@echo "DEPENDENCY ERROR"
@echo
@echo "Under the '$(CONFIG)' configutation, the target you are trying "
@echo "to build requires systemtap 2.7+ (on Linux) or dtrace (on other "
@echo "platforms such as Solaris and *BSD). "
@echo
@echo "Please consult INSTALL to get more information."
@echo
stop:
@false
@ -863,6 +898,18 @@ endif
% endfor
ifeq ($(CONFIG),stapprof)
src/core/profiling/stap_timers.c: $(GENDIR)/src/core/profiling/stap_probes.h
ifeq ($(HAS_SYSTEMTAP),true)
$(GENDIR)/src/core/profiling/stap_probes.h: src/core/profiling/stap_probes.d
$(E) "[DTRACE] Compiling $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(DTRACE) -C -h -s $< -o $@
else
$(GENDIR)/src/core/profiling/stap_probes.h: systemtap_dep_error stop
endif
endif
$(OBJDIR)/$(CONFIG)/%.o : %.c
$(E) "[C] Compiling $<"
$(Q) mkdir -p `dirname $@`
@ -883,7 +930,6 @@ $(OBJDIR)/$(CONFIG)/%.o : %.cc
$(Q) mkdir -p `dirname $@`
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
install: install_c install_cxx install-plugins install-certs verify-install
install_c: install-headers_c install-static_c install-shared_c

@ -32,9 +32,9 @@
<%namespace file="packages.include" import="get_openssl,get_zlib"/>\
<%def name="to_windows_path(path)">${path.replace('/','\\')}</%def>\
<%
allowed_dependencies = set(['gpr', 'grpc', 'gpr_test_util', 'grpc_test_util'])
disallowed_dependencies = set(['end2end_certs'])
buildable_targets = [ target for target in targets
if set(target.deps).issubset(allowed_dependencies) and
if not disallowed_dependencies.intersection(target.deps) and
all([src.endswith('.c') for src in target.src]) and
'windows' in target.platforms ]
c_test_targets = [ target for target in buildable_targets if target.build == 'test' and not target.language == 'c++' ]

@ -0,0 +1,42 @@
/*
*
* Copyright 2015, 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 <sys/sdt.h>
#ifndef _SYS_SDT_H
#error "_SYS_SDT_H not defined, despite <sys/sdt.h> being present."
#endif
int main() {
return 0;
}

@ -1,138 +0,0 @@
/*
*
* Copyright 2015, 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 <grpc/grpc.h>
#include <string.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include <grpc/byte_buffer.h>
#include "test/core/util/test_config.h"
enum { WRITE_SLICE_LENGTH = 1024, TOTAL_BYTES = 102400 };
/* Start write the next slice, fill slice.data[0..length - 1] with first % 256,
(first + 1) % 256, ... (first + length - 1) % 256.
Produce a GRPC_WRITE_ACCEPTED event */
static void start_write_next_slice(grpc_call *call, int first, int length) {
int i = 0;
grpc_byte_buffer *byte_buffer = NULL;
gpr_slice slice = gpr_slice_malloc(length);
for (i = 0; i < length; i++)
GPR_SLICE_START_PTR(slice)[i] = (first + i) % 256;
byte_buffer = grpc_byte_buffer_create(&slice, 1);
GPR_ASSERT(grpc_call_start_write_old(call, byte_buffer, (void *)1, 0) ==
GRPC_CALL_OK);
gpr_slice_unref(slice);
grpc_byte_buffer_destroy(byte_buffer);
}
int main(int argc, char **argv) {
grpc_channel *channel = NULL;
grpc_call *call = NULL;
grpc_event *ev = NULL;
grpc_byte_buffer_reader *bb_reader = NULL;
grpc_completion_queue *cq = NULL;
int bytes_written = 0;
int bytes_read = 0;
unsigned i = 0;
int waiting_finishes;
gpr_slice read_slice;
grpc_test_init(argc, argv);
grpc_init();
cq = grpc_completion_queue_create();
GPR_ASSERT(argc == 2);
channel = grpc_channel_create(argv[1], NULL);
call = grpc_channel_create_call_old(channel, "/foo", "localhost",
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5));
GPR_ASSERT(grpc_call_invoke_old(call, cq, (void *)1, (void *)1, 0) ==
GRPC_CALL_OK);
start_write_next_slice(call, bytes_written, WRITE_SLICE_LENGTH);
bytes_written += WRITE_SLICE_LENGTH;
GPR_ASSERT(grpc_call_start_read_old(call, (void *)1) == GRPC_CALL_OK);
waiting_finishes = 2;
while (waiting_finishes) {
ev = grpc_completion_queue_next(cq, gpr_inf_future);
switch (ev->type) {
case GRPC_WRITE_ACCEPTED:
if (bytes_written < TOTAL_BYTES) {
start_write_next_slice(call, bytes_written, WRITE_SLICE_LENGTH);
bytes_written += WRITE_SLICE_LENGTH;
} else {
GPR_ASSERT(grpc_call_writes_done_old(call, (void *)1) ==
GRPC_CALL_OK);
}
break;
case GRPC_CLIENT_METADATA_READ:
break;
case GRPC_READ:
bb_reader = grpc_byte_buffer_reader_create(ev->data.read);
while (grpc_byte_buffer_reader_next(bb_reader, &read_slice)) {
for (i = 0; i < GPR_SLICE_LENGTH(read_slice); i++) {
GPR_ASSERT(GPR_SLICE_START_PTR(read_slice)[i] == bytes_read % 256);
bytes_read++;
}
gpr_slice_unref(read_slice);
}
grpc_byte_buffer_reader_destroy(bb_reader);
if (bytes_read < TOTAL_BYTES) {
GPR_ASSERT(grpc_call_start_read_old(call, (void *)1) == GRPC_CALL_OK);
}
break;
case GRPC_FINISHED:
case GRPC_FINISH_ACCEPTED:
waiting_finishes--;
break;
default:
GPR_ASSERT(0 && "unexpected event");
break;
}
grpc_event_finish(ev);
}
GPR_ASSERT(bytes_read == TOTAL_BYTES);
gpr_log(GPR_INFO, "All data have been successfully echoed");
grpc_call_destroy(call);
grpc_channel_destroy(channel);
grpc_completion_queue_destroy(cq);
grpc_shutdown();
return 0;
}

@ -1,135 +0,0 @@
/*
*
* Copyright 2015, 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 _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "src/core/iomgr/socket_utils_posix.h"
#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include "test/core/util/port.h"
int test_client(const char *root, const char *host, int port) {
int status;
pid_t cli;
cli = fork();
if (cli == 0) {
char *binary_path;
char *binding;
gpr_asprintf(&binary_path, "%s/echo_client", root);
gpr_join_host_port(&binding, host, port);
execl(binary_path, binary_path, binding, NULL);
gpr_free(binary_path);
gpr_free(binding);
return 1;
}
/* wait for client */
gpr_log(GPR_INFO, "Waiting for client: %s", host);
if (waitpid(cli, &status, 0) == -1) return 2;
if (!WIFEXITED(status)) return 4;
if (WEXITSTATUS(status)) return WEXITSTATUS(status);
return 0;
}
int main(int argc, char **argv) {
char *me = argv[0];
char *lslash = strrchr(me, '/');
char root[1024];
int port = grpc_pick_unused_port_or_die();
int status;
pid_t svr;
int ret;
int do_ipv6 = 1;
/* seed rng with pid, so we don't end up with the same random numbers as a
concurrently running test binary */
srand(getpid());
if (!grpc_ipv6_loopback_available()) {
gpr_log(GPR_INFO, "Can't bind to ::1. Skipping IPv6 tests.");
do_ipv6 = 0;
}
/* figure out where we are */
if (lslash) {
memcpy(root, me, lslash - me);
root[lslash - me] = 0;
} else {
strcpy(root, ".");
}
/* start the server */
svr = fork();
if (svr == 0) {
char *binary_path;
char *binding;
gpr_asprintf(&binary_path, "%s/echo_server", root);
gpr_join_host_port(&binding, "::", port);
execl(binary_path, binary_path, "-bind", binding, NULL);
gpr_free(binary_path);
gpr_free(binding);
return 1;
}
/* wait a little */
sleep(2);
/* start the clients */
ret = test_client(root, "127.0.0.1", port);
if (ret != 0) return ret;
ret = test_client(root, "::ffff:127.0.0.1", port);
if (ret != 0) return ret;
ret = test_client(root, "localhost", port);
if (ret != 0) return ret;
if (do_ipv6) {
ret = test_client(root, "::1", port);
if (ret != 0) return ret;
}
/* wait for server */
gpr_log(GPR_INFO, "Waiting for server");
kill(svr, SIGINT);
if (waitpid(svr, &status, 0) == -1) return 2;
if (!WIFEXITED(status)) return 4;
if (WEXITSTATUS(status)) return WEXITSTATUS(status);
return 0;
}

@ -1,223 +0,0 @@
/*
*
* Copyright 2015, 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 <grpc/grpc.h>
#include <grpc/grpc_http.h>
#include <grpc/grpc_security.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "src/core/support/string.h"
#include "test/core/util/test_config.h"
#include <grpc/support/alloc.h>
#include <grpc/support/cmdline.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "test/core/util/port.h"
#include "test/core/end2end/data/ssl_test_data.h"
static grpc_completion_queue *cq;
static grpc_server *server;
static int got_sigint = 0;
typedef struct {
gpr_refcount pending_ops;
gpr_intmax bytes_read;
} call_state;
static void request_call(void) {
call_state *tag = gpr_malloc(sizeof(*tag));
gpr_ref_init(&tag->pending_ops, 2);
tag->bytes_read = 0;
grpc_server_request_call_old(server, tag);
}
static void assert_read_ok(call_state *s, grpc_byte_buffer *b) {
grpc_byte_buffer_reader *bb_reader = NULL;
gpr_slice read_slice;
unsigned i;
bb_reader = grpc_byte_buffer_reader_create(b);
while (grpc_byte_buffer_reader_next(bb_reader, &read_slice)) {
for (i = 0; i < GPR_SLICE_LENGTH(read_slice); i++) {
GPR_ASSERT(GPR_SLICE_START_PTR(read_slice)[i] == s->bytes_read % 256);
s->bytes_read++;
}
gpr_slice_unref(read_slice);
}
grpc_byte_buffer_reader_destroy(bb_reader);
}
static void sigint_handler(int x) { got_sigint = 1; }
int main(int argc, char **argv) {
grpc_event *ev;
call_state *s;
char *addr_buf = NULL;
gpr_cmdline *cl;
int shutdown_started = 0;
int shutdown_finished = 0;
int secure = 0;
char *addr = NULL;
char *fake_argv[1];
#define MAX_ARGS 4
grpc_arg arge[MAX_ARGS];
grpc_arg *e;
grpc_channel_args args = {0, NULL};
grpc_http_server_page home_page = {"/", "text/html",
"<head>\n"
"<title>Echo Server</title>\n"
"</head>\n"
"<body>\n"
"Welcome to the world of the future!\n"
"</body>\n"};
GPR_ASSERT(argc >= 1);
fake_argv[0] = argv[0];
grpc_test_init(1, fake_argv);
grpc_init();
srand(clock());
memset(arge, 0, sizeof(arge));
args.args = arge;
cl = gpr_cmdline_create("echo server");
gpr_cmdline_add_string(cl, "bind", "Bind host:port", &addr);
gpr_cmdline_add_flag(cl, "secure", "Run with security?", &secure);
gpr_cmdline_parse(cl, argc, argv);
gpr_cmdline_destroy(cl);
e = &arge[args.num_args++];
e->type = GRPC_ARG_POINTER;
e->key = GRPC_ARG_SERVE_OVER_HTTP;
e->value.pointer.p = &home_page;
if (addr == NULL) {
gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die());
addr = addr_buf;
}
gpr_log(GPR_INFO, "creating server on: %s", addr);
cq = grpc_completion_queue_create();
if (secure) {
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key,
test_server1_cert};
grpc_server_credentials *ssl_creds =
grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1);
server = grpc_server_create(cq, &args);
GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
grpc_server_credentials_release(ssl_creds);
} else {
server = grpc_server_create(cq, &args);
GPR_ASSERT(grpc_server_add_http2_port(server, addr));
}
grpc_server_start(server);
gpr_free(addr_buf);
addr = addr_buf = NULL;
request_call();
signal(SIGINT, sigint_handler);
while (!shutdown_finished) {
if (got_sigint && !shutdown_started) {
gpr_log(GPR_INFO, "Shutting down due to SIGINT");
grpc_server_shutdown(server);
grpc_completion_queue_shutdown(cq);
shutdown_started = 1;
}
ev = grpc_completion_queue_next(
cq, gpr_time_add(gpr_now(), gpr_time_from_seconds(1)));
if (!ev) continue;
s = ev->tag;
switch (ev->type) {
case GRPC_SERVER_RPC_NEW:
if (ev->call != NULL) {
/* initial ops are already started in request_call */
grpc_call_server_accept_old(ev->call, cq, s);
grpc_call_server_end_initial_metadata_old(ev->call,
GRPC_WRITE_BUFFER_HINT);
GPR_ASSERT(grpc_call_start_read_old(ev->call, s) == GRPC_CALL_OK);
request_call();
} else {
GPR_ASSERT(shutdown_started);
gpr_free(s);
}
break;
case GRPC_WRITE_ACCEPTED:
GPR_ASSERT(ev->data.write_accepted == GRPC_OP_OK);
GPR_ASSERT(grpc_call_start_read_old(ev->call, s) == GRPC_CALL_OK);
break;
case GRPC_READ:
if (ev->data.read) {
assert_read_ok(ev->tag, ev->data.read);
GPR_ASSERT(grpc_call_start_write_old(ev->call, ev->data.read, s,
GRPC_WRITE_BUFFER_HINT) ==
GRPC_CALL_OK);
} else {
GPR_ASSERT(grpc_call_start_write_status_old(ev->call, GRPC_STATUS_OK,
NULL, s) == GRPC_CALL_OK);
}
break;
case GRPC_FINISH_ACCEPTED:
case GRPC_FINISHED:
if (gpr_unref(&s->pending_ops)) {
grpc_call_destroy(ev->call);
gpr_free(s);
}
break;
case GRPC_QUEUE_SHUTDOWN:
GPR_ASSERT(shutdown_started);
shutdown_finished = 1;
break;
default:
GPR_ASSERT(0);
}
grpc_event_finish(ev);
}
grpc_server_destroy(server);
grpc_completion_queue_destroy(cq);
grpc_shutdown();
return 0;
}

@ -61,23 +61,7 @@ typedef struct expectation {
grpc_completion_type type;
void *tag;
union {
grpc_op_error finish_accepted;
grpc_op_error write_accepted;
grpc_op_error op_complete;
struct {
const char *method;
const char *host;
gpr_timespec deadline;
grpc_call **output_call;
metadata *metadata;
} server_rpc_new;
metadata *client_metadata_read;
struct {
grpc_status_code status;
const char *details;
metadata *metadata;
} finished;
gpr_slice *read;
} data;
} expectation;
@ -121,17 +105,6 @@ int contains_metadata(grpc_metadata_array *array, const char *key,
return has_metadata(array->metadata, array->count, key, value);
}
static void verify_and_destroy_metadata(metadata *md, grpc_metadata *elems,
size_t count) {
size_t i;
for (i = 0; i < md->count; i++) {
GPR_ASSERT(has_metadata(elems, count, md->keys[i], md->values[i]));
}
gpr_free(md->keys);
gpr_free(md->values);
gpr_free(md);
}
static gpr_slice merge_slices(gpr_slice *slices, size_t nslices) {
size_t i;
size_t len = 0;
@ -168,60 +141,13 @@ int byte_buffer_eq_string(grpc_byte_buffer *bb, const char *str) {
return byte_buffer_eq_slice(bb, gpr_slice_from_copied_string(str));
}
static int string_equivalent(const char *a, const char *b) {
if (a == NULL) return b == NULL || b[0] == 0;
if (b == NULL) return a[0] == 0;
return strcmp(a, b) == 0;
}
static void verify_matches(expectation *e, grpc_event *ev) {
GPR_ASSERT(e->type == ev->type);
switch (e->type) {
case GRPC_FINISH_ACCEPTED:
GPR_ASSERT(e->data.finish_accepted == ev->data.finish_accepted);
break;
case GRPC_WRITE_ACCEPTED:
GPR_ASSERT(e->data.write_accepted == ev->data.write_accepted);
break;
case GRPC_SERVER_RPC_NEW:
GPR_ASSERT(string_equivalent(e->data.server_rpc_new.method,
ev->data.server_rpc_new.method));
GPR_ASSERT(string_equivalent(e->data.server_rpc_new.host,
ev->data.server_rpc_new.host));
GPR_ASSERT(gpr_time_cmp(e->data.server_rpc_new.deadline,
ev->data.server_rpc_new.deadline) <= 0);
*e->data.server_rpc_new.output_call = ev->call;
verify_and_destroy_metadata(e->data.server_rpc_new.metadata,
ev->data.server_rpc_new.metadata_elements,
ev->data.server_rpc_new.metadata_count);
break;
case GRPC_CLIENT_METADATA_READ:
verify_and_destroy_metadata(e->data.client_metadata_read,
ev->data.client_metadata_read.elements,
ev->data.client_metadata_read.count);
break;
case GRPC_FINISHED:
if (e->data.finished.status != GRPC_STATUS__DO_NOT_USE) {
GPR_ASSERT(e->data.finished.status == ev->data.finished.status);
GPR_ASSERT(string_equivalent(e->data.finished.details,
ev->data.finished.details));
}
verify_and_destroy_metadata(e->data.finished.metadata,
ev->data.finished.metadata_elements,
ev->data.finished.metadata_count);
break;
case GRPC_QUEUE_SHUTDOWN:
gpr_log(GPR_ERROR, "premature queue shutdown");
abort();
break;
case GRPC_READ:
if (e->data.read) {
GPR_ASSERT(byte_buffer_eq_slice(ev->data.read, *e->data.read));
gpr_free(e->data.read);
} else {
GPR_ASSERT(ev->data.read == NULL);
}
break;
case GRPC_OP_COMPLETE:
GPR_ASSERT(e->data.op_complete == ev->data.op_complete);
break;
@ -234,66 +160,14 @@ static void verify_matches(expectation *e, grpc_event *ev) {
}
}
static void metadata_expectation(gpr_strvec *buf, metadata *md) {
size_t i;
char *tmp;
if (!md) {
gpr_strvec_add(buf, gpr_strdup("nil"));
} else {
for (i = 0; i < md->count; i++) {
gpr_asprintf(&tmp, "%c%s:%s", i ? ',' : '{', md->keys[i], md->values[i]);
gpr_strvec_add(buf, tmp);
}
if (md->count) {
gpr_strvec_add(buf, gpr_strdup("}"));
}
}
}
static void expectation_to_strvec(gpr_strvec *buf, expectation *e) {
gpr_timespec timeout;
char *tmp;
switch (e->type) {
case GRPC_FINISH_ACCEPTED:
gpr_asprintf(&tmp, "GRPC_FINISH_ACCEPTED result=%d",
e->data.finish_accepted);
gpr_strvec_add(buf, tmp);
break;
case GRPC_WRITE_ACCEPTED:
gpr_asprintf(&tmp, "GRPC_WRITE_ACCEPTED result=%d",
e->data.write_accepted);
gpr_strvec_add(buf, tmp);
break;
case GRPC_OP_COMPLETE:
gpr_asprintf(&tmp, "GRPC_OP_COMPLETE result=%d", e->data.op_complete);
gpr_strvec_add(buf, tmp);
break;
case GRPC_SERVER_RPC_NEW:
timeout = gpr_time_sub(e->data.server_rpc_new.deadline, gpr_now());
gpr_asprintf(&tmp, "GRPC_SERVER_RPC_NEW method=%s host=%s timeout=%fsec",
e->data.server_rpc_new.method, e->data.server_rpc_new.host,
timeout.tv_sec + 1e-9 * timeout.tv_nsec);
gpr_strvec_add(buf, tmp);
break;
case GRPC_CLIENT_METADATA_READ:
gpr_strvec_add(buf, gpr_strdup("GRPC_CLIENT_METADATA_READ "));
metadata_expectation(buf, e->data.client_metadata_read);
break;
case GRPC_FINISHED:
gpr_asprintf(&tmp, "GRPC_FINISHED status=%d details=%s ",
e->data.finished.status, e->data.finished.details);
gpr_strvec_add(buf, tmp);
metadata_expectation(buf, e->data.finished.metadata);
break;
case GRPC_READ:
gpr_strvec_add(buf, gpr_strdup("GRPC_READ data="));
gpr_strvec_add(
buf,
gpr_hexdump((char *)GPR_SLICE_START_PTR(*e->data.read),
GPR_SLICE_LENGTH(*e->data.read), GPR_HEXDUMP_PLAINTEXT));
break;
case GRPC_SERVER_SHUTDOWN:
gpr_strvec_add(buf, gpr_strdup("GRPC_SERVER_SHUTDOWN"));
break;
@ -395,104 +269,10 @@ static expectation *add(cq_verifier *v, grpc_completion_type type, void *tag) {
return e;
}
static metadata *metadata_from_args(va_list args) {
metadata *md = gpr_malloc(sizeof(metadata));
const char *key, *value;
md->count = 0;
md->cap = 0;
md->keys = NULL;
md->values = NULL;
for (;;) {
key = va_arg(args, const char *);
if (!key) return md;
value = va_arg(args, const char *);
GPR_ASSERT(value);
if (md->cap == md->count) {
md->cap = GPR_MAX(md->cap + 1, md->cap * 3 / 2);
md->keys = gpr_realloc(md->keys, sizeof(char *) * md->cap);
md->values = gpr_realloc(md->values, sizeof(char *) * md->cap);
}
md->keys[md->count] = (char *)key;
md->values[md->count] = (char *)value;
md->count++;
}
}
void cq_expect_write_accepted(cq_verifier *v, void *tag, grpc_op_error result) {
add(v, GRPC_WRITE_ACCEPTED, tag)->data.write_accepted = result;
}
void cq_expect_completion(cq_verifier *v, void *tag, grpc_op_error result) {
add(v, GRPC_OP_COMPLETE, tag)->data.op_complete = result;
}
void cq_expect_finish_accepted(cq_verifier *v, void *tag,
grpc_op_error result) {
add(v, GRPC_FINISH_ACCEPTED, tag)->data.finish_accepted = result;
}
void cq_expect_read(cq_verifier *v, void *tag, gpr_slice bytes) {
expectation *e = add(v, GRPC_READ, tag);
e->data.read = gpr_malloc(sizeof(gpr_slice));
*e->data.read = bytes;
}
void cq_expect_empty_read(cq_verifier *v, void *tag) {
expectation *e = add(v, GRPC_READ, tag);
e->data.read = NULL;
}
void cq_expect_server_rpc_new(cq_verifier *v, grpc_call **output_call,
void *tag, const char *method, const char *host,
gpr_timespec deadline, ...) {
va_list args;
expectation *e = add(v, GRPC_SERVER_RPC_NEW, tag);
e->data.server_rpc_new.method = method;
e->data.server_rpc_new.host = host;
e->data.server_rpc_new.deadline = deadline;
e->data.server_rpc_new.output_call = output_call;
va_start(args, deadline);
e->data.server_rpc_new.metadata = metadata_from_args(args);
va_end(args);
}
void cq_expect_client_metadata_read(cq_verifier *v, void *tag, ...) {
va_list args;
expectation *e = add(v, GRPC_CLIENT_METADATA_READ, tag);
va_start(args, tag);
e->data.client_metadata_read = metadata_from_args(args);
va_end(args);
}
static void finished_internal(cq_verifier *v, void *tag,
grpc_status_code status, const char *details,
va_list args) {
expectation *e = add(v, GRPC_FINISHED, tag);
e->data.finished.status = status;
e->data.finished.details = details;
e->data.finished.metadata = metadata_from_args(args);
}
void cq_expect_finished_with_status(cq_verifier *v, void *tag,
grpc_status_code status,
const char *details, ...) {
va_list args;
va_start(args, details);
finished_internal(v, tag, status, details, args);
va_end(args);
}
void cq_expect_finished(cq_verifier *v, void *tag, ...) {
va_list args;
va_start(args, tag);
finished_internal(v, tag, GRPC_STATUS__DO_NOT_USE, NULL, args);
va_end(args);
}
void cq_expect_server_shutdown(cq_verifier *v, void *tag) {
add(v, GRPC_SERVER_SHUTDOWN, tag);
}

@ -57,20 +57,7 @@ void cq_verify_empty(cq_verifier *v);
Any functions taking ... expect a NULL terminated list of key/value pairs
(each pair using two parameter slots) of metadata that MUST be present in
the event. */
void cq_expect_write_accepted(cq_verifier *v, void *tag, grpc_op_error result);
void cq_expect_finish_accepted(cq_verifier *v, void *tag, grpc_op_error result);
void cq_expect_read(cq_verifier *v, void *tag, gpr_slice bytes);
void cq_expect_empty_read(cq_verifier *v, void *tag);
void cq_expect_completion(cq_verifier *v, void *tag, grpc_op_error result);
/* *output_call is set the the server call instance */
void cq_expect_server_rpc_new(cq_verifier *v, grpc_call **output_call,
void *tag, const char *method, const char *host,
gpr_timespec deadline, ...);
void cq_expect_client_metadata_read(cq_verifier *v, void *tag, ...);
void cq_expect_finished_with_status(cq_verifier *v, void *tag,
grpc_status_code status_code,
const char *details, ...);
void cq_expect_finished(cq_verifier *v, void *tag, ...);
void cq_expect_server_shutdown(cq_verifier *v, void *tag);
int byte_buffer_eq_string(grpc_byte_buffer *byte_buffer, const char *string);

@ -31,6 +31,7 @@
*
*/
#include <string.h>
#include "src/core/iomgr/socket_utils_posix.h"
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
@ -74,6 +75,16 @@ void test_connect(const char *server_host, const char *client_host, int port,
cq_verifier *v_server;
gpr_timespec deadline;
int got_port;
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
int was_cancelled = 2;
grpc_call_details call_details;
if (port == 0) {
port = grpc_pick_unused_port_or_die();
@ -81,6 +92,11 @@ void test_connect(const char *server_host, const char *client_host, int port,
gpr_join_host_port(&server_hostport, server_host, port);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
/* Create server. */
server_cq = grpc_completion_queue_create();
server = grpc_server_create(server_cq, NULL);
@ -116,54 +132,74 @@ void test_connect(const char *server_host, const char *client_host, int port,
}
/* Send a trivial request. */
c = grpc_channel_create_call_old(client, "/foo", "foo.test.google.fr",
deadline);
c = grpc_channel_create_call(client, client_cq, "/foo", "foo.test.google.fr",
deadline);
GPR_ASSERT(c);
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_invoke_old(c, client_cq, tag(2), tag(3), 0));
GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c, tag(4)));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
if (expect_ok) {
/* Check for a successful request. */
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(server, tag(100)));
cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
"foo.test.google.fr", deadline, NULL);
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(server, &s,
&call_details,
&request_metadata_recv,
server_cq, tag(101)));
cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
cq_verify(v_server);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
op->data.send_status_from_server.status_details = "xyz";
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_server_accept_old(s, 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);
grpc_call_start_batch(s, ops, op - ops, tag(102)));
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_expect_completion(v_server, tag(102), GRPC_OP_OK);
cq_verify(v_server);
cq_expect_completion(v_client, tag(1), GRPC_OP_OK);
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);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == strcmp(details, "xyz"));
GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
GPR_ASSERT(was_cancelled == 0);
grpc_call_destroy(c);
grpc_call_destroy(s);
} else {
/* Check for a failed connection. */
cq_expect_client_metadata_read(v_client, tag(2), NULL);
cq_expect_finished_with_status(v_client, tag(3),
GRPC_STATUS_DEADLINE_EXCEEDED,
"Deadline Exceeded", NULL);
cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK);
cq_expect_completion(v_client, tag(1), GRPC_OP_OK);
cq_verify(v_client);
grpc_call_destroy(c);
GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED);
}
grpc_call_destroy(c);
cq_verifier_destroy(v_client);
cq_verifier_destroy(v_server);

@ -72,33 +72,6 @@ END2END_TESTS = {
'simple_delayed_request': True,
'simple_request': True,
'registered_call': True,
'thread_stress': True,
'writes_done_hangs_with_pending_read': True,
'cancel_after_accept_legacy': False,
'cancel_after_accept_and_writes_closed_legacy': True,
'cancel_after_invoke_legacy': True,
'cancel_before_invoke_legacy': True,
'cancel_in_a_vacuum_legacy': True,
'census_simple_request_legacy': True,
'disappearing_server_legacy': True,
'early_server_shutdown_finishes_inflight_calls_legacy': True,
'early_server_shutdown_finishes_tags_legacy': True,
'graceful_server_shutdown_legacy': True,
'invoke_large_request_legacy': False,
'max_concurrent_streams_legacy': True,
'no_op_legacy': True,
'ping_pong_streaming_legacy': True,
'request_response_with_binary_metadata_and_payload_legacy': True,
'request_response_with_metadata_and_payload_legacy': True,
'request_response_with_payload_legacy': True,
'request_response_with_trailing_metadata_and_payload_legacy': True,
'request_with_large_metadata_legacy': True,
'request_with_payload_legacy': True,
'simple_delayed_request_legacy': True,
'simple_request_legacy': True,
'thread_stress_legacy': True,
'writes_done_hangs_with_pending_read_legacy': True,
}

@ -32,6 +32,7 @@
*/
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "test/core/end2end/cq_verifier.h"
#include "test/core/util/test_config.h"
@ -46,23 +47,43 @@ int main(int argc, char **argv) {
cq_verifier *cqv;
grpc_event *ev;
int done;
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array trailing_metadata_recv;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
grpc_test_init(argc, argv);
grpc_init();
grpc_metadata_array_init(&trailing_metadata_recv);
cq = grpc_completion_queue_create();
cqv = cq_verifier_create(cq);
/* create a call, channel to a non existant server */
chan = grpc_channel_create("nonexistant:54321", NULL);
call = grpc_channel_create_call_old(chan, "/foo", "nonexistant", deadline);
GPR_ASSERT(grpc_call_invoke_old(call, cq, tag(2), tag(3), 0) == GRPC_CALL_OK);
call = grpc_channel_create_call(chan, cq, "/Foo", "nonexistant", deadline);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_start_batch(call, ops, op - ops, tag(1)));
/* verify that all tags get completed */
cq_expect_client_metadata_read(cqv, tag(2), NULL);
cq_expect_finished_with_status(cqv, tag(3), GRPC_STATUS_DEADLINE_EXCEEDED,
"Deadline Exceeded", NULL);
cq_expect_completion(cqv, tag(1), GRPC_OP_OK);
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED);
grpc_completion_queue_shutdown(cq);
for (done = 0; !done;) {
ev = grpc_completion_queue_next(cq, gpr_inf_future);
@ -74,6 +95,9 @@ int main(int argc, char **argv) {
grpc_channel_destroy(chan);
cq_verifier_destroy(cqv);
gpr_free(details);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_shutdown();
return 0;

@ -153,8 +153,6 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = request_payload;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
@ -173,15 +171,15 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &request_payload_recv;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = response_payload;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(3)));
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c));

@ -106,48 +106,106 @@ static void end_test(grpc_end2end_test_fixture *f) {
/* 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_op ops[6];
grpc_op *op;
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", "foo.test.google.fr",
deadline);
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
grpc_byte_buffer *request_payload_recv = NULL;
grpc_byte_buffer *response_payload_recv = 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 =
grpc_byte_buffer_create(&request_payload_slice, 1);
grpc_byte_buffer *response_payload =
grpc_byte_buffer_create(&response_payload_slice, 1);
int was_cancelled = 2;
c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
"foo.test.google.fr", 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", "foo.test.google.fr",
deadline, NULL);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = request_payload;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &response_payload_recv;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
f.server, &s, &call_details,
&request_metadata_recv, f.server_cq, tag(2)));
cq_expect_completion(v_server, tag(2), GRPC_OP_OK);
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);
op = ops;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &request_payload_recv;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = response_payload;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(3)));
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 == mode.initiate_cancel(c));
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read_old(s, tag(101)));
cq_expect_empty_read(v_server, tag(101));
cq_expect_completion(v_server, tag(3), GRPC_OP_OK);
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_expect_completion(v_client, tag(1), GRPC_OP_OK);
cq_verify(v_client);
cq_expect_finished_with_status(v_server, tag(102), GRPC_STATUS_CANCELLED,
NULL, NULL);
cq_verify(v_server);
GPR_ASSERT(status == mode.expect_status);
GPR_ASSERT(0 == strcmp(details, mode.expect_details));
GPR_ASSERT(was_cancelled == 1);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload);
grpc_byte_buffer_destroy(request_payload_recv);
grpc_byte_buffer_destroy(response_payload_recv);
gpr_free(details);
grpc_call_destroy(c);
grpc_call_destroy(s);

@ -1,167 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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]);
}
}

@ -1,159 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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]);
}
}

@ -1,141 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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]);
}
}

@ -1,134 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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,
"Cancelled", 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);
}

@ -1,131 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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]);
}
}

@ -102,41 +102,85 @@ 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);
gpr_timespec deadline = n_seconds_time(5);
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", "foo.test.google.fr",
deadline);
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
int was_cancelled = 2;
c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
"foo.test.google.fr:1234", 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);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
&call_details,
&request_metadata_recv,
f.server_cq, tag(101)));
cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
cq_verify(v_server);
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", "foo.test.google.fr",
deadline, NULL);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
op->data.send_status_from_server.status_details = "xyz";
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102)));
cq_expect_completion(v_server, tag(102), GRPC_OP_OK);
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_expect_completion(v_client, tag(1), GRPC_OP_OK);
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);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == strcmp(details, "xyz"));
GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234"));
GPR_ASSERT(was_cancelled == 0);
gpr_free(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
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);

@ -1,178 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -96,42 +96,85 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f,
grpc_call *c;
grpc_call *s;
gpr_timespec deadline = five_seconds_time();
c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.fr",
deadline);
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
int was_cancelled = 2;
c = grpc_channel_create_call(f->client, f->client_cq, "/foo",
"foo.test.google.fr:1234", 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", "foo.test.google.fr",
deadline, NULL);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f->server, &s,
&call_details,
&request_metadata_recv,
f->server_cq, tag(101)));
cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
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);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
op->data.send_status_from_server.status_details = "xyz";
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102)));
cq_expect_completion(v_server, tag(102), GRPC_OP_OK);
cq_verify(v_server);
cq_expect_completion(v_client, tag(1), GRPC_OP_OK);
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);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == strcmp(details, "xyz"));
GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234"));
GPR_ASSERT(was_cancelled == 0);
gpr_free(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_call_destroy(c);
grpc_call_destroy(s);

@ -1,168 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}
}

@ -104,48 +104,85 @@ static void end_test(grpc_end2end_test_fixture *f) {
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();
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);
c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
deadline);
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
int was_cancelled = 2;
c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
"foo.test.google.fr", 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", "foo.test.google.fr",
deadline, NULL);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->data.send_initial_metadata.metadata = NULL;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
&call_details,
&request_metadata_recv,
f.server_cq, tag(101)));
cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
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);
op = ops;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102)));
/* shutdown and destroy the server */
shutdown_server(&f);
cq_expect_finished(v_server, tag(102), NULL);
cq_expect_completion(v_server, tag(102), GRPC_OP_OK);
cq_verify(v_server);
grpc_call_destroy(s);
cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNAVAILABLE,
NULL, NULL);
cq_expect_completion(v_client, tag(1), GRPC_OP_OK);
cq_verify(v_client);
GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
GPR_ASSERT(was_cancelled == 1);
gpr_free(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_call_destroy(c);
grpc_call_destroy(s);
cq_verifier_destroy(v_client);
cq_verifier_destroy(v_server);

@ -1,159 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -107,13 +107,20 @@ static void test_early_server_shutdown_finishes_tags(
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;
grpc_call_details call_details;
grpc_metadata_array request_metadata_recv;
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
/* upon shutdown, the server should finish all requested calls indicating
no new call */
grpc_server_request_call_old(f.server, tag(1000));
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
&call_details,
&request_metadata_recv,
f.server_cq, tag(101)));
grpc_server_shutdown(f.server);
cq_expect_server_rpc_new(v_server, &s, tag(1000), NULL, NULL, gpr_inf_past,
NULL);
cq_expect_completion(v_server, tag(101), GRPC_OP_ERROR);
cq_verify(v_server);
GPR_ASSERT(s == NULL);

@ -1,127 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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);
}

@ -103,49 +103,96 @@ static void end_test(grpc_end2end_test_fixture *f) {
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();
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);
c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
deadline);
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
int was_cancelled = 2;
c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
"foo.test.google.fr", 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", "foo.test.google.fr",
deadline, NULL);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->data.send_initial_metadata.metadata = NULL;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
&call_details,
&request_metadata_recv,
f.server_cq, tag(101)));
cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
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 */
/* shutdown and destroy 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));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
op->data.send_status_from_server.status_details = "xyz";
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102)));
cq_expect_completion(v_server, tag(102), GRPC_OP_OK);
cq_verify(v_server);
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_expect_completion(v_client, tag(1), GRPC_OP_OK);
cq_verify(v_client);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
GPR_ASSERT(was_cancelled == 0);
gpr_free(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_call_destroy(c);
cq_verifier_destroy(v_client);

@ -1,160 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -107,66 +107,108 @@ static gpr_slice large_slice(void) {
}
static void test_invoke_large_request(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
gpr_slice request_payload_slice = large_slice();
gpr_slice response_payload_slice = large_slice();
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);
grpc_byte_buffer *response_payload =
grpc_byte_buffer_create(&response_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", "foo.test.google.fr",
deadline);
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_byte_buffer *request_payload_recv = NULL;
grpc_byte_buffer *response_payload_recv = NULL;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
int was_cancelled = 2;
c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
"foo.test.google.fr", 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", "foo.test.google.fr",
deadline, NULL);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = request_payload;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &response_payload_recv;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
&call_details,
&request_metadata_recv,
f.server_cq, tag(101)));
cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
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());
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = response_payload;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
op->data.send_status_from_server.status_details = "xyz";
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &request_payload_recv;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102)));
cq_expect_completion(v_server, tag(102), GRPC_OP_OK);
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_expect_completion(v_client, tag(1), GRPC_OP_OK);
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);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == strcmp(details, "xyz"));
GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
GPR_ASSERT(was_cancelled == 0);
gpr_free(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_call_destroy(c);
grpc_call_destroy(s);
@ -174,6 +216,13 @@ static void test_invoke_large_request(grpc_end2end_test_config config) {
cq_verifier_destroy(v_client);
cq_verifier_destroy(v_server);
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload);
grpc_byte_buffer_destroy(request_payload_recv);
grpc_byte_buffer_destroy(response_payload_recv);
gpr_slice_unref(request_payload_slice);
gpr_slice_unref(response_payload_slice);
end_test(&f);
config.tear_down_data(&f);
}

@ -1,183 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -108,38 +108,81 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
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", "foo.test.google.fr",
deadline);
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
int was_cancelled = 2;
c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
"foo.test.google.fr:1234", 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);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
&call_details,
&request_metadata_recv,
f.server_cq, tag(101)));
cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
cq_verify(v_server);
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", "foo.test.google.fr",
deadline, NULL);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
op->data.send_status_from_server.status_details = "xyz";
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102)));
cq_expect_completion(v_server, tag(102), GRPC_OP_OK);
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_expect_completion(v_client, tag(1), GRPC_OP_OK);
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);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == strcmp(details, "xyz"));
GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234"));
GPR_ASSERT(was_cancelled == 0);
cq_expect_finish_accepted(v_server, tag(5), GRPC_OP_OK);
cq_expect_finished(v_server, tag(102), NULL);
cq_verify(v_server);
gpr_free(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_call_destroy(c);
grpc_call_destroy(s);
@ -161,6 +204,21 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
cq_verifier *v_client;
cq_verifier *v_server;
grpc_event *ev;
grpc_call_details call_details;
grpc_metadata_array request_metadata_recv;
grpc_metadata_array initial_metadata_recv1;
grpc_metadata_array trailing_metadata_recv1;
grpc_metadata_array initial_metadata_recv2;
grpc_metadata_array trailing_metadata_recv2;
grpc_status_code status1;
char *details1 = NULL;
size_t details_capacity1 = 0;
grpc_status_code status2;
char *details2 = NULL;
size_t details_capacity2 = 0;
grpc_op ops[6];
grpc_op *op;
int was_cancelled;
server_arg.key = GRPC_ARG_MAX_CONCURRENT_STREAMS;
server_arg.type = GRPC_ARG_INTEGER;
@ -173,6 +231,13 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
v_client = cq_verifier_create(f.client_cq);
v_server = cq_verifier_create(f.server_cq);
grpc_metadata_array_init(&request_metadata_recv);
grpc_metadata_array_init(&initial_metadata_recv1);
grpc_metadata_array_init(&trailing_metadata_recv1);
grpc_metadata_array_init(&initial_metadata_recv2);
grpc_metadata_array_init(&trailing_metadata_recv2);
grpc_call_details_init(&call_details);
/* perform a ping-pong to ensure that settings have had a chance to round
trip */
simple_request_body(f);
@ -181,82 +246,130 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
/* 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", "foo.test.google.fr",
deadline);
GPR_ASSERT(c1);
c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.fr",
deadline);
deadline = n_seconds_time(10);
c1 = grpc_channel_create_call(f.client, f.client_cq, "/alpha",
"foo.test.google.fr:1234", deadline);
GPR_ASSERT(c1);
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
c2 = grpc_channel_create_call(f.client, f.client_cq, "/beta",
"foo.test.google.fr:1234", deadline);
GPR_ASSERT(c2);
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s1,
&call_details,
&request_metadata_recv,
f.server_cq, tag(101)));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_start_batch(c1, ops, op - ops, tag(301)));
op = ops;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv1;
op->data.recv_status_on_client.status = &status1;
op->data.recv_status_on_client.status_details = &details1;
op->data.recv_status_on_client.status_details_capacity = &details_capacity1;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv1;
op++;
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_invoke_old(c1, f.client_cq, tag(301), tag(302), 0));
grpc_call_start_batch(c1, ops, op - ops, tag(302)));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
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(403)));
grpc_call_start_batch(c2, ops, op - ops, tag(401)));
op = ops;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv2;
op->data.recv_status_on_client.status = &status2;
op->data.recv_status_on_client.status_details = &details2;
op->data.recv_status_on_client.status_details_capacity = &details_capacity2;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv1;
op++;
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_start_batch(c2, ops, op - ops, tag(402)));
cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
cq_verify(v_server);
ev = grpc_completion_queue_next(
f.client_cq, gpr_time_add(gpr_now(), gpr_time_from_seconds(10)));
ev = grpc_completion_queue_next(f.client_cq,
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3));
GPR_ASSERT(ev);
GPR_ASSERT(ev->type == GRPC_FINISH_ACCEPTED);
GPR_ASSERT(ev->data.invoke_accepted == GRPC_OP_OK);
GPR_ASSERT(ev->type == GRPC_OP_COMPLETE);
GPR_ASSERT(ev->data.op_complete == GRPC_OP_OK);
GPR_ASSERT(ev->tag == tag(301) || ev->tag == tag(401));
/* 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;
live_call = ((int)(gpr_intptr)ev->tag) - 1;
grpc_event_finish(ev);
cq_expect_server_rpc_new(v_server, &s1, tag(100),
live_call == 300 ? "/alpha" : "/beta",
"foo.test.google.fr", deadline, NULL);
cq_verify(v_server);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
op->data.send_status_from_server.status_details = "xyz";
op++;
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);
grpc_call_start_batch(s1, ops, op - ops, tag(102)));
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_expect_completion(v_server, tag(102), GRPC_OP_OK);
cq_verify(v_server);
cq_expect_completion(v_client, tag(live_call + 2), GRPC_OP_OK);
/* 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);
live_call = (live_call == 300) ? 400 : 300;
cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK);
cq_expect_completion(v_client, tag(live_call + 1), GRPC_OP_OK);
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",
"foo.test.google.fr", deadline, NULL);
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s2,
&call_details,
&request_metadata_recv,
f.server_cq, tag(201)));
cq_expect_completion(v_server, tag(201), GRPC_OP_OK);
cq_verify(v_server);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
op->data.send_status_from_server.status_details = "xyz";
op++;
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);
grpc_call_start_batch(s2, ops, op - ops, tag(202)));
cq_expect_completion(v_client, tag(live_call + 2), GRPC_OP_OK);
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_expect_completion(v_server, tag(202), GRPC_OP_OK);
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);
@ -265,6 +378,15 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
grpc_call_destroy(c2);
grpc_call_destroy(s2);
gpr_free(details1);
gpr_free(details2);
grpc_metadata_array_destroy(&initial_metadata_recv1);
grpc_metadata_array_destroy(&trailing_metadata_recv1);
grpc_metadata_array_destroy(&initial_metadata_recv2);
grpc_metadata_array_destroy(&trailing_metadata_recv2);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
end_test(&f);
config.tear_down_data(&f);
}

@ -1,274 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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", "foo.test.google.fr",
deadline);
GPR_ASSERT(c1);
c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.fr",
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(403)));
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",
"foo.test.google.fr", 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);
live_call = (live_call == 300) ? 400 : 300;
cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK);
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",
"foo.test.google.fr", 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);
}

@ -1,109 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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); }

@ -105,93 +105,148 @@ static void end_test(grpc_end2end_test_fixture *f) {
/* 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);
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);
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
int was_cancelled = 2;
grpc_byte_buffer *request_payload;
grpc_byte_buffer *request_payload_recv;
grpc_byte_buffer *response_payload;
grpc_byte_buffer *response_payload_recv;
int i;
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world");
gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you");
gpr_log(GPR_INFO, "testing with %d message pairs.", messages);
c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
deadline);
c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
"foo.test.google.fr:1234", 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", "foo.test.google.fr",
deadline, NULL);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
&call_details,
&request_metadata_recv,
f.server_cq, tag(100)));
cq_expect_completion(v_server, tag(100), GRPC_OP_OK);
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);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(101)));
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);
response_payload = grpc_byte_buffer_create(&response_payload_slice, 1);
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"));
op = ops;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = request_payload;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &response_payload_recv;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(2)));
op = ops;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &request_payload_recv;
op++;
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_start_batch(s, ops, op - ops, tag(102)));
cq_expect_completion(v_server, tag(102), GRPC_OP_OK);
cq_verify(v_server);
response_payload = grpc_byte_buffer_create(&response_payload_slice, 1);
op = ops;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = response_payload;
op++;
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);
grpc_call_start_batch(s, ops, op - ops, tag(103)));
cq_expect_completion(v_server, tag(103), 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_expect_completion(v_client, tag(2), GRPC_OP_OK);
cq_verify(v_client);
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload);
grpc_byte_buffer_destroy(request_payload_recv);
grpc_byte_buffer_destroy(response_payload_recv);
}
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);
op = ops;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(3)));
op = ops;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
op->data.send_status_from_server.status_details = "xyz";
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(104)));
cq_expect_completion(v_client, tag(1), GRPC_OP_OK);
cq_expect_completion(v_client, tag(3), GRPC_OP_OK);
cq_verify(v_client);
cq_expect_finish_accepted(v_server, tag(7), GRPC_OP_OK);
cq_expect_finished(v_server, tag(102), NULL);
cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
cq_expect_completion(v_server, tag(104), GRPC_OP_OK);
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);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
gpr_free(details);
end_test(&f);
config.tear_down_data(&f);
}
void grpc_end2end_tests(grpc_end2end_test_config config) {

@ -1,203 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}
}

@ -1,231 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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,
{{NULL, NULL, NULL}}};
grpc_metadata meta2 = {
"key2-bin",
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d",
14,
{{NULL, NULL, NULL}}};
grpc_metadata meta3 = {
"key3-bin",
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee",
15,
{{NULL, NULL, NULL}}};
grpc_metadata meta4 = {
"key4-bin",
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
16,
{{NULL, NULL, NULL}}};
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", "foo.test.google.fr",
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", "foo.test.google.fr", 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);
}

@ -1,208 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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, {{NULL, NULL, NULL}}};
grpc_metadata meta2 = {"key2", "val2", 4, {{NULL, NULL, NULL}}};
grpc_metadata meta3 = {"key3", "val3", 4, {{NULL, NULL, NULL}}};
grpc_metadata meta4 = {"key4", "val4", 4, {{NULL, NULL, NULL}}};
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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -1,208 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -1,213 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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, {{NULL, NULL, NULL}}};
grpc_metadata meta2 = {"key2", "val2", 4, {{NULL, NULL, NULL}}};
grpc_metadata meta3 = {"key3", "val3", 4, {{NULL, NULL, NULL}}};
grpc_metadata meta4 = {"key4", "val4", 4, {{NULL, NULL, NULL}}};
grpc_metadata meta5 = {"key5", "val5", 4, {{NULL, NULL, NULL}}};
grpc_metadata meta6 = {"key6", "val6", 4, {{NULL, NULL, NULL}}};
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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -1,172 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -1,172 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -1,175 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}
}

@ -1,232 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -1,325 +0,0 @@
/*
*
* Copyright 2015, 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>
#include "test/core/util/test_config.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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr", 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);
}

@ -1,325 +0,0 @@
/*
*
* Copyright 2015, 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>
#include "test/core/util/test_config.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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr", 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);
}

@ -1,199 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -1,199 +0,0 @@
/*
*
* Copyright 2015, 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 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(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", "foo.test.google.fr",
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", "foo.test.google.fr",
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);
}

@ -39,6 +39,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "test/core/util/grpc_profiler.h"
#include "test/core/util/test_config.h"
@ -165,7 +166,7 @@ static void start_send_status(void) {
tag(FLING_SERVER_SEND_STATUS_FOR_STREAMING)));
}
static void sigint_handler(int x) { got_sigint = 1; }
static void sigint_handler(int x) { _exit(0); }
int main(int argc, char **argv) {
grpc_event *ev;
@ -292,14 +293,6 @@ int main(int argc, char **argv) {
break;
}
break;
case GRPC_SERVER_RPC_NEW:
case GRPC_WRITE_ACCEPTED:
case GRPC_READ:
case GRPC_FINISH_ACCEPTED:
case GRPC_FINISHED:
gpr_log(GPR_ERROR, "Unexpected event type.");
abort();
break;
case GRPC_QUEUE_SHUTDOWN:
GPR_ASSERT(shutdown_started);
shutdown_finished = 1;

@ -0,0 +1,40 @@
/* This script requires a command line argument, to be used in the "process"
* probe definition.
*
* For a statically build binary, that'd be the name of the binary itself.
* For dinamically built ones, point to the location of the libgprc.so being
* used. */
global starts, times, times_per_tag
probe process(@1).mark("timing_ns_begin") {
starts[$arg1, tid()] = gettimeofday_ns();
}
probe process(@1).mark("timing_ns_end") {
tag = $arg1
t = gettimeofday_ns();
if (s = starts[tag, tid()]) {
times[tag, tid()] <<< t-s;
delete starts[tag, tid()];
}
}
probe end {
printf("%15s %9s %10s %10s %10s %10s\n", "tag", "tid", "count",
"min(ns)", "avg(ns)", "max(ns)");
foreach ([tag+, tid] in times) {
printf("%15X %9d %10d %10d %10d %10d\n", tag, tid, @count(times[tag, tid]),
@min(times[tag, tid]), @avg(times[tag, tid]), @max(times[tag, tid]));
}
printf("Per tag average of averages\n");
foreach ([tag+, tid] in times) {
times_per_tag[tag] <<< @avg(times[tag, tid]);
}
printf("%15s %10s %10s\n", "tag", "count", "avg(ns)");
foreach ([tag+] in times_per_tag) {
printf("%15X %10d %10d\n", tag, @count(times_per_tag[tag]),
@avg(times_per_tag[tag]));
}
}

@ -76,8 +76,8 @@ void test_log_events(int num_seqs) {
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
grpc_timers_log_global_init();
grpc_timers_global_init();
test_log_events(1000000);
grpc_timers_log_global_destroy();
grpc_timers_global_destroy();
return 0;
}

@ -79,7 +79,7 @@ static void test_wait_empty(void) {
shutdown_and_destroy(cc);
}
static void test_cq_end_read(void) {
static void test_cq_end_op(void) {
grpc_event *ev;
grpc_completion_queue *cc;
int on_finish_called = 0;
@ -89,94 +89,15 @@ static void test_cq_end_read(void) {
cc = grpc_completion_queue_create();
grpc_cq_begin_op(cc, NULL, GRPC_READ);
grpc_cq_end_read(cc, tag, NULL, increment_int_on_finish, &on_finish_called,
NULL);
grpc_cq_begin_op(cc, NULL, GRPC_OP_COMPLETE);
grpc_cq_end_op(cc, tag, NULL, increment_int_on_finish, &on_finish_called,
GRPC_OP_OK);
ev = grpc_completion_queue_next(cc, gpr_inf_past);
GPR_ASSERT(ev != NULL);
GPR_ASSERT(ev->type == GRPC_READ);
GPR_ASSERT(ev->type == GRPC_OP_COMPLETE);
GPR_ASSERT(ev->tag == tag);
GPR_ASSERT(ev->data.read == NULL);
GPR_ASSERT(on_finish_called == 0);
grpc_event_finish(ev);
GPR_ASSERT(on_finish_called == 1);
shutdown_and_destroy(cc);
}
static void test_cq_end_write_accepted(void) {
grpc_event *ev;
grpc_completion_queue *cc;
int on_finish_called = 0;
void *tag = create_test_tag();
LOG_TEST();
cc = grpc_completion_queue_create();
grpc_cq_begin_op(cc, NULL, GRPC_WRITE_ACCEPTED);
grpc_cq_end_write_accepted(cc, tag, NULL, increment_int_on_finish,
&on_finish_called, GRPC_OP_OK);
ev = grpc_completion_queue_next(cc, gpr_inf_past);
GPR_ASSERT(ev != NULL);
GPR_ASSERT(ev->type == GRPC_WRITE_ACCEPTED);
GPR_ASSERT(ev->tag == tag);
GPR_ASSERT(ev->data.write_accepted == GRPC_OP_OK);
GPR_ASSERT(on_finish_called == 0);
grpc_event_finish(ev);
GPR_ASSERT(on_finish_called == 1);
shutdown_and_destroy(cc);
}
static void test_cq_end_finish_accepted(void) {
grpc_event *ev;
grpc_completion_queue *cc;
int on_finish_called = 0;
void *tag = create_test_tag();
LOG_TEST();
cc = grpc_completion_queue_create();
grpc_cq_begin_op(cc, NULL, GRPC_FINISH_ACCEPTED);
grpc_cq_end_finish_accepted(cc, tag, NULL, increment_int_on_finish,
&on_finish_called, GRPC_OP_OK);
ev = grpc_completion_queue_next(cc, gpr_inf_past);
GPR_ASSERT(ev != NULL);
GPR_ASSERT(ev->type == GRPC_FINISH_ACCEPTED);
GPR_ASSERT(ev->tag == tag);
GPR_ASSERT(ev->data.finish_accepted == GRPC_OP_OK);
GPR_ASSERT(on_finish_called == 0);
grpc_event_finish(ev);
GPR_ASSERT(on_finish_called == 1);
shutdown_and_destroy(cc);
}
static void test_cq_end_client_metadata_read(void) {
grpc_event *ev;
grpc_completion_queue *cc;
int on_finish_called = 0;
void *tag = create_test_tag();
LOG_TEST();
cc = grpc_completion_queue_create();
grpc_cq_begin_op(cc, NULL, GRPC_CLIENT_METADATA_READ);
grpc_cq_end_client_metadata_read(cc, tag, NULL, increment_int_on_finish,
&on_finish_called, 0, NULL);
ev = grpc_completion_queue_next(cc, gpr_inf_past);
GPR_ASSERT(ev != NULL);
GPR_ASSERT(ev->type == GRPC_CLIENT_METADATA_READ);
GPR_ASSERT(ev->tag == tag);
GPR_ASSERT(ev->data.client_metadata_read.count == 0);
GPR_ASSERT(ev->data.client_metadata_read.elements == NULL);
GPR_ASSERT(ev->data.op_complete == GRPC_OP_OK);
GPR_ASSERT(on_finish_called == 0);
grpc_event_finish(ev);
GPR_ASSERT(on_finish_called == 1);
@ -203,9 +124,9 @@ static void test_pluck(void) {
cc = grpc_completion_queue_create();
for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
grpc_cq_begin_op(cc, NULL, GRPC_WRITE_ACCEPTED);
grpc_cq_end_write_accepted(cc, tags[i], NULL, increment_int_on_finish,
&on_finish_called, GRPC_OP_OK);
grpc_cq_begin_op(cc, NULL, GRPC_OP_COMPLETE);
grpc_cq_end_op(cc, tags[i], NULL, increment_int_on_finish,
&on_finish_called, GRPC_OP_OK);
}
for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
@ -217,9 +138,9 @@ static void test_pluck(void) {
GPR_ASSERT(on_finish_called == GPR_ARRAY_SIZE(tags));
for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
grpc_cq_begin_op(cc, NULL, GRPC_WRITE_ACCEPTED);
grpc_cq_end_write_accepted(cc, tags[i], NULL, increment_int_on_finish,
&on_finish_called, GRPC_OP_OK);
grpc_cq_begin_op(cc, NULL, GRPC_OP_COMPLETE);
grpc_cq_end_op(cc, tags[i], NULL, increment_int_on_finish,
&on_finish_called, GRPC_OP_OK);
}
for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
@ -261,7 +182,7 @@ static void producer_thread(void *arg) {
gpr_log(GPR_INFO, "producer %d phase 1", opt->id);
for (i = 0; i < TEST_THREAD_EVENTS; i++) {
grpc_cq_begin_op(opt->cc, NULL, GRPC_WRITE_ACCEPTED);
grpc_cq_begin_op(opt->cc, NULL, GRPC_OP_COMPLETE);
}
gpr_log(GPR_INFO, "producer %d phase 1 done", opt->id);
@ -270,8 +191,8 @@ static void producer_thread(void *arg) {
gpr_log(GPR_INFO, "producer %d phase 2", opt->id);
for (i = 0; i < TEST_THREAD_EVENTS; i++) {
grpc_cq_end_write_accepted(opt->cc, (void *)(gpr_intptr) 1, NULL, NULL,
NULL, GRPC_OP_OK);
grpc_cq_end_op(opt->cc, (void *)(gpr_intptr)1, NULL, NULL, NULL,
GRPC_OP_OK);
opt->events_triggered++;
}
@ -298,8 +219,8 @@ static void consumer_thread(void *arg) {
ev = grpc_completion_queue_next(opt->cc, ten_seconds_time());
GPR_ASSERT(ev);
switch (ev->type) {
case GRPC_WRITE_ACCEPTED:
GPR_ASSERT(ev->data.write_accepted == GRPC_OP_OK);
case GRPC_OP_COMPLETE:
GPR_ASSERT(ev->data.op_complete == GRPC_OP_OK);
opt->events_triggered++;
grpc_event_finish(ev);
break;
@ -394,10 +315,7 @@ int main(int argc, char **argv) {
grpc_iomgr_init();
test_no_op();
test_wait_empty();
test_cq_end_read();
test_cq_end_write_accepted();
test_cq_end_finish_accepted();
test_cq_end_client_metadata_read();
test_cq_end_op();
test_pluck();
test_threading(1, 1);
test_threading(1, 10);

@ -35,6 +35,7 @@
#include "test/core/end2end/cq_verifier.h"
#include "test/core/util/test_config.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
static void *tag(gpr_intptr x) { return (void *)x; }
@ -42,30 +43,43 @@ static void *tag(gpr_intptr x) { return (void *)x; }
int main(int argc, char **argv) {
grpc_channel *chan;
grpc_call *call;
grpc_metadata md = {"a", "b", 1, {{NULL, NULL, NULL}}};
grpc_completion_queue *cq;
cq_verifier *cqv;
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array trailing_metadata_recv;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
grpc_test_init(argc, argv);
grpc_init();
grpc_metadata_array_init(&trailing_metadata_recv);
chan = grpc_lame_client_channel_create();
GPR_ASSERT(chan);
call = grpc_channel_create_call_old(chan, "/Foo", "anywhere",
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100));
GPR_ASSERT(call);
cq = grpc_completion_queue_create();
call = grpc_channel_create_call(chan, cq, "/Foo", "anywhere",
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100));
GPR_ASSERT(call);
cqv = cq_verifier_create(cq);
/* we should be able to add metadata */
GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(call, &md, 0));
/* and invoke the call */
GPR_ASSERT(GRPC_CALL_OK == grpc_call_invoke_old(call, cq, tag(2), tag(3), 0));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_start_batch(call, ops, op - ops, tag(1)));
/* the call should immediately fail */
cq_expect_client_metadata_read(cqv, tag(2), NULL);
cq_expect_finished(cqv, tag(3), NULL);
cq_expect_completion(cqv, tag(1), GRPC_OP_OK);
cq_verify(cqv);
grpc_call_destroy(call);
@ -73,6 +87,9 @@ int main(int argc, char **argv) {
cq_verifier_destroy(cqv);
grpc_completion_queue_destroy(cq);
grpc_metadata_array_destroy(&trailing_metadata_recv);
gpr_free(details);
grpc_shutdown();
return 0;

@ -205,7 +205,6 @@ class End2endTest : public ::testing::Test {
ThreadPool thread_pool_;
};
/*
static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
int num_rpcs) {
EchoRequest request;
@ -578,7 +577,18 @@ TEST_F(End2endTest, ClientCancelsBidi) {
Status s = stream->Finish();
EXPECT_EQ(grpc::StatusCode::CANCELLED, s.code());
}
*/
TEST_F(End2endTest, ThreadStress) {
ResetStub();
std::vector<std::thread*> threads;
for (int i = 0; i < 100; ++i) {
threads.push_back(new std::thread(SendRpc, stub_.get(), 1000));
}
for (int i = 0; i < 100; ++i) {
threads[i]->join();
delete threads[i];
}
}
TEST_F(End2endTest, RpcMaxMessageSize) {
ResetStub();

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -399,7 +399,9 @@
</ClCompile>
<ClCompile Include="..\..\src\core\json\json_writer.c">
</ClCompile>
<ClCompile Include="..\..\src\core\profiling\timers.c">
<ClCompile Include="..\..\src\core\profiling\basic_timers.c">
</ClCompile>
<ClCompile Include="..\..\src\core\profiling\stap_timers.c">
</ClCompile>
<ClCompile Include="..\..\src\core\statistics\census_init.c">
</ClCompile>

@ -211,7 +211,10 @@
<ClCompile Include="..\..\src\core\json\json_writer.c">
<Filter>src\core\json</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\profiling\timers.c">
<ClCompile Include="..\..\src\core\profiling\basic_timers.c">
<Filter>src\core\profiling</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\profiling\stap_timers.c">
<Filter>src\core\profiling</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\statistics\census_init.c">

@ -344,7 +344,9 @@
</ClCompile>
<ClCompile Include="..\..\src\core\json\json_writer.c">
</ClCompile>
<ClCompile Include="..\..\src\core\profiling\timers.c">
<ClCompile Include="..\..\src\core\profiling\basic_timers.c">
</ClCompile>
<ClCompile Include="..\..\src\core\profiling\stap_timers.c">
</ClCompile>
<ClCompile Include="..\..\src\core\statistics\census_init.c">
</ClCompile>

@ -154,7 +154,10 @@
<ClCompile Include="..\..\src\core\json\json_writer.c">
<Filter>src\core\json</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\profiling\timers.c">
<ClCompile Include="..\..\src\core\profiling\basic_timers.c">
<Filter>src\core\profiling</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\profiling\stap_timers.c">
<Filter>src\core\profiling</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\statistics\census_init.c">

Loading…
Cancel
Save