aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/channel/client_uchannel.c572
-rw-r--r--src/core/channel/client_uchannel.h70
-rw-r--r--src/core/client_config/subchannel.c47
-rw-r--r--src/core/client_config/subchannel.h11
-rw-r--r--src/core/iomgr/closure.c10
-rw-r--r--src/core/iomgr/closure.h9
-rw-r--r--src/core/iomgr/executor.c148
-rw-r--r--src/core/iomgr/executor.h53
-rw-r--r--src/core/iomgr/resolve_address_posix.c22
-rw-r--r--src/core/iomgr/resolve_address_windows.c26
-rw-r--r--src/core/surface/channel_connectivity.c62
-rw-r--r--src/core/surface/init.c3
-rw-r--r--src/csharp/.gitignore1
-rw-r--r--src/csharp/.nuget/packages.config2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClient.cs6
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs4
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropServer.cs2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/TestCredentials.cs17
-rw-r--r--src/csharp/README.md9
-rw-r--r--src/node/interop/interop_client.js6
-rw-r--r--src/node/src/metadata.js1
-rw-r--r--src/node/src/server.js4
-rw-r--r--src/node/test/async_test.js1
-rw-r--r--src/node/test/credentials_test.js2
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+OAuth2.h16
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+Tests.h28
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+Tests.m3
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.h236
-rw-r--r--src/objective-c/GRPCClient/private/GRPCChannel.h12
-rw-r--r--src/objective-c/GRPCClient/private/GRPCCompletionQueue.h20
-rw-r--r--src/objective-c/GRPCClient/private/GRPCHost.h6
-rw-r--r--src/objective-c/GRPCClient/private/GRPCSecureChannel.h8
-rw-r--r--src/objective-c/GRPCClient/private/GRPCWrappedCall.h2
-rw-r--r--src/objective-c/GRPCClient/private/NSError+GRPC.h6
-rw-r--r--src/objective-c/ProtoRPC/ProtoMethod.h6
-rw-r--r--src/objective-c/RxLibrary/GRXBufferedPipe.h36
-rw-r--r--src/objective-c/RxLibrary/GRXConcurrentWriteable.h54
-rw-r--r--src/objective-c/RxLibrary/GRXForwardingWriter.h24
-rw-r--r--src/objective-c/RxLibrary/GRXImmediateWriter.h70
-rw-r--r--src/objective-c/RxLibrary/GRXWriteable.h22
-rw-r--r--src/objective-c/RxLibrary/GRXWriter+Immediate.h44
-rw-r--r--src/objective-c/RxLibrary/GRXWriter+Transformations.h6
-rw-r--r--src/objective-c/RxLibrary/GRXWriter.h116
-rw-r--r--src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h22
-rw-r--r--src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h12
-rw-r--r--src/objective-c/RxLibrary/private/GRXNSFastEnumerator.h14
-rw-r--r--src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.h8
-rw-r--r--src/objective-c/RxLibrary/transformations/GRXMappingWriter.h2
-rwxr-xr-xsrc/objective-c/change-comments.py128
-rw-r--r--src/objective-c/format-all-comments.sh (renamed from src/python/grpcio_test/grpc_test/early_adopter/__init__.py)3
-rw-r--r--src/objective-c/tests/GRPCClientTests.m36
-rw-r--r--src/objective-c/tests/InteropTests.h16
-rw-r--r--src/objective-c/tests/InteropTests.m14
-rw-r--r--src/objective-c/tests/InteropTestsLocalCleartext.m4
-rw-r--r--src/objective-c/tests/InteropTestsLocalSSL.m4
-rw-r--r--src/objective-c/tests/InteropTestsRemote.m50
-rw-r--r--src/objective-c/tests/LocalClearTextTests.m164
-rw-r--r--src/objective-c/tests/Podfile18
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/project.pbxproj622
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme14
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme101
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme95
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme95
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/RxLibraryUnitTests.xcscheme90
-rw-r--r--src/php/README.md11
-rwxr-xr-xsrc/php/bin/run_gen_code_test.sh4
-rwxr-xr-x[-rw-r--r--]src/php/bin/run_php_cs_fixer.sh (renamed from src/python/grpcio_test/grpc_test/framework/base/__init__.py)12
-rwxr-xr-xsrc/php/bin/run_tests.sh2
-rw-r--r--src/php/ext/grpc/credentials.c10
-rw-r--r--src/php/lib/Grpc/AbstractCall.php116
-rwxr-xr-xsrc/php/lib/Grpc/BaseStub.php467
-rw-r--r--src/php/lib/Grpc/BidiStreamingCall.php123
-rw-r--r--src/php/lib/Grpc/ClientStreamingCall.php84
-rw-r--r--src/php/lib/Grpc/ServerStreamingCall.php93
-rw-r--r--src/php/lib/Grpc/UnaryCall.php67
-rw-r--r--src/php/phpunit.xml22
-rw-r--r--src/php/tests/bootstrap.php21
-rw-r--r--src/php/tests/generated_code/AbstractGeneratedCodeTest.php304
-rwxr-xr-xsrc/php/tests/generated_code/GeneratedCodeTest.php17
-rw-r--r--src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php32
-rw-r--r--src/php/tests/generated_code/math_client.php55
-rwxr-xr-xsrc/php/tests/interop/interop_client.php599
-rwxr-xr-xsrc/php/tests/interop/message_set.php26
-rwxr-xr-xsrc/php/tests/unit_tests/CallTest.php98
-rwxr-xr-xsrc/php/tests/unit_tests/EndToEndTest.php415
-rwxr-xr-xsrc/php/tests/unit_tests/SecureEndToEndTest.php365
-rwxr-xr-xsrc/php/tests/unit_tests/TimevalTest.php100
-rw-r--r--src/python/grpcio/grpc/early_adopter/__init__.py5
-rw-r--r--src/python/grpcio/grpc/framework/alpha/__init__.py7
-rw-r--r--src/python/grpcio/grpc/framework/base/__init__.py5
-rw-r--r--src/python/grpcio/grpc/framework/face/__init__.py5
-rw-r--r--src/python/grpcio_health_checking/commands.py8
-rw-r--r--src/python/grpcio_test/.gitignore1
-rw-r--r--src/python/grpcio_test/commands.py49
-rw-r--r--src/python/grpcio_test/grpc_interop/_insecure_interop_test.py15
-rw-r--r--src/python/grpcio_test/grpc_interop/_secure_interop_test.py25
-rw-r--r--src/python/grpcio_test/grpc_interop/client.py31
-rw-r--r--src/python/grpcio_test/grpc_interop/empty.proto43
-rw-r--r--src/python/grpcio_test/grpc_interop/empty_pb2.py63
-rw-r--r--src/python/grpcio_test/grpc_interop/messages.proto167
-rw-r--r--src/python/grpcio_test/grpc_interop/messages_pb2.py447
-rw-r--r--src/python/grpcio_test/grpc_interop/methods.py150
-rw-r--r--src/python/grpcio_test/grpc_interop/server.py13
-rw-r--r--src/python/grpcio_test/grpc_interop/test.proto86
-rw-r--r--src/python/grpcio_test/grpc_interop/test_pb2.py178
-rw-r--r--src/python/grpcio_test/grpc_protoc_plugin/alpha_python_plugin_test.py541
-rw-r--r--src/python/grpcio_test/grpc_protoc_plugin/python_plugin_test.py541
-rw-r--r--src/python/grpcio_test/grpc_protoc_plugin/test.proto2
-rw-r--r--src/python/grpcio_test/grpc_test/_adapter/_blocking_invocation_inline_service_test.py46
-rw-r--r--src/python/grpcio_test/grpc_test/_adapter/_event_invocation_synchronous_event_service_test.py46
-rw-r--r--src/python/grpcio_test/grpc_test/_adapter/_face_test_case.py106
-rw-r--r--src/python/grpcio_test/grpc_test/_adapter/_future_invocation_asynchronous_event_service_test.py46
-rw-r--r--src/python/grpcio_test/grpc_test/_adapter/_links_test.py277
-rw-r--r--src/python/grpcio_test/grpc_test/_adapter/_lonely_rear_link_test.py100
-rw-r--r--src/python/grpcio_test/grpc_test/_adapter/_test_links.py80
-rw-r--r--src/python/grpcio_test/grpc_test/early_adopter/implementations_test.py180
-rw-r--r--src/python/grpcio_test/grpc_test/framework/base/implementations_test.py80
-rw-r--r--src/python/grpcio_test/grpc_test/framework/base/interfaces_test_case.py307
-rw-r--r--src/python/grpcio_test/grpc_test/framework/face/_test_case.py61
-rw-r--r--src/python/grpcio_test/grpc_test/framework/face/blocking_invocation_inline_service_test.py46
-rw-r--r--src/python/grpcio_test/grpc_test/framework/face/event_invocation_synchronous_event_service_test.py46
-rw-r--r--src/python/grpcio_test/grpc_test/framework/face/future_invocation_asynchronous_event_service_test.py46
-rw-r--r--src/python/grpcio_test/grpc_test/framework/face/testing/serial.py70
-rw-r--r--src/python/grpcio_test/setup.py4
-rwxr-xr-xsrc/ruby/pb/test/client.rb6
125 files changed, 4872 insertions, 5415 deletions
diff --git a/src/core/channel/client_uchannel.c b/src/core/channel/client_uchannel.c
new file mode 100644
index 0000000000..510677a844
--- /dev/null
+++ b/src/core/channel/client_uchannel.c
@@ -0,0 +1,572 @@
+/*
+ *
+ * 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 "src/core/channel/client_uchannel.h"
+
+#include <string.h>
+
+#include "src/core/census/grpc_filter.h"
+#include "src/core/channel/channel_args.h"
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/compress_filter.h"
+#include "src/core/iomgr/iomgr.h"
+#include "src/core/support/string.h"
+#include "src/core/surface/channel.h"
+#include "src/core/transport/connectivity_state.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/useful.h>
+
+/** Microchannel (uchannel) implementation: a lightweight channel without any
+ * load-balancing mechanisms meant for communication from within the core. */
+
+typedef struct call_data call_data;
+
+typedef struct client_uchannel_channel_data {
+ /** metadata context for this channel */
+ grpc_mdctx *mdctx;
+
+ /** master channel - the grpc_channel instance that ultimately owns
+ this channel_data via its channel stack.
+ We occasionally use this to bump the refcount on the master channel
+ to keep ourselves alive through an asynchronous operation. */
+ grpc_channel *master;
+
+ /** connectivity state being tracked */
+ grpc_connectivity_state_tracker state_tracker;
+
+ /** the subchannel wrapped by the microchannel */
+ grpc_subchannel *subchannel;
+
+ /** the callback used to stay subscribed to subchannel connectivity
+ * notifications */
+ grpc_closure connectivity_cb;
+
+ /** the current connectivity state of the wrapped subchannel */
+ grpc_connectivity_state subchannel_connectivity;
+
+ gpr_mu mu_state;
+} channel_data;
+
+typedef enum {
+ CALL_CREATED,
+ CALL_WAITING_FOR_SEND,
+ CALL_WAITING_FOR_CALL,
+ CALL_ACTIVE,
+ CALL_CANCELLED
+} call_state;
+
+struct call_data {
+ /* owning element */
+ grpc_call_element *elem;
+
+ gpr_mu mu_state;
+
+ call_state state;
+ gpr_timespec deadline;
+ grpc_closure async_setup_task;
+ grpc_transport_stream_op waiting_op;
+ /* our child call stack */
+ grpc_subchannel_call *subchannel_call;
+ grpc_linked_mdelem status;
+ grpc_linked_mdelem details;
+};
+
+static grpc_closure *merge_into_waiting_op(grpc_call_element *elem,
+ grpc_transport_stream_op *new_op)
+ GRPC_MUST_USE_RESULT;
+
+static void handle_op_after_cancellation(grpc_exec_ctx *exec_ctx,
+ grpc_call_element *elem,
+ grpc_transport_stream_op *op) {
+ call_data *calld = elem->call_data;
+ channel_data *chand = elem->channel_data;
+ if (op->send_ops) {
+ grpc_stream_ops_unref_owned_objects(op->send_ops->ops, op->send_ops->nops);
+ op->on_done_send->cb(exec_ctx, op->on_done_send->cb_arg, 0);
+ }
+ if (op->recv_ops) {
+ char status[GPR_LTOA_MIN_BUFSIZE];
+ grpc_metadata_batch mdb;
+ gpr_ltoa(GRPC_STATUS_CANCELLED, status);
+ calld->status.md =
+ grpc_mdelem_from_strings(chand->mdctx, "grpc-status", status);
+ calld->details.md =
+ grpc_mdelem_from_strings(chand->mdctx, "grpc-message", "Cancelled");
+ calld->status.prev = calld->details.next = NULL;
+ calld->status.next = &calld->details;
+ calld->details.prev = &calld->status;
+ mdb.list.head = &calld->status;
+ mdb.list.tail = &calld->details;
+ mdb.garbage.head = mdb.garbage.tail = NULL;
+ mdb.deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
+ grpc_sopb_add_metadata(op->recv_ops, mdb);
+ *op->recv_state = GRPC_STREAM_CLOSED;
+ op->on_done_recv->cb(exec_ctx, op->on_done_recv->cb_arg, 1);
+ }
+ if (op->on_consumed) {
+ op->on_consumed->cb(exec_ctx, op->on_consumed->cb_arg, 0);
+ }
+}
+
+typedef struct {
+ grpc_closure closure;
+ grpc_call_element *elem;
+} waiting_call;
+
+static void perform_transport_stream_op(grpc_exec_ctx *exec_ctx,
+ grpc_call_element *elem,
+ grpc_transport_stream_op *op,
+ int continuation);
+
+static int is_empty(void *p, int len) {
+ char *ptr = p;
+ int i;
+ for (i = 0; i < len; i++) {
+ if (ptr[i] != 0) return 0;
+ }
+ return 1;
+}
+
+static void monitor_subchannel(grpc_exec_ctx *exec_ctx, void *arg,
+ int iomgr_success) {
+ channel_data *chand = arg;
+ grpc_connectivity_state_set(exec_ctx, &chand->state_tracker,
+ chand->subchannel_connectivity,
+ "uchannel_monitor_subchannel");
+ grpc_subchannel_notify_on_state_change(exec_ctx, chand->subchannel,
+ &chand->subchannel_connectivity,
+ &chand->connectivity_cb);
+}
+
+static void started_call_locked(grpc_exec_ctx *exec_ctx, void *arg,
+ int iomgr_success) {
+ call_data *calld = arg;
+ grpc_transport_stream_op op;
+ int have_waiting;
+
+ if (calld->state == CALL_CANCELLED && iomgr_success == 0) {
+ have_waiting = !is_empty(&calld->waiting_op, sizeof(calld->waiting_op));
+ gpr_mu_unlock(&calld->mu_state);
+ if (have_waiting) {
+ handle_op_after_cancellation(exec_ctx, calld->elem, &calld->waiting_op);
+ }
+ } else if (calld->state == CALL_CANCELLED && calld->subchannel_call != NULL) {
+ memset(&op, 0, sizeof(op));
+ op.cancel_with_status = GRPC_STATUS_CANCELLED;
+ gpr_mu_unlock(&calld->mu_state);
+ grpc_subchannel_call_process_op(exec_ctx, calld->subchannel_call, &op);
+ } else if (calld->state == CALL_WAITING_FOR_CALL) {
+ have_waiting = !is_empty(&calld->waiting_op, sizeof(calld->waiting_op));
+ if (calld->subchannel_call != NULL) {
+ calld->state = CALL_ACTIVE;
+ gpr_mu_unlock(&calld->mu_state);
+ if (have_waiting) {
+ grpc_subchannel_call_process_op(exec_ctx, calld->subchannel_call,
+ &calld->waiting_op);
+ }
+ } else {
+ calld->state = CALL_CANCELLED;
+ gpr_mu_unlock(&calld->mu_state);
+ if (have_waiting) {
+ handle_op_after_cancellation(exec_ctx, calld->elem, &calld->waiting_op);
+ }
+ }
+ } else {
+ GPR_ASSERT(calld->state == CALL_CANCELLED);
+ gpr_mu_unlock(&calld->mu_state);
+ have_waiting = !is_empty(&calld->waiting_op, sizeof(calld->waiting_op));
+ if (have_waiting) {
+ handle_op_after_cancellation(exec_ctx, calld->elem, &calld->waiting_op);
+ }
+ }
+}
+
+static void started_call(grpc_exec_ctx *exec_ctx, void *arg,
+ int iomgr_success) {
+ call_data *calld = arg;
+ gpr_mu_lock(&calld->mu_state);
+ started_call_locked(exec_ctx, arg, iomgr_success);
+}
+
+static grpc_closure *merge_into_waiting_op(grpc_call_element *elem,
+ grpc_transport_stream_op *new_op) {
+ call_data *calld = elem->call_data;
+ grpc_closure *consumed_op = NULL;
+ grpc_transport_stream_op *waiting_op = &calld->waiting_op;
+ GPR_ASSERT((waiting_op->send_ops != NULL) + (new_op->send_ops != NULL) <= 1);
+ GPR_ASSERT((waiting_op->recv_ops != NULL) + (new_op->recv_ops != NULL) <= 1);
+ if (new_op->send_ops != NULL) {
+ waiting_op->send_ops = new_op->send_ops;
+ waiting_op->is_last_send = new_op->is_last_send;
+ waiting_op->on_done_send = new_op->on_done_send;
+ }
+ if (new_op->recv_ops != NULL) {
+ waiting_op->recv_ops = new_op->recv_ops;
+ waiting_op->recv_state = new_op->recv_state;
+ waiting_op->on_done_recv = new_op->on_done_recv;
+ }
+ if (new_op->on_consumed != NULL) {
+ if (waiting_op->on_consumed != NULL) {
+ consumed_op = waiting_op->on_consumed;
+ }
+ waiting_op->on_consumed = new_op->on_consumed;
+ }
+ if (new_op->cancel_with_status != GRPC_STATUS_OK) {
+ waiting_op->cancel_with_status = new_op->cancel_with_status;
+ }
+ return consumed_op;
+}
+
+static char *cuc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
+ call_data *calld = elem->call_data;
+ channel_data *chand = elem->channel_data;
+ grpc_subchannel_call *subchannel_call;
+ char *result;
+
+ gpr_mu_lock(&calld->mu_state);
+ if (calld->state == CALL_ACTIVE) {
+ subchannel_call = calld->subchannel_call;
+ GRPC_SUBCHANNEL_CALL_REF(subchannel_call, "get_peer");
+ gpr_mu_unlock(&calld->mu_state);
+ result = grpc_subchannel_call_get_peer(exec_ctx, subchannel_call);
+ GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, subchannel_call, "get_peer");
+ return result;
+ } else {
+ gpr_mu_unlock(&calld->mu_state);
+ return grpc_channel_get_target(chand->master);
+ }
+}
+
+static void perform_transport_stream_op(grpc_exec_ctx *exec_ctx,
+ grpc_call_element *elem,
+ grpc_transport_stream_op *op,
+ int continuation) {
+ call_data *calld = elem->call_data;
+ channel_data *chand = elem->channel_data;
+ grpc_subchannel_call *subchannel_call;
+ grpc_transport_stream_op op2;
+ GPR_ASSERT(elem->filter == &grpc_client_uchannel_filter);
+ GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+
+ gpr_mu_lock(&calld->mu_state);
+ /* make sure the wrapped subchannel has been set (see
+ * grpc_client_uchannel_set_subchannel) */
+ GPR_ASSERT(chand->subchannel != NULL);
+
+ switch (calld->state) {
+ case CALL_ACTIVE:
+ GPR_ASSERT(!continuation);
+ subchannel_call = calld->subchannel_call;
+ gpr_mu_unlock(&calld->mu_state);
+ grpc_subchannel_call_process_op(exec_ctx, subchannel_call, op);
+ break;
+ case CALL_CANCELLED:
+ gpr_mu_unlock(&calld->mu_state);
+ handle_op_after_cancellation(exec_ctx, elem, op);
+ break;
+ case CALL_WAITING_FOR_SEND:
+ GPR_ASSERT(!continuation);
+ grpc_exec_ctx_enqueue(exec_ctx, merge_into_waiting_op(elem, op), 1);
+ if (!calld->waiting_op.send_ops &&
+ calld->waiting_op.cancel_with_status == GRPC_STATUS_OK) {
+ gpr_mu_unlock(&calld->mu_state);
+ break;
+ }
+ *op = calld->waiting_op;
+ memset(&calld->waiting_op, 0, sizeof(calld->waiting_op));
+ continuation = 1;
+ /* fall through */
+ case CALL_WAITING_FOR_CALL:
+ if (!continuation) {
+ if (op->cancel_with_status != GRPC_STATUS_OK) {
+ calld->state = CALL_CANCELLED;
+ op2 = calld->waiting_op;
+ memset(&calld->waiting_op, 0, sizeof(calld->waiting_op));
+ if (op->on_consumed) {
+ calld->waiting_op.on_consumed = op->on_consumed;
+ op->on_consumed = NULL;
+ } else if (op2.on_consumed) {
+ calld->waiting_op.on_consumed = op2.on_consumed;
+ op2.on_consumed = NULL;
+ }
+ gpr_mu_unlock(&calld->mu_state);
+ handle_op_after_cancellation(exec_ctx, elem, op);
+ handle_op_after_cancellation(exec_ctx, elem, &op2);
+ grpc_subchannel_cancel_waiting_call(exec_ctx, chand->subchannel, 1);
+ } else {
+ grpc_exec_ctx_enqueue(exec_ctx, merge_into_waiting_op(elem, op), 1);
+ gpr_mu_unlock(&calld->mu_state);
+ }
+ break;
+ }
+ /* fall through */
+ case CALL_CREATED:
+ if (op->cancel_with_status != GRPC_STATUS_OK) {
+ calld->state = CALL_CANCELLED;
+ gpr_mu_unlock(&calld->mu_state);
+ handle_op_after_cancellation(exec_ctx, elem, op);
+ } else {
+ calld->waiting_op = *op;
+ if (op->send_ops == NULL) {
+ calld->state = CALL_WAITING_FOR_SEND;
+ gpr_mu_unlock(&calld->mu_state);
+ } else {
+ grpc_subchannel_call_create_status call_creation_status;
+ grpc_pollset *pollset = calld->waiting_op.bind_pollset;
+ calld->state = CALL_WAITING_FOR_CALL;
+ grpc_closure_init(&calld->async_setup_task, started_call, calld);
+ call_creation_status = grpc_subchannel_create_call(
+ exec_ctx, chand->subchannel, pollset, &calld->subchannel_call,
+ &calld->async_setup_task);
+ if (call_creation_status == GRPC_SUBCHANNEL_CALL_CREATE_READY) {
+ started_call_locked(exec_ctx, calld, 1);
+ } else {
+ gpr_mu_unlock(&calld->mu_state);
+ }
+ }
+ }
+ break;
+ }
+}
+
+static void cuc_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
+ grpc_call_element *elem,
+ grpc_transport_stream_op *op) {
+ perform_transport_stream_op(exec_ctx, elem, op, 0);
+}
+
+static void cuc_start_transport_op(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_transport_op *op) {
+ channel_data *chand = elem->channel_data;
+
+ grpc_exec_ctx_enqueue(exec_ctx, op->on_consumed, 1);
+
+ GPR_ASSERT(op->set_accept_stream == NULL);
+ GPR_ASSERT(op->bind_pollset == NULL);
+
+ if (op->on_connectivity_state_change != NULL) {
+ grpc_connectivity_state_notify_on_state_change(
+ exec_ctx, &chand->state_tracker, op->connectivity_state,
+ op->on_connectivity_state_change);
+ op->on_connectivity_state_change = NULL;
+ op->connectivity_state = NULL;
+ }
+
+ if (op->disconnect) {
+ grpc_connectivity_state_set(exec_ctx, &chand->state_tracker,
+ GRPC_CHANNEL_FATAL_FAILURE, "disconnect");
+ }
+}
+
+/* Constructor for call_data */
+static void cuc_init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+ const void *server_transport_data,
+ grpc_transport_stream_op *initial_op) {
+ call_data *calld = elem->call_data;
+ memset(calld, 0, sizeof(call_data));
+
+ /* TODO(ctiller): is there something useful we can do here? */
+ GPR_ASSERT(initial_op == NULL);
+
+ GPR_ASSERT(elem->filter == &grpc_client_uchannel_filter);
+ GPR_ASSERT(server_transport_data == NULL);
+ gpr_mu_init(&calld->mu_state);
+ calld->elem = elem;
+ calld->state = CALL_CREATED;
+ calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
+}
+
+/* Destructor for call_data */
+static void cuc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
+ grpc_call_element *elem) {
+ call_data *calld = elem->call_data;
+ grpc_subchannel_call *subchannel_call;
+
+ /* if the call got activated, we need to destroy the child stack also, and
+ remove it from the in-flight requests tracked by the child_entry we
+ picked */
+ gpr_mu_lock(&calld->mu_state);
+ switch (calld->state) {
+ case CALL_ACTIVE:
+ subchannel_call = calld->subchannel_call;
+ gpr_mu_unlock(&calld->mu_state);
+ GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, subchannel_call, "client_uchannel");
+ break;
+ case CALL_CREATED:
+ case CALL_CANCELLED:
+ gpr_mu_unlock(&calld->mu_state);
+ break;
+ case CALL_WAITING_FOR_CALL:
+ case CALL_WAITING_FOR_SEND:
+ GPR_UNREACHABLE_CODE(return );
+ }
+}
+
+/* Constructor for channel_data */
+static void cuc_init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel *master,
+ const grpc_channel_args *args,
+ grpc_mdctx *metadata_context, int is_first,
+ int is_last) {
+ channel_data *chand = elem->channel_data;
+ memset(chand, 0, sizeof(*chand));
+ grpc_closure_init(&chand->connectivity_cb, monitor_subchannel, chand);
+ GPR_ASSERT(is_last);
+ GPR_ASSERT(elem->filter == &grpc_client_uchannel_filter);
+ chand->mdctx = metadata_context;
+ chand->master = master;
+ grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
+ "client_uchannel");
+ gpr_mu_init(&chand->mu_state);
+}
+
+/* Destructor for channel_data */
+static void cuc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem) {
+ channel_data *chand = elem->channel_data;
+ grpc_subchannel_state_change_unsubscribe(exec_ctx, chand->subchannel,
+ &chand->connectivity_cb);
+ grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
+ gpr_mu_destroy(&chand->mu_state);
+}
+
+const grpc_channel_filter grpc_client_uchannel_filter = {
+ cuc_start_transport_stream_op,
+ cuc_start_transport_op,
+ sizeof(call_data),
+ cuc_init_call_elem,
+ cuc_destroy_call_elem,
+ sizeof(channel_data),
+ cuc_init_channel_elem,
+ cuc_destroy_channel_elem,
+ cuc_get_peer,
+ "client-uchannel",
+};
+
+grpc_connectivity_state grpc_client_uchannel_check_connectivity_state(
+ grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect) {
+ channel_data *chand = elem->channel_data;
+ grpc_connectivity_state out;
+ out = grpc_connectivity_state_check(&chand->state_tracker);
+ gpr_mu_lock(&chand->mu_state);
+ if (out == GRPC_CHANNEL_IDLE && try_to_connect) {
+ grpc_connectivity_state_set(exec_ctx, &chand->state_tracker,
+ GRPC_CHANNEL_CONNECTING,
+ "uchannel_connecting_changed");
+ chand->subchannel_connectivity = out;
+ grpc_subchannel_notify_on_state_change(exec_ctx, chand->subchannel,
+ &chand->subchannel_connectivity,
+ &chand->connectivity_cb);
+ }
+ gpr_mu_unlock(&chand->mu_state);
+ return out;
+}
+
+void grpc_client_uchannel_watch_connectivity_state(
+ grpc_exec_ctx *exec_ctx, grpc_channel_element *elem,
+ grpc_connectivity_state *state, grpc_closure *on_complete) {
+ channel_data *chand = elem->channel_data;
+ gpr_mu_lock(&chand->mu_state);
+ grpc_connectivity_state_notify_on_state_change(
+ exec_ctx, &chand->state_tracker, state, on_complete);
+ gpr_mu_unlock(&chand->mu_state);
+}
+
+grpc_pollset_set *grpc_client_uchannel_get_connecting_pollset_set(
+ grpc_channel_element *elem) {
+ channel_data *chand = elem->channel_data;
+ grpc_channel_element *parent_elem;
+ gpr_mu_lock(&chand->mu_state);
+ parent_elem = grpc_channel_stack_last_element(grpc_channel_get_channel_stack(
+ grpc_subchannel_get_master(chand->subchannel)));
+ gpr_mu_unlock(&chand->mu_state);
+ return grpc_client_channel_get_connecting_pollset_set(parent_elem);
+}
+
+void grpc_client_uchannel_add_interested_party(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_pollset *pollset) {
+ grpc_pollset_set *master_pollset_set =
+ grpc_client_uchannel_get_connecting_pollset_set(elem);
+ grpc_pollset_set_add_pollset(exec_ctx, master_pollset_set, pollset);
+}
+
+void grpc_client_uchannel_del_interested_party(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_pollset *pollset) {
+ grpc_pollset_set *master_pollset_set =
+ grpc_client_uchannel_get_connecting_pollset_set(elem);
+ grpc_pollset_set_del_pollset(exec_ctx, master_pollset_set, pollset);
+}
+
+grpc_channel *grpc_client_uchannel_create(grpc_subchannel *subchannel,
+ grpc_channel_args *args) {
+ grpc_channel *channel = NULL;
+#define MAX_FILTERS 3
+ const grpc_channel_filter *filters[MAX_FILTERS];
+ grpc_mdctx *mdctx = grpc_subchannel_get_mdctx(subchannel);
+ grpc_channel *master = grpc_subchannel_get_master(subchannel);
+ char *target = grpc_channel_get_target(master);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ size_t n = 0;
+
+ grpc_mdctx_ref(mdctx);
+ if (grpc_channel_args_is_census_enabled(args)) {
+ filters[n++] = &grpc_client_census_filter;
+ }
+ filters[n++] = &grpc_compress_filter;
+ filters[n++] = &grpc_client_uchannel_filter;
+ GPR_ASSERT(n <= MAX_FILTERS);
+
+ channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, n,
+ args, mdctx, 1);
+
+ gpr_free(target);
+ return channel;
+}
+
+void grpc_client_uchannel_set_subchannel(grpc_channel *uchannel,
+ grpc_subchannel *subchannel) {
+ grpc_channel_element *elem =
+ grpc_channel_stack_last_element(grpc_channel_get_channel_stack(uchannel));
+ channel_data *chand = elem->channel_data;
+ GPR_ASSERT(elem->filter == &grpc_client_uchannel_filter);
+ gpr_mu_lock(&chand->mu_state);
+ chand->subchannel = subchannel;
+ gpr_mu_unlock(&chand->mu_state);
+}
diff --git a/src/core/channel/client_uchannel.h b/src/core/channel/client_uchannel.h
new file mode 100644
index 0000000000..dfe6695ae3
--- /dev/null
+++ b/src/core/channel/client_uchannel.h
@@ -0,0 +1,70 @@
+/*
+ *
+ * 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 GRPC_INTERNAL_CORE_CHANNEL_CLIENT_MICROCHANNEL_H
+#define GRPC_INTERNAL_CORE_CHANNEL_CLIENT_MICROCHANNEL_H
+
+#include "src/core/channel/channel_stack.h"
+#include "src/core/client_config/resolver.h"
+
+#define GRPC_MICROCHANNEL_SUBCHANNEL_ARG "grpc.microchannel_subchannel_key"
+
+/* A client microchannel (aka uchannel) is a channel wrapping a subchannel, for
+ * the purposes of lightweight RPC communications from within the core.*/
+
+extern const grpc_channel_filter grpc_client_uchannel_filter;
+
+grpc_connectivity_state grpc_client_uchannel_check_connectivity_state(
+ grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect);
+
+void grpc_client_uchannel_watch_connectivity_state(
+ grpc_exec_ctx *exec_ctx, grpc_channel_element *elem,
+ grpc_connectivity_state *state, grpc_closure *on_complete);
+
+grpc_pollset_set *grpc_client_uchannel_get_connecting_pollset_set(
+ grpc_channel_element *elem);
+
+void grpc_client_uchannel_add_interested_party(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *channel,
+ grpc_pollset *pollset);
+void grpc_client_uchannel_del_interested_party(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *channel,
+ grpc_pollset *pollset);
+
+grpc_channel *grpc_client_uchannel_create(grpc_subchannel *subchannel,
+ grpc_channel_args *args);
+
+void grpc_client_uchannel_set_subchannel(grpc_channel *uchannel,
+ grpc_subchannel *subchannel);
+
+#endif /* GRPC_INTERNAL_CORE_CHANNEL_CLIENT_MICROCHANNEL_H */
diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c
index 095000ba4f..0401dd3868 100644
--- a/src/core/client_config/subchannel.c
+++ b/src/core/client_config/subchannel.c
@@ -312,6 +312,29 @@ grpc_subchannel *grpc_subchannel_create(grpc_connector *connector,
return c;
}
+void grpc_subchannel_cancel_waiting_call(grpc_exec_ctx *exec_ctx,
+ grpc_subchannel *subchannel,
+ int iomgr_success) {
+ waiting_for_connect *w4c;
+ gpr_mu_lock(&subchannel->mu);
+ w4c = subchannel->waiting;
+ subchannel->waiting = NULL;
+ gpr_mu_unlock(&subchannel->mu);
+ while (w4c != NULL) {
+ waiting_for_connect *next = w4c->next;
+ grpc_subchannel_del_interested_party(exec_ctx, w4c->subchannel,
+ w4c->pollset);
+ if (w4c->notify) {
+ w4c->notify->cb(exec_ctx, w4c->notify->cb_arg, iomgr_success);
+ }
+
+ GRPC_SUBCHANNEL_UNREF(exec_ctx, w4c->subchannel, "waiting_for_connect");
+ gpr_free(w4c);
+
+ w4c = next;
+ }
+}
+
static void continue_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
grpc_connect_in_args args;
@@ -659,24 +682,12 @@ static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, int iomgr_success) {
iomgr_success = 0;
}
connectivity_state_changed_locked(exec_ctx, c, "alarm");
+ gpr_mu_unlock(&c->mu);
if (iomgr_success) {
- gpr_mu_unlock(&c->mu);
update_reconnect_parameters(c);
continue_connect(exec_ctx, c);
} else {
- waiting_for_connect *w4c;
- w4c = c->waiting;
- c->waiting = NULL;
- gpr_mu_unlock(&c->mu);
- while (w4c != NULL) {
- waiting_for_connect *next = w4c->next;
- grpc_subchannel_del_interested_party(exec_ctx, w4c->subchannel,
- w4c->pollset);
- w4c->notify->cb(exec_ctx, w4c->notify->cb_arg, 0);
- GRPC_SUBCHANNEL_UNREF(exec_ctx, w4c->subchannel, "waiting_for_connect");
- gpr_free(w4c);
- w4c = next;
- }
+ grpc_subchannel_cancel_waiting_call(exec_ctx, c, iomgr_success);
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, c->master, "connecting");
GRPC_SUBCHANNEL_UNREF(exec_ctx, c, "connecting");
}
@@ -784,3 +795,11 @@ static grpc_subchannel_call *create_call(grpc_exec_ctx *exec_ctx,
grpc_call_stack_init(exec_ctx, chanstk, NULL, NULL, callstk);
return call;
}
+
+grpc_mdctx *grpc_subchannel_get_mdctx(grpc_subchannel *subchannel) {
+ return subchannel->mdctx;
+}
+
+grpc_channel *grpc_subchannel_get_master(grpc_subchannel *subchannel) {
+ return subchannel->master;
+}
diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h
index a26d08f02e..ec1cc7cc69 100644
--- a/src/core/client_config/subchannel.h
+++ b/src/core/client_config/subchannel.h
@@ -92,6 +92,11 @@ grpc_subchannel_call_create_status grpc_subchannel_create_call(
grpc_exec_ctx *exec_ctx, grpc_subchannel *subchannel, grpc_pollset *pollset,
grpc_subchannel_call **target, grpc_closure *notify);
+/** cancel \a call in the waiting state. */
+void grpc_subchannel_cancel_waiting_call(grpc_exec_ctx *exec_ctx,
+ grpc_subchannel *subchannel,
+ int iomgr_success);
+
/** process a transport level op */
void grpc_subchannel_process_transport_op(grpc_exec_ctx *exec_ctx,
grpc_subchannel *subchannel,
@@ -154,4 +159,10 @@ struct grpc_subchannel_args {
grpc_subchannel *grpc_subchannel_create(grpc_connector *connector,
grpc_subchannel_args *args);
+/** Return the metadata context associated with the subchannel */
+grpc_mdctx *grpc_subchannel_get_mdctx(grpc_subchannel *subchannel);
+
+/** Return the master channel associated with the subchannel */
+grpc_channel *grpc_subchannel_get_master(grpc_subchannel *subchannel);
+
#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_H */
diff --git a/src/core/iomgr/closure.c b/src/core/iomgr/closure.c
index d91681990f..b4f1817de4 100644
--- a/src/core/iomgr/closure.c
+++ b/src/core/iomgr/closure.c
@@ -72,6 +72,16 @@ void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst) {
src->head = src->tail = NULL;
}
+grpc_closure *grpc_closure_list_pop(grpc_closure_list *list) {
+ grpc_closure *head;
+ if (list->head == NULL) {
+ return NULL;
+ }
+ head = list->head;
+ list->head = list->head->next;
+ return head;
+}
+
typedef struct {
grpc_iomgr_cb_func cb;
void *cb_arg;
diff --git a/src/core/iomgr/closure.h b/src/core/iomgr/closure.h
index d812659af0..7a9f7ccad0 100644
--- a/src/core/iomgr/closure.h
+++ b/src/core/iomgr/closure.h
@@ -83,9 +83,18 @@ grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg);
#define GRPC_CLOSURE_LIST_INIT \
{ NULL, NULL }
+/** add \a closure to the end of \a list and set \a closure's success to \a
+ * success */
void grpc_closure_list_add(grpc_closure_list *list, grpc_closure *closure,
int success);
+
+/** append all closures from \a src to \a dst and empty \a src. */
void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst);
+
+/** pop (return and remove) the head closure from \a list. */
+grpc_closure *grpc_closure_list_pop(grpc_closure_list *list);
+
+/** return whether \a list is empty. */
int grpc_closure_list_empty(grpc_closure_list list);
#endif /* GRPC_INTERNAL_CORE_IOMGR_CLOSURE_H */
diff --git a/src/core/iomgr/executor.c b/src/core/iomgr/executor.c
new file mode 100644
index 0000000000..457e5cdbac
--- /dev/null
+++ b/src/core/iomgr/executor.c
@@ -0,0 +1,148 @@
+/*
+ *
+ * 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 "src/core/iomgr/executor.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include "src/core/iomgr/exec_ctx.h"
+
+typedef struct grpc_executor_data {
+ int busy; /**< is the thread currently running? */
+ int shutting_down; /**< has \a grpc_shutdown() been invoked? */
+ int pending_join; /**< has the thread finished but not been joined? */
+ grpc_closure_list closures; /**< collection of pending work */
+ gpr_thd_id tid; /**< thread id of the thread, only valid if \a busy or \a
+ pending_join are true */
+ gpr_thd_options options;
+ gpr_mu mu;
+} grpc_executor;
+
+static grpc_executor g_executor;
+
+void grpc_executor_init() {
+ memset(&g_executor, 0, sizeof(grpc_executor));
+ gpr_mu_init(&g_executor.mu);
+ g_executor.options = gpr_thd_options_default();
+ gpr_thd_options_set_joinable(&g_executor.options);
+}
+
+/* thread body */
+static void closure_exec_thread_func(void *ignored) {
+ grpc_closure *closure;
+
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ while (1) {
+ gpr_mu_lock(&g_executor.mu);
+ if (g_executor.shutting_down != 0) {
+ gpr_mu_unlock(&g_executor.mu);
+ break;
+ }
+ closure = grpc_closure_list_pop(&g_executor.closures);
+ if (closure == NULL) {
+ /* no more work, time to die */
+ GPR_ASSERT(g_executor.busy == 1);
+ g_executor.busy = 0;
+ gpr_mu_unlock(&g_executor.mu);
+ break;
+ }
+ gpr_mu_unlock(&g_executor.mu);
+ closure->cb(&exec_ctx, closure->cb_arg, closure->success);
+ grpc_exec_ctx_flush(&exec_ctx);
+ }
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+/* Spawn the thread if new work has arrived a no thread is up */
+static void maybe_spawn_locked() {
+ if (grpc_closure_list_empty(g_executor.closures) == 1) {
+ return;
+ }
+ if (g_executor.shutting_down == 1) {
+ return;
+ }
+
+ if (g_executor.busy != 0) {
+ /* Thread still working. New work will be picked up by already running
+ * thread. Not spawning anything. */
+ return;
+ } else if (g_executor.pending_join != 0) {
+ /* Pickup the remains of the previous incarnations of the thread. */
+ gpr_thd_join(g_executor.tid);
+ g_executor.pending_join = 0;
+ }
+
+ /* All previous instances of the thread should have been joined at this point.
+ * Spawn time! */
+ g_executor.busy = 1;
+ gpr_thd_new(&g_executor.tid, closure_exec_thread_func, NULL,
+ &g_executor.options);
+ g_executor.pending_join = 1;
+}
+
+void grpc_executor_enqueue(grpc_closure *closure, int success) {
+ gpr_mu_lock(&g_executor.mu);
+ if (g_executor.shutting_down == 0) {
+ grpc_closure_list_add(&g_executor.closures, closure, success);
+ maybe_spawn_locked();
+ }
+ gpr_mu_unlock(&g_executor.mu);
+}
+
+void grpc_executor_shutdown() {
+ int pending_join;
+ grpc_closure *closure;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+ gpr_mu_lock(&g_executor.mu);
+ pending_join = g_executor.pending_join;
+ g_executor.shutting_down = 1;
+ gpr_mu_unlock(&g_executor.mu);
+ /* we can release the lock at this point despite the access to the closure
+ * list below because we aren't accepting new work */
+
+ /* Execute pending callbacks, some may be performing cleanups */
+ while ((closure = grpc_closure_list_pop(&g_executor.closures)) != NULL) {
+ closure->cb(&exec_ctx, closure->cb_arg, closure->success);
+ }
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(grpc_closure_list_empty(g_executor.closures));
+ if (pending_join) {
+ gpr_thd_join(g_executor.tid);
+ }
+ gpr_mu_destroy(&g_executor.mu);
+}
diff --git a/src/core/iomgr/executor.h b/src/core/iomgr/executor.h
new file mode 100644
index 0000000000..6da446ae9c
--- /dev/null
+++ b/src/core/iomgr/executor.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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 GRPC_INTERNAL_CORE_IOMGR_EXECUTOR_H
+#define GRPC_INTERNAL_CORE_IOMGR_EXECUTOR_H
+
+#include "src/core/iomgr/closure.h"
+
+/** Initialize the global executor.
+ *
+ * This mechanism is meant to outsource work (grpc_closure instances) to a
+ * thread, for those cases where blocking isn't an option but there isn't a
+ * non-blocking solution available. */
+void grpc_executor_init();
+
+/** Enqueue \a closure for its eventual execution of \a f(arg) on a separate
+ * thread */
+void grpc_executor_enqueue(grpc_closure *closure, int success);
+
+/** Shutdown the executor, running all pending work as part of the call */
+void grpc_executor_shutdown();
+
+#endif /* GRPC_INTERNAL_CORE_IOMGR_EXECUTOR_H */
diff --git a/src/core/iomgr/resolve_address_posix.c b/src/core/iomgr/resolve_address_posix.c
index ed0a93fcc9..555c74ce7e 100644
--- a/src/core/iomgr/resolve_address_posix.c
+++ b/src/core/iomgr/resolve_address_posix.c
@@ -41,6 +41,7 @@
#include <sys/un.h>
#include <string.h>
+#include "src/core/iomgr/executor.h"
#include "src/core/iomgr/iomgr_internal.h"
#include "src/core/iomgr/sockaddr_utils.h"
#include "src/core/support/block_annotate.h"
@@ -57,8 +58,8 @@ typedef struct {
char *name;
char *default_port;
grpc_resolve_cb cb;
+ grpc_closure request_closure;
void *arg;
- grpc_iomgr_object iomgr_object;
} request;
grpc_resolved_addresses *grpc_blocking_resolve_address(
@@ -149,20 +150,18 @@ done:
return addrs;
}
-/* Thread function to asynch-ify grpc_blocking_resolve_address */
-static void do_request_thread(void *rp) {
+/* Callback to be passed to grpc_executor to asynch-ify
+ * grpc_blocking_resolve_address */
+static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp, int success) {
request *r = rp;
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_resolved_addresses *resolved =
grpc_blocking_resolve_address(r->name, r->default_port);
void *arg = r->arg;
grpc_resolve_cb cb = r->cb;
gpr_free(r->name);
gpr_free(r->default_port);
- cb(&exec_ctx, arg, resolved);
- grpc_iomgr_unregister_object(&r->iomgr_object);
+ cb(exec_ctx, arg, resolved);
gpr_free(r);
- grpc_exec_ctx_finish(&exec_ctx);
}
void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
@@ -173,17 +172,12 @@ void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
void grpc_resolve_address(const char *name, const char *default_port,
grpc_resolve_cb cb, void *arg) {
request *r = gpr_malloc(sizeof(request));
- gpr_thd_id id;
- char *tmp;
- gpr_asprintf(&tmp, "resolve_address:name='%s':default_port='%s'", name,
- default_port);
- grpc_iomgr_register_object(&r->iomgr_object, tmp);
- gpr_free(tmp);
+ grpc_closure_init(&r->request_closure, do_request_thread, r);
r->name = gpr_strdup(name);
r->default_port = gpr_strdup(default_port);
r->cb = cb;
r->arg = arg;
- gpr_thd_new(&id, do_request_thread, r, NULL);
+ grpc_executor_enqueue(&r->request_closure, 1);
}
#endif
diff --git a/src/core/iomgr/resolve_address_windows.c b/src/core/iomgr/resolve_address_windows.c
index 82a5602996..007c855d10 100644
--- a/src/core/iomgr/resolve_address_windows.c
+++ b/src/core/iomgr/resolve_address_windows.c
@@ -40,6 +40,7 @@
#include <sys/types.h>
#include <string.h>
+#include "src/core/iomgr/executor.h"
#include "src/core/iomgr/iomgr_internal.h"
#include "src/core/iomgr/sockaddr_utils.h"
#include "src/core/support/block_annotate.h"
@@ -47,6 +48,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
+#include <grpc/support/log_win32.h>
#include <grpc/support/string_util.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
@@ -55,8 +57,8 @@ typedef struct {
char *name;
char *default_port;
grpc_resolve_cb cb;
+ grpc_closure request_closure;
void *arg;
- grpc_iomgr_object iomgr_object;
} request;
grpc_resolved_addresses *grpc_blocking_resolve_address(
@@ -93,7 +95,9 @@ grpc_resolved_addresses *grpc_blocking_resolve_address(
s = getaddrinfo(host, port, &hints, &result);
GRPC_SCHEDULING_END_BLOCKING_REGION;
if (s != 0) {
- gpr_log(GPR_ERROR, "getaddrinfo: %s", gai_strerror(s));
+ char *error_message = gpr_format_message(s);
+ gpr_log(GPR_ERROR, "getaddrinfo: %s", error_message);
+ gpr_free(error_message);
goto done;
}
@@ -129,9 +133,9 @@ done:
return addrs;
}
-/* Thread function to asynch-ify grpc_blocking_resolve_address */
-static void do_request(void *rp) {
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+/* Callback to be passed to grpc_executor to asynch-ify
+ * grpc_blocking_resolve_address */
+static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp, int success) {
request *r = rp;
grpc_resolved_addresses *resolved =
grpc_blocking_resolve_address(r->name, r->default_port);
@@ -139,10 +143,8 @@ static void do_request(void *rp) {
grpc_resolve_cb cb = r->cb;
gpr_free(r->name);
gpr_free(r->default_port);
- grpc_iomgr_unregister_object(&r->iomgr_object);
+ cb(exec_ctx, arg, resolved);
gpr_free(r);
- cb(&exec_ctx, arg, resolved);
- grpc_exec_ctx_finish(&exec_ctx);
}
void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
@@ -153,16 +155,12 @@ void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
void grpc_resolve_address(const char *name, const char *default_port,
grpc_resolve_cb cb, void *arg) {
request *r = gpr_malloc(sizeof(request));
- gpr_thd_id id;
- char *label;
- gpr_asprintf(&label, "resolve:%s", name);
- grpc_iomgr_register_object(&r->iomgr_object, label);
- gpr_free(label);
+ grpc_closure_init(&r->request_closure, do_request_thread, r);
r->name = gpr_strdup(name);
r->default_port = gpr_strdup(default_port);
r->cb = cb;
r->arg = arg;
- gpr_thd_new(&id, do_request, r, NULL);
+ grpc_executor_enqueue(&r->request_closure, 1);
}
#endif
diff --git a/src/core/surface/channel_connectivity.c b/src/core/surface/channel_connectivity.c
index 1a2aef64ef..df2774b527 100644
--- a/src/core/surface/channel_connectivity.c
+++ b/src/core/surface/channel_connectivity.c
@@ -37,6 +37,7 @@
#include <grpc/support/log.h>
#include "src/core/channel/client_channel.h"
+#include "src/core/channel/client_uchannel.h"
#include "src/core/iomgr/timer.h"
#include "src/core/surface/api_trace.h"
#include "src/core/surface/completion_queue.h"
@@ -51,18 +52,24 @@ grpc_connectivity_state grpc_channel_check_connectivity_state(
GRPC_API_TRACE(
"grpc_channel_check_connectivity_state(channel=%p, try_to_connect=%d)", 2,
(channel, try_to_connect));
- if (client_channel_elem->filter != &grpc_client_channel_filter) {
- gpr_log(GPR_ERROR,
- "grpc_channel_check_connectivity_state called on something that is "
- "not a client channel, but '%s'",
- client_channel_elem->filter->name);
+ if (client_channel_elem->filter == &grpc_client_channel_filter) {
+ state = grpc_client_channel_check_connectivity_state(
+ &exec_ctx, client_channel_elem, try_to_connect);
grpc_exec_ctx_finish(&exec_ctx);
- return GRPC_CHANNEL_FATAL_FAILURE;
+ return state;
}
- state = grpc_client_channel_check_connectivity_state(
- &exec_ctx, client_channel_elem, try_to_connect);
+ if (client_channel_elem->filter == &grpc_client_uchannel_filter) {
+ state = grpc_client_uchannel_check_connectivity_state(
+ &exec_ctx, client_channel_elem, try_to_connect);
+ grpc_exec_ctx_finish(&exec_ctx);
+ return state;
+ }
+ gpr_log(GPR_ERROR,
+ "grpc_channel_check_connectivity_state called on something that is "
+ "not a (u)client channel, but '%s'",
+ client_channel_elem->filter->name);
grpc_exec_ctx_finish(&exec_ctx);
- return state;
+ return GRPC_CHANNEL_FATAL_FAILURE;
}
typedef enum {
@@ -87,7 +94,17 @@ typedef struct {
} state_watcher;
static void delete_state_watcher(grpc_exec_ctx *exec_ctx, state_watcher *w) {
- GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel, "watch_connectivity");
+ grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element(
+ grpc_channel_get_channel_stack(w->channel));
+ if (client_channel_elem->filter == &grpc_client_channel_filter) {
+ GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel,
+ "watch_channel_connectivity");
+ } else if (client_channel_elem->filter == &grpc_client_uchannel_filter) {
+ GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel,
+ "watch_uchannel_connectivity");
+ } else {
+ abort();
+ }
gpr_mu_destroy(&w->mu);
gpr_free(w);
}
@@ -125,8 +142,13 @@ static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w,
w->removed = 1;
client_channel_elem = grpc_channel_stack_last_element(
grpc_channel_get_channel_stack(w->channel));
- grpc_client_channel_del_interested_party(exec_ctx, client_channel_elem,
- grpc_cq_pollset(w->cq));
+ if (client_channel_elem->filter == &grpc_client_channel_filter) {
+ grpc_client_channel_del_interested_party(exec_ctx, client_channel_elem,
+ grpc_cq_pollset(w->cq));
+ } else {
+ grpc_client_uchannel_del_interested_party(exec_ctx, client_channel_elem,
+ grpc_cq_pollset(w->cq));
+ }
}
gpr_mu_unlock(&w->mu);
if (due_to_completion) {
@@ -199,18 +221,18 @@ void grpc_channel_watch_connectivity_state(
gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
timeout_complete, w, gpr_now(GPR_CLOCK_MONOTONIC));
- if (client_channel_elem->filter != &grpc_client_channel_filter) {
- gpr_log(GPR_ERROR,
- "grpc_channel_watch_connectivity_state called on something that is "
- "not a client channel, but '%s'",
- client_channel_elem->filter->name);
- grpc_exec_ctx_enqueue(&exec_ctx, &w->on_complete, 1);
- } else {
- GRPC_CHANNEL_INTERNAL_REF(channel, "watch_connectivity");
+ if (client_channel_elem->filter == &grpc_client_channel_filter) {
+ GRPC_CHANNEL_INTERNAL_REF(channel, "watch_channel_connectivity");
grpc_client_channel_add_interested_party(&exec_ctx, client_channel_elem,
grpc_cq_pollset(cq));
grpc_client_channel_watch_connectivity_state(&exec_ctx, client_channel_elem,
&w->state, &w->on_complete);
+ } else if (client_channel_elem->filter == &grpc_client_uchannel_filter) {
+ GRPC_CHANNEL_INTERNAL_REF(channel, "watch_uchannel_connectivity");
+ grpc_client_uchannel_add_interested_party(&exec_ctx, client_channel_elem,
+ grpc_cq_pollset(cq));
+ grpc_client_uchannel_watch_connectivity_state(
+ &exec_ctx, client_channel_elem, &w->state, &w->on_complete);
}
grpc_exec_ctx_finish(&exec_ctx);
diff --git a/src/core/surface/init.c b/src/core/surface/init.c
index 715c90a5e1..b2e66a830e 100644
--- a/src/core/surface/init.c
+++ b/src/core/surface/init.c
@@ -47,6 +47,7 @@
#include "src/core/client_config/resolvers/dns_resolver.h"
#include "src/core/client_config/resolvers/sockaddr_resolver.h"
#include "src/core/debug/trace.h"
+#include "src/core/iomgr/executor.h"
#include "src/core/iomgr/iomgr.h"
#include "src/core/profiling/timers.h"
#include "src/core/surface/api_trace.h"
@@ -108,6 +109,7 @@ void grpc_init(void) {
grpc_register_tracer("connectivity_state", &grpc_connectivity_state_trace);
grpc_security_pre_init();
grpc_iomgr_init();
+ grpc_executor_init();
grpc_tracer_init("GRPC_TRACE");
/* Only initialize census if noone else has. */
if (census_enabled() == CENSUS_FEATURE_NONE) {
@@ -132,6 +134,7 @@ void grpc_shutdown(void) {
gpr_mu_lock(&g_init_mu);
if (--g_initializations == 0) {
grpc_iomgr_shutdown();
+ grpc_executor_shutdown();
census_shutdown();
gpr_timers_global_destroy();
grpc_tracer_shutdown();
diff --git a/src/csharp/.gitignore b/src/csharp/.gitignore
index deac55029e..0f96a48221 100644
--- a/src/csharp/.gitignore
+++ b/src/csharp/.gitignore
@@ -7,6 +7,7 @@ Grpc.v12.suo
Grpc.sdf
TestResult.xml
+coverage_results.xml
/TestResults
.vs/
*.nupkg
diff --git a/src/csharp/.nuget/packages.config b/src/csharp/.nuget/packages.config
index a7df95cf6b..89a310ac56 100644
--- a/src/csharp/.nuget/packages.config
+++ b/src/csharp/.nuget/packages.config
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit.Runners" version="2.6.4" />
+ <package id="OpenCover" version="4.6.166" />
+ <package id="ReportGenerator" version="2.3.2.0" />
</packages> \ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 030a098cad..5eec11abf7 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -137,7 +137,11 @@ namespace Grpc.IntegrationTesting
private async Task<ChannelCredentials> CreateCredentialsAsync()
{
- var credentials = options.UseTls.Value ? TestCredentials.CreateTestClientCredentials(options.UseTestCa.Value) : ChannelCredentials.Insecure;
+ var credentials = ChannelCredentials.Insecure;
+ if (options.UseTls.Value)
+ {
+ credentials = options.UseTestCa.Value ? TestCredentials.CreateSslCredentials() : new SslCredentials();
+ }
if (options.TestCase == "jwt_token_creds")
{
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
index 7bc17a207f..837ae74c45 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -59,7 +59,7 @@ namespace Grpc.IntegrationTesting
server = new Server
{
Services = { TestService.BindService(new TestServiceImpl()) },
- Ports = { { Host, ServerPort.PickUnused, TestCredentials.CreateTestServerCredentials() } }
+ Ports = { { Host, ServerPort.PickUnused, TestCredentials.CreateSslServerCredentials() } }
};
server.Start();
@@ -68,7 +68,7 @@ namespace Grpc.IntegrationTesting
new ChannelOption(ChannelOptions.SslTargetNameOverride, TestCredentials.DefaultHostOverride)
};
int port = server.Ports.Single().BoundPort;
- channel = new Channel(Host, port, TestCredentials.CreateTestClientCredentials(true), options);
+ channel = new Channel(Host, port, TestCredentials.CreateSslCredentials(), options);
client = TestService.NewClient(channel);
}
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
index 29f842be2e..cd47e31c2b 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
@@ -102,7 +102,7 @@ namespace Grpc.IntegrationTesting
int port = options.Port;
if (options.UseTls.Value)
{
- server.Ports.Add(host, port, TestCredentials.CreateTestServerCredentials());
+ server.Ports.Add(host, port, TestCredentials.CreateSslServerCredentials());
}
else
{
diff --git a/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs b/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
index 7a48d6e92e..ce108d808b 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
@@ -51,26 +51,15 @@ namespace Grpc.IntegrationTesting
public const string DefaultHostOverride = "foo.test.google.fr";
public const string ClientCertAuthorityPath = "data/ca.pem";
- public const string ClientCertAuthorityEnvName = "SSL_CERT_FILE";
-
public const string ServerCertChainPath = "data/server1.pem";
public const string ServerPrivateKeyPath = "data/server1.key";
- public static SslCredentials CreateTestClientCredentials(bool useTestCa)
+ public static SslCredentials CreateSslCredentials()
{
- string caPath = ClientCertAuthorityPath;
- if (!useTestCa)
- {
- caPath = Environment.GetEnvironmentVariable(ClientCertAuthorityEnvName);
- if (string.IsNullOrEmpty(caPath))
- {
- throw new ArgumentException("CA path environment variable is not set.");
- }
- }
- return new SslCredentials(File.ReadAllText(caPath));
+ return new SslCredentials(File.ReadAllText(ClientCertAuthorityPath));
}
- public static SslServerCredentials CreateTestServerCredentials()
+ public static SslServerCredentials CreateSslServerCredentials()
{
var keyCertPair = new KeyCertificatePair(
File.ReadAllText(ServerCertChainPath),
diff --git a/src/csharp/README.md b/src/csharp/README.md
index b215d5aa07..65ae0b5efd 100644
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -1,3 +1,4 @@
+[![Nuget](https://img.shields.io/nuget/v/Grpc.svg)](http://www.nuget.org/packages/Grpc/)
gRPC C#
=======
@@ -57,6 +58,9 @@ HOW TO USE
- Add NuGet package `Grpc` as a dependency (Project -> Add NuGet packages).
+- NOTE: Currently, there are no debian packages for the latest version Protocol Buffers compiler (_protoc_)
+ and the gRPC _protoc_ plugin. You can install them using [gRPC Linuxbrew instructions][].
+
**Mac OS X**
- WARNING: As of now gRPC C# only works on 64bit version of Mono (because we don't compile
@@ -70,7 +74,7 @@ HOW TO USE
$ curl -fsSL https://goo.gl/getgrpc | bash -
```
This will download and run the [gRPC install script][], then install the latest version of gRPC C core and native C# extension.
- It also installs Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin for ruby.
+ It also installs Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin for C#.
- Install 64-bit version of mono with command `brew install mono`.
@@ -192,8 +196,9 @@ Internally, gRPC C# uses a native library written in C (gRPC C core) and invokes
- Possible cause for the problem is that the `grpc_csharp_ext` library is installed, but it has different bitness (32/64bit) than your C# runtime (in case you are using mono) or C# application.
+[gRPC Linuxbrew instructions]:https://github.com/grpc/homebrew-grpc#quick-install-linux
[homebrew]:http://brew.sh
[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
[grpc.io]: http://www.grpc.io/docs/installation/csharp.html
[Debian jessie-backports]:http://backports.debian.org/Instructions/
-[Helloworld example]:../../examples/csharp/helloworld \ No newline at end of file
+[Helloworld example]:../../examples/csharp/helloworld
diff --git a/src/node/interop/interop_client.js b/src/node/interop/interop_client.js
index b5061895cf..53ffa385bd 100644
--- a/src/node/interop/interop_client.js
+++ b/src/node/interop/interop_client.js
@@ -562,11 +562,11 @@ function runTest(address, host_override, test_case, tls, test_ca, done, extra) {
var ca_path;
if (test_ca) {
ca_path = path.join(__dirname, '../test/data/ca.pem');
+ var ca_data = fs.readFileSync(ca_path);
+ creds = grpc.credentials.createSsl(ca_data);
} else {
- ca_path = process.env.SSL_CERT_FILE;
+ creds = grpc.credentials.createSsl();
}
- var ca_data = fs.readFileSync(ca_path);
- creds = grpc.credentials.createSsl(ca_data);
if (host_override) {
options['grpc.ssl_target_name_override'] = host_override;
options['grpc.default_authority'] = host_override;
diff --git a/src/node/src/metadata.js b/src/node/src/metadata.js
index 375c7e985c..0a2f1489b6 100644
--- a/src/node/src/metadata.js
+++ b/src/node/src/metadata.js
@@ -68,7 +68,6 @@ function normalizeKey(key) {
function validate(key, value) {
if (_.endsWith(key, '-bin')) {
if (!(value instanceof Buffer)) {
- console.log(value.constructor.toString());
throw new Error('keys that end with \'-bin\' must have Buffer values');
}
} else {
diff --git a/src/node/src/server.js b/src/node/src/server.js
index 9f9e1898a9..d1fb627e6c 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -608,10 +608,6 @@ function Server(options) {
throw new Error('Server is already running');
}
this.started = true;
- console.log('Server starting');
- _.each(handlers, function(handler, handler_name) {
- console.log('Serving', handler_name);
- });
server.start();
/**
* Handles the SERVER_RPC_NEW event. If there is a handler associated with
diff --git a/src/node/test/async_test.js b/src/node/test/async_test.js
index 6d71ea24f5..0af63c379e 100644
--- a/src/node/test/async_test.js
+++ b/src/node/test/async_test.js
@@ -86,7 +86,6 @@ describe('Async functionality', function() {
});
readStream.on('error', function (error) {
- console.log(error);
});
});
diff --git a/src/node/test/credentials_test.js b/src/node/test/credentials_test.js
index 3d0b38fd52..3e01b62cf4 100644
--- a/src/node/test/credentials_test.js
+++ b/src/node/test/credentials_test.js
@@ -71,7 +71,7 @@ var fakeSuccessfulGoogleCredentials = {
var fakeFailingGoogleCredentials = {
getRequestMetadata: function(service_url, callback) {
setTimeout(function() {
- callback(new Error("Authorization failure"));
+ callback(new Error('Authorization failure'));
}, 0);
}
};
diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h
index 2e379a7157..6b443877e9 100644
--- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h
+++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h
@@ -33,17 +33,19 @@
#import "GRPCCall.h"
-// Helpers for setting and reading headers compatible with OAuth2.
+/** Helpers for setting and reading headers compatible with OAuth2. */
@interface GRPCCall (OAuth2)
-// Setting this property is equivalent to setting "Bearer <passed token>" as the value of the
-// request header with key "authorization" (the authorization header). Setting it to nil removes the
-// authorization header from the request.
-// The value obtained by getting the property is the OAuth2 bearer token if the authorization header
-// of the request has the form "Bearer <token>", or nil otherwise.
+/**
+ * Setting this property is equivalent to setting "Bearer <passed token>" as the value of the
+ * request header with key "authorization" (the authorization header). Setting it to nil removes the
+ * authorization header from the request.
+ * The value obtained by getting the property is the OAuth2 bearer token if the authorization header
+ * of the request has the form "Bearer <token>", or nil otherwise.
+ */
@property(atomic, copy) NSString *oauth2AccessToken;
-// Returns the value (if any) of the "www-authenticate" response header (the challenge header).
+/** Returns the value (if any) of the "www-authenticate" response header (the challenge header). */
@property(atomic, readonly) NSString *oauth2ChallengeHeader;
@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.h b/src/objective-c/GRPCClient/GRPCCall+Tests.h
index cca1614606..ccc5723ec7 100644
--- a/src/objective-c/GRPCClient/GRPCCall+Tests.h
+++ b/src/objective-c/GRPCClient/GRPCCall+Tests.h
@@ -33,22 +33,28 @@
#import "GRPCCall.h"
-// Methods to let tune down the security of gRPC connections for specific hosts. These shouldn't be
-// used in releases, but are sometimes needed for testing.
+/**
+ * Methods to let tune down the security of gRPC connections for specific hosts. These shouldn't be
+ * used in releases, but are sometimes needed for testing.
+ */
@interface GRPCCall (Tests)
-// Establish all SSL connections to the provided host using the passed SSL target name and the root
-// certificates found in the file at |certsPath|.
-//
-// Must be called before any gRPC call to that host is made. It's illegal to pass the same host to
-// more than one invocation of the methods of this category.
+/**
+ * Establish all SSL connections to the provided host using the passed SSL target name and the root
+ * certificates found in the file at |certsPath|.
+ *
+ * Must be called before any gRPC call to that host is made. It's illegal to pass the same host to
+ * more than one invocation of the methods of this category.
+ */
+ (void)useTestCertsPath:(NSString *)certsPath
testName:(NSString *)testName
forHost:(NSString *)host;
-// Establish all connections to the provided host using cleartext instead of SSL.
-//
-// Must be called before any gRPC call to that host is made. It's illegal to pass the same host to
-// more than one invocation of the methods of this category.
+/**
+ * Establish all connections to the provided host using cleartext instead of SSL.
+ *
+ * Must be called before any gRPC call to that host is made. It's illegal to pass the same host to
+ * more than one invocation of the methods of this category.
+ */
+ (void)useInsecureConnectionsForHost:(NSString *)host;
@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.m b/src/objective-c/GRPCClient/GRPCCall+Tests.m
index bade0b2920..c8e8133703 100644
--- a/src/objective-c/GRPCClient/GRPCCall+Tests.m
+++ b/src/objective-c/GRPCClient/GRPCCall+Tests.m
@@ -40,6 +40,9 @@
+ (void)useTestCertsPath:(NSString *)certsPath
testName:(NSString *)testName
forHost:(NSString *)host {
+ if (!host || !certsPath || !testName) {
+ [NSException raise:NSInvalidArgumentException format:@"host, path and name must be provided."];
+ }
GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
hostConfig.pathToCertificates = certsPath;
hostConfig.hostNameOverride = testName;
diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h
index 35f7e16af7..5918f8857a 100644
--- a/src/objective-c/GRPCClient/GRPCCall.h
+++ b/src/objective-c/GRPCClient/GRPCCall.h
@@ -31,117 +31,145 @@
*
*/
-// The gRPC protocol is an RPC protocol on top of HTTP2.
-//
-// While the most common type of RPC receives only one request message and returns only one response
-// message, the protocol also supports RPCs that return multiple individual messages in a streaming
-// fashion, RPCs that accept a stream of request messages, or RPCs with both streaming requests and
-// responses.
-//
-// Conceptually, each gRPC call consists of a bidirectional stream of binary messages, with RPCs of
-// the "non-streaming type" sending only one message in the corresponding direction (the protocol
-// doesn't make any distinction).
-//
-// Each RPC uses a different HTTP2 stream, and thus multiple simultaneous RPCs can be multiplexed
-// transparently on the same TCP connection.
+/**
+ * The gRPC protocol is an RPC protocol on top of HTTP2.
+ *
+ * While the most common type of RPC receives only one request message and returns only one response
+ * message, the protocol also supports RPCs that return multiple individual messages in a streaming
+ * fashion, RPCs that accept a stream of request messages, or RPCs with both streaming requests and
+ * responses.
+ *
+ * Conceptually, each gRPC call consists of a bidirectional stream of binary messages, with RPCs of
+ * the "non-streaming type" sending only one message in the corresponding direction (the protocol
+ * doesn't make any distinction).
+ *
+ * Each RPC uses a different HTTP2 stream, and thus multiple simultaneous RPCs can be multiplexed
+ * transparently on the same TCP connection.
+ */
#import <Foundation/Foundation.h>
#import <RxLibrary/GRXWriter.h>
#pragma mark gRPC errors
-// Domain of NSError objects produced by gRPC.
+/** Domain of NSError objects produced by gRPC. */
extern NSString *const kGRPCErrorDomain;
-// gRPC error codes.
-// Note that a few of these are never produced by the gRPC libraries, but are of general utility for
-// server applications to produce.
+/**
+ * gRPC error codes.
+ * Note that a few of these are never produced by the gRPC libraries, but are of general utility for
+ * server applications to produce.
+ */
typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
- // The operation was cancelled (typically by the caller).
+ /** The operation was cancelled (typically by the caller). */
GRPCErrorCodeCancelled = 1,
- // Unknown error. Errors raised by APIs that do not return enough error information may be
- // converted to this error.
+ /**
+ * Unknown error. Errors raised by APIs that do not return enough error information may be
+ * converted to this error.
+ */
GRPCErrorCodeUnknown = 2,
- // The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION.
- // INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the
- // server (e.g., a malformed file name).
+ /**
+ * The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION.
+ * INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the
+ * server (e.g., a malformed file name).
+ */
GRPCErrorCodeInvalidArgument = 3,
- // Deadline expired before operation could complete. For operations that change the state of the
- // server, this error may be returned even if the operation has completed successfully. For
- // example, a successful response from the server could have been delayed long enough for the
- // deadline to expire.
+ /**
+ * Deadline expired before operation could complete. For operations that change the state of the
+ * server, this error may be returned even if the operation has completed successfully. For
+ * example, a successful response from the server could have been delayed long enough for the
+ * deadline to expire.
+ */
GRPCErrorCodeDeadlineExceeded = 4,
- // Some requested entity (e.g., file or directory) was not found.
+ /** Some requested entity (e.g., file or directory) was not found. */
GRPCErrorCodeNotFound = 5,
- // Some entity that we attempted to create (e.g., file or directory) already exists.
+ /** Some entity that we attempted to create (e.g., file or directory) already exists. */
GRPCErrorCodeAlreadyExists = 6,
- // The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't
- // used for rejections caused by exhausting some resource (RESOURCE_EXHAUSTED is used instead for
- // those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller
- // (UNAUTHENTICATED is used instead for those errors).
+ /**
+ * The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't
+ * used for rejections caused by exhausting some resource (RESOURCE_EXHAUSTED is used instead for
+ * those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller
+ * (UNAUTHENTICATED is used instead for those errors).
+ */
GRPCErrorCodePermissionDenied = 7,
- // The request does not have valid authentication credentials for the operation (e.g. the caller's
- // identity can't be verified).
+ /**
+ * The request does not have valid authentication credentials for the operation (e.g. the caller's
+ * identity can't be verified).
+ */
GRPCErrorCodeUnauthenticated = 16,
- // Some resource has been exhausted, perhaps a per-user quota.
+ /** Some resource has been exhausted, perhaps a per-user quota. */
GRPCErrorCodeResourceExhausted = 8,
- // The RPC was rejected because the server is not in a state required for the procedure's
- // execution. For example, a directory to be deleted may be non-empty, etc.
- // The client should not retry until the server state has been explicitly fixed (e.g. by
- // performing another RPC). The details depend on the service being called, and should be found in
- // the NSError's userInfo.
+ /**
+ * The RPC was rejected because the server is not in a state required for the procedure's
+ * execution. For example, a directory to be deleted may be non-empty, etc.
+ * The client should not retry until the server state has been explicitly fixed (e.g. by
+ * performing another RPC). The details depend on the service being called, and should be found in
+ * the NSError's userInfo.
+ */
GRPCErrorCodeFailedPrecondition = 9,
- // The RPC was aborted, typically due to a concurrency issue like sequencer check failures,
- // transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read-
- // modify-write sequence).
+ /**
+ * The RPC was aborted, typically due to a concurrency issue like sequencer check failures,
+ * transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read-
+ * modify-write sequence).
+ */
GRPCErrorCodeAborted = 10,
- // The RPC was attempted past the valid range. E.g., enumerating past the end of a list.
- // Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state
- // changes. For example, an RPC to get elements of a list will generate INVALID_ARGUMENT if asked
- // to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return
- // the element at an index past the current size of the list.
+ /**
+ * The RPC was attempted past the valid range. E.g., enumerating past the end of a list.
+ * Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state
+ * changes. For example, an RPC to get elements of a list will generate INVALID_ARGUMENT if asked
+ * to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return
+ * the element at an index past the current size of the list.
+ */
GRPCErrorCodeOutOfRange = 11,
- // The procedure is not implemented or not supported/enabled in this server.
+ /** The procedure is not implemented or not supported/enabled in this server. */
GRPCErrorCodeUnimplemented = 12,
- // Internal error. Means some invariant expected by the server application or the gRPC library has
- // been broken.
+ /**
+ * Internal error. Means some invariant expected by the server application or the gRPC library has
+ * been broken.
+ */
GRPCErrorCodeInternal = 13,
- // The server is currently unavailable. This is most likely a transient condition and may be
- // corrected by retrying with a backoff.
+ /**
+ * The server is currently unavailable. This is most likely a transient condition and may be
+ * corrected by retrying with a backoff.
+ */
GRPCErrorCodeUnavailable = 14,
- // Unrecoverable data loss or corruption.
+ /** Unrecoverable data loss or corruption. */
GRPCErrorCodeDataLoss = 15,
};
-// Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by
-// the server.
+/**
+ * Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by
+ * the server.
+ */
extern id const kGRPCHeadersKey;
extern id const kGRPCTrailersKey;
#pragma mark GRPCCall
-// The container of the request headers of an RPC conforms to this protocol, which is a subset of
-// NSMutableDictionary's interface. It will become a NSMutableDictionary later on.
-// The keys of this container are the header names, which per the HTTP standard are case-
-// insensitive. They are stored in lowercase (which is how HTTP/2 mandates them on the wire), and
-// can only consist of ASCII characters.
-// A header value is a NSString object (with only ASCII characters), unless the header name has the
-// suffix "-bin", in which case the value has to be a NSData object.
+/**
+ * The container of the request headers of an RPC conforms to this protocol, which is a subset of
+ * NSMutableDictionary's interface. It will become a NSMutableDictionary later on.
+ * The keys of this container are the header names, which per the HTTP standard are case-
+ * insensitive. They are stored in lowercase (which is how HTTP/2 mandates them on the wire), and
+ * can only consist of ASCII characters.
+ * A header value is a NSString object (with only ASCII characters), unless the header name has the
+ * suffix "-bin", in which case the value has to be a NSData object.
+ */
@protocol GRPCRequestHeaders <NSObject>
@property(nonatomic, readonly) NSUInteger count;
@@ -154,53 +182,63 @@ extern id const kGRPCTrailersKey;
@end
-// Represents a single gRPC remote call.
+/** Represents a single gRPC remote call. */
@interface GRPCCall : GRXWriter
-// These HTTP headers will be passed to the server as part of this call. Each HTTP header is a
-// name-value pair with string names and either string or binary values.
-//
-// The passed dictionary has to use NSString keys, corresponding to the header names. The value
-// associated to each can be a NSString object or a NSData object. E.g.:
-//
-// call.requestHeaders = @{@"authorization": @"Bearer ..."};
-//
-// call.requestHeaders[@"my-header-bin"] = someData;
-//
-// After the call is started, trying to modify this property is an error.
-//
-// The property is initialized to an empty NSMutableDictionary.
+/**
+ * These HTTP headers will be passed to the server as part of this call. Each HTTP header is a
+ * name-value pair with string names and either string or binary values.
+ *
+ * The passed dictionary has to use NSString keys, corresponding to the header names. The value
+ * associated to each can be a NSString object or a NSData object. E.g.:
+ *
+ * call.requestHeaders = @{@"authorization": @"Bearer ..."};
+ *
+ * call.requestHeaders[@"my-header-bin"] = someData;
+ *
+ * After the call is started, trying to modify this property is an error.
+ *
+ * The property is initialized to an empty NSMutableDictionary.
+ */
@property(atomic, readonly) id<GRPCRequestHeaders> requestHeaders;
-// This dictionary is populated with the HTTP headers received from the server. This happens before
-// any response message is received from the server. It has the same structure as the request
-// headers dictionary: Keys are NSString header names; names ending with the suffix "-bin" have a
-// NSData value; the others have a NSString value.
-//
-// The value of this property is nil until all response headers are received, and will change before
-// any of -writeValue: or -writesFinishedWithError: are sent to the writeable.
+/**
+ * This dictionary is populated with the HTTP headers received from the server. This happens before
+ * any response message is received from the server. It has the same structure as the request
+ * headers dictionary: Keys are NSString header names; names ending with the suffix "-bin" have a
+ * NSData value; the others have a NSString value.
+ *
+ * The value of this property is nil until all response headers are received, and will change before
+ * any of -writeValue: or -writesFinishedWithError: are sent to the writeable.
+ */
@property(atomic, readonly) NSDictionary *responseHeaders;
-// Same as responseHeaders, but populated with the HTTP trailers received from the server before the
-// call finishes.
-//
-// The value of this property is nil until all response trailers are received, and will change
-// before -writesFinishedWithError: is sent to the writeable.
+/**
+ * Same as responseHeaders, but populated with the HTTP trailers received from the server before the
+ * call finishes.
+ *
+ * The value of this property is nil until all response trailers are received, and will change
+ * before -writesFinishedWithError: is sent to the writeable.
+ */
@property(atomic, readonly) NSDictionary *responseTrailers;
-// The request writer has to write NSData objects into the provided Writeable. The server will
-// receive each of those separately and in order as distinct messages.
-// A gRPC call might not complete until the request writer finishes. On the other hand, the request
-// finishing doesn't necessarily make the call to finish, as the server might continue sending
-// messages to the response side of the call indefinitely (depending on the semantics of the
-// specific remote method called).
-// To finish a call right away, invoke cancel.
+/**
+ * The request writer has to write NSData objects into the provided Writeable. The server will
+ * receive each of those separately and in order as distinct messages.
+ * A gRPC call might not complete until the request writer finishes. On the other hand, the request
+ * finishing doesn't necessarily make the call to finish, as the server might continue sending
+ * messages to the response side of the call indefinitely (depending on the semantics of the
+ * specific remote method called).
+ * To finish a call right away, invoke cancel.
+ */
- (instancetype)initWithHost:(NSString *)host
path:(NSString *)path
requestsWriter:(GRXWriter *)requestsWriter NS_DESIGNATED_INITIALIZER;
-// Finishes the request side of this call, notifies the server that the RPC should be cancelled, and
-// finishes the response side of the call with an error of code CANCELED.
+/**
+ * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and
+ * finishes the response side of the call with an error of code CANCELED.
+ */
- (void)cancel;
// TODO(jcanizales): Let specify a deadline. As a category of GRXWriter?
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h
index 2a7b701576..e2d19d506a 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.h
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.h
@@ -35,12 +35,16 @@
struct grpc_channel;
-// Each separate instance of this class represents at least one TCP connection to the provided host.
-// Create them using one of the subclasses |GRPCSecureChannel| and |GRPCUnsecuredChannel|.
+/**
+ * Each separate instance of this class represents at least one TCP connection to the provided host.
+ * Create them using one of the subclasses |GRPCSecureChannel| and |GRPCUnsecuredChannel|.
+ */
@interface GRPCChannel : NSObject
@property(nonatomic, readonly) struct grpc_channel *unmanagedChannel;
-// This initializer takes ownership of the passed channel, and will destroy it when this object is
-// deallocated. It's illegal to pass the same grpc_channel to two different GRPCChannel objects.
+/**
+ * This initializer takes ownership of the passed channel, and will destroy it when this object is
+ * deallocated. It's illegal to pass the same grpc_channel to two different GRPCChannel objects.
+ */
- (instancetype)initWithChannel:(struct grpc_channel *)unmanagedChannel NS_DESIGNATED_INITIALIZER;
@end
diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
index ab8d714d22..fe3b8f39d1 100644
--- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
+++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
@@ -36,15 +36,17 @@
typedef void(^GRPCQueueCompletionHandler)(bool success);
-// This class lets one more easily use |grpc_completion_queue|. To use it, pass the value of the
-// |unmanagedQueue| property of an instance of this class to |grpc_channel_create_call|. Then for
-// every |grpc_call_*| method that accepts a tag, you can pass a block of type
-// |GRPCQueueCompletionHandler| (remembering to cast it using |__bridge_retained|). The block is
-// guaranteed to eventually be called, by a concurrent queue, and then released. Each such block is
-// passed a |bool| that tells if the operation was successful.
-//
-// Release the GRPCCompletionQueue object only after you are not going to pass any more blocks to
-// the |grpc_call| that's using it.
+/**
+ * This class lets one more easily use |grpc_completion_queue|. To use it, pass the value of the
+ * |unmanagedQueue| property of an instance of this class to |grpc_channel_create_call|. Then for
+ * every |grpc_call_*| method that accepts a tag, you can pass a block of type
+ * |GRPCQueueCompletionHandler| (remembering to cast it using |__bridge_retained|). The block is
+ * guaranteed to eventually be called, by a concurrent queue, and then released. Each such block is
+ * passed a |bool| that tells if the operation was successful.
+ *
+ * Release the GRPCCompletionQueue object only after you are not going to pass any more blocks to
+ * the |grpc_call| that's using it.
+ */
@interface GRPCCompletionQueue : NSObject
@property(nonatomic, readonly) grpc_completion_queue *unmanagedQueue;
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h
index f0bbd53023..6b4f98746d 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.h
+++ b/src/objective-c/GRPCClient/private/GRPCHost.h
@@ -40,18 +40,18 @@ struct grpc_call;
@property(nonatomic, readonly) NSString *address;
-// The following properties should only be modified for testing:
+/** The following properties should only be modified for testing: */
@property(nonatomic, getter=isSecure) BOOL secure;
@property(nonatomic, copy) NSString *pathToCertificates;
@property(nonatomic, copy) NSString *hostNameOverride;
-// Host objects initialized with the same address are the same.
+/** Host objects initialized with the same address are the same. */
+ (instancetype)hostWithAddress:(NSString *)address;
- (instancetype)initWithAddress:(NSString *)address NS_DESIGNATED_INITIALIZER;
-// Create a grpc_call object to the provided path on this host.
+/** Create a grpc_call object to the provided path on this host. */
- (struct grpc_call *)unmanagedCallWithPath:(NSString *)path
completionQueue:(GRPCCompletionQueue *)queue;
diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannel.h b/src/objective-c/GRPCClient/private/GRPCSecureChannel.h
index 74257eb058..4e0881e5a2 100644
--- a/src/objective-c/GRPCClient/private/GRPCSecureChannel.h
+++ b/src/objective-c/GRPCClient/private/GRPCSecureChannel.h
@@ -40,13 +40,15 @@ struct grpc_credentials;
@interface GRPCSecureChannel : GRPCChannel
- (instancetype)initWithHost:(NSString *)host;
-// Only in tests shouldn't pathToCertificates or hostNameOverride be nil. Passing nil for
-// pathToCertificates results in using the default root certificates distributed with the library.
+/**
+ * Only in tests shouldn't pathToCertificates or hostNameOverride be nil. Passing nil for
+ * pathToCertificates results in using the default root certificates distributed with the library.
+ */
- (instancetype)initWithHost:(NSString *)host
pathToCertificates:(NSString *)path
hostNameOverride:(NSString *)hostNameOverride;
-// The passed arguments aren't required to be valid beyond the invocation of this initializer.
+/** The passed arguments aren't required to be valid beyond the invocation of this initializer. */
- (instancetype)initWithHost:(NSString *)host
credentials:(struct grpc_credentials *)credentials
args:(grpc_channel_args *)args NS_DESIGNATED_INITIALIZER;
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
index 4ca2766147..7747aa53ef 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
@@ -39,7 +39,7 @@
@interface GRPCOperation : NSObject
@property(nonatomic, readonly) grpc_op op;
-// Guaranteed to be called when the operation has finished.
+/** Guaranteed to be called when the operation has finished. */
- (void)finish;
@end
diff --git a/src/objective-c/GRPCClient/private/NSError+GRPC.h b/src/objective-c/GRPCClient/private/NSError+GRPC.h
index f4729dc8a1..e0c1efc1f9 100644
--- a/src/objective-c/GRPCClient/private/NSError+GRPC.h
+++ b/src/objective-c/GRPCClient/private/NSError+GRPC.h
@@ -35,7 +35,9 @@
#include <grpc/grpc.h>
@interface NSError (GRPC)
-// Returns nil if the status code is OK. Otherwise, a NSError whose code is one of |GRPCErrorCode|
-// and whose domain is |kGRPCErrorDomain|.
+/**
+ * Returns nil if the status code is OK. Otherwise, a NSError whose code is one of |GRPCErrorCode|
+ * and whose domain is |kGRPCErrorDomain|.
+ */
+ (instancetype)grpc_errorFromStatusCode:(grpc_status_code)statusCode details:(char *)details;
@end
diff --git a/src/objective-c/ProtoRPC/ProtoMethod.h b/src/objective-c/ProtoRPC/ProtoMethod.h
index 8f554a0483..a0ed2cf98a 100644
--- a/src/objective-c/ProtoRPC/ProtoMethod.h
+++ b/src/objective-c/ProtoRPC/ProtoMethod.h
@@ -33,8 +33,10 @@
#import <Foundation/Foundation.h>
-// A fully-qualified proto service method name. Full qualification is needed because a gRPC endpoint
-// can implement multiple services.
+/**
+ * A fully-qualified proto service method name. Full qualification is needed because a gRPC endpoint
+ * can implement multiple services.
+ */
@interface ProtoMethod : NSObject
@property(nonatomic, readonly) NSString *package;
@property(nonatomic, readonly) NSString *service;
diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.h b/src/objective-c/RxLibrary/GRXBufferedPipe.h
index ca94ce275f..03b0359278 100644
--- a/src/objective-c/RxLibrary/GRXBufferedPipe.h
+++ b/src/objective-c/RxLibrary/GRXBufferedPipe.h
@@ -36,25 +36,27 @@
#import "GRXWriteable.h"
#import "GRXWriter.h"
-// A buffered pipe is a Writer that also acts as a Writeable.
-// Once it is started, whatever values are written into it (via -writeValue:) will be propagated
-// immediately, unless flow control prevents it.
-// If it is throttled and keeps receiving values, as well as if it receives values before being
-// started, it will buffer them and propagate them in order as soon as its state becomes Started.
-// If it receives an error (via -writesFinishedWithError:), it will drop any buffered values and
-// propagate the error immediately.
-//
-// Beware that a pipe of this type can't prevent receiving more values when it is paused (for
-// example if used to write data to a congested network connection). Because in such situations the
-// pipe will keep buffering all data written to it, your application could run out of memory and
-// crash. If you want to react to flow control signals to prevent that, instead of using this class
-// you can implement an object that conforms to GRXWriter.
-//
-// Thread-safety:
-// The methods of an object of this class should not be called concurrently from different threads.
+/**
+ * A buffered pipe is a Writer that also acts as a Writeable.
+ * Once it is started, whatever values are written into it (via -writeValue:) will be propagated
+ * immediately, unless flow control prevents it.
+ * If it is throttled and keeps receiving values, as well as if it receives values before being
+ * started, it will buffer them and propagate them in order as soon as its state becomes Started.
+ * If it receives an error (via -writesFinishedWithError:), it will drop any buffered values and
+ * propagate the error immediately.
+ *
+ * Beware that a pipe of this type can't prevent receiving more values when it is paused (for
+ * example if used to write data to a congested network connection). Because in such situations the
+ * pipe will keep buffering all data written to it, your application could run out of memory and
+ * crash. If you want to react to flow control signals to prevent that, instead of using this class
+ * you can implement an object that conforms to GRXWriter.
+ *
+ * Thread-safety:
+ * The methods of an object of this class should not be called concurrently from different threads.
+ */
@interface GRXBufferedPipe : GRXWriter<GRXWriteable>
-// Convenience constructor.
+/** Convenience constructor. */
+ (instancetype)pipe;
@end
diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h
index 1080001905..b2775f98b5 100644
--- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h
+++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h
@@ -36,36 +36,48 @@
#import "GRXWriter.h"
#import "GRXWriteable.h"
-// This is a thread-safe wrapper over a GRXWriteable instance. It lets one enqueue calls to a
-// GRXWriteable instance for the main thread, guaranteeing that writesFinishedWithError: is the last
-// message sent to it (no matter what messages are sent to the wrapper, in what order, nor from
-// which thread). It also guarantees that, if cancelWithError: is called from the main thread (e.g.
-// by the app cancelling the writes), no further messages are sent to the writeable except
-// writesFinishedWithError:.
-//
-// TODO(jcanizales): Let the user specify another queue for the writeable callbacks.
+/**
+ * This is a thread-safe wrapper over a GRXWriteable instance. It lets one enqueue calls to a
+ * GRXWriteable instance for the main thread, guaranteeing that writesFinishedWithError: is the last
+ * message sent to it (no matter what messages are sent to the wrapper, in what order, nor from
+ * which thread). It also guarantees that, if cancelWithError: is called from the main thread (e.g.
+ * by the app cancelling the writes), no further messages are sent to the writeable except
+ * writesFinishedWithError:.
+ *
+ * TODO(jcanizales): Let the user specify another queue for the writeable callbacks.
+ */
@interface GRXConcurrentWriteable : NSObject
-// The GRXWriteable passed is the wrapped writeable.
-// The GRXWriteable instance is retained until writesFinishedWithError: is sent to it, and released
-// after that.
+/**
+ * The GRXWriteable passed is the wrapped writeable.
+ * The GRXWriteable instance is retained until writesFinishedWithError: is sent to it, and released
+ * after that.
+ */
- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable NS_DESIGNATED_INITIALIZER;
-// Enqueues writeValue: to be sent to the writeable in the main thread.
-// The passed handler is invoked from the main thread after writeValue: returns.
+/**
+ * Enqueues writeValue: to be sent to the writeable in the main thread.
+ * The passed handler is invoked from the main thread after writeValue: returns.
+ */
- (void)enqueueValue:(id)value completionHandler:(void (^)())handler;
-// Enqueues writesFinishedWithError:nil to be sent to the writeable in the main thread. After that
-// message is sent to the writeable, all other methods of this object are effectively noops.
+/**
+ * Enqueues writesFinishedWithError:nil to be sent to the writeable in the main thread. After that
+ * message is sent to the writeable, all other methods of this object are effectively noops.
+ */
- (void)enqueueSuccessfulCompletion;
-// If the writeable has not yet received a writesFinishedWithError: message, this will enqueue one
-// to be sent to it in the main thread, and cancel all other pending messages to the writeable
-// enqueued by this object (both past and future).
-// The error argument cannot be nil.
+/**
+ * If the writeable has not yet received a writesFinishedWithError: message, this will enqueue one
+ * to be sent to it in the main thread, and cancel all other pending messages to the writeable
+ * enqueued by this object (both past and future).
+ * The error argument cannot be nil.
+ */
- (void)cancelWithError:(NSError *)error;
-// Cancels all pending messages to the writeable enqueued by this object (both past and future).
-// Because the writeable won't receive writesFinishedWithError:, this also releases the writeable.
+/**
+ * Cancels all pending messages to the writeable enqueued by this object (both past and future).
+ * Because the writeable won't receive writesFinishedWithError:, this also releases the writeable.
+ */
- (void)cancelSilently;
@end
diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.h b/src/objective-c/RxLibrary/GRXForwardingWriter.h
index f310832284..8d45b8ed8d 100644
--- a/src/objective-c/RxLibrary/GRXForwardingWriter.h
+++ b/src/objective-c/RxLibrary/GRXForwardingWriter.h
@@ -33,17 +33,19 @@
#import "GRXWriter.h"
-// A "proxy" class that simply forwards values, completion, and errors from its input writer to its
-// writeable.
-// It is useful as a superclass for pipes that act as a transformation of their
-// input writer, and for classes that represent objects with input and
-// output sequences of values, like an RPC.
-//
-// Thread-safety:
-// All messages sent to this object need to be serialized. When it is started, the writer it wraps
-// is started in the same thread. Manual state changes are propagated to the wrapped writer in the
-// same thread too. Importantly, all messages the wrapped writer sends to its writeable need to be
-// serialized with any message sent to this object.
+/**
+ * A "proxy" class that simply forwards values, completion, and errors from its input writer to its
+ * writeable.
+ * It is useful as a superclass for pipes that act as a transformation of their
+ * input writer, and for classes that represent objects with input and
+ * output sequences of values, like an RPC.
+ *
+ * Thread-safety:
+ * All messages sent to this object need to be serialized. When it is started, the writer it wraps
+ * is started in the same thread. Manual state changes are propagated to the wrapped writer in the
+ * same thread too. Importantly, all messages the wrapped writer sends to its writeable need to be
+ * serialized with any message sent to this object.
+ */
@interface GRXForwardingWriter : GRXWriter
- (instancetype)initWithWriter:(GRXWriter *)writer NS_DESIGNATED_INITIALIZER;
@end
diff --git a/src/objective-c/RxLibrary/GRXImmediateWriter.h b/src/objective-c/RxLibrary/GRXImmediateWriter.h
index 3fcc259434..e22b056ff5 100644
--- a/src/objective-c/RxLibrary/GRXImmediateWriter.h
+++ b/src/objective-c/RxLibrary/GRXImmediateWriter.h
@@ -35,46 +35,60 @@
#import "GRXWriter.h"
-// Utility to construct GRXWriter instances from values that are immediately available when
-// required.
-//
-// Thread-safety:
-//
-// An object of this class shouldn't be messaged concurrently by more than one thread. It will start
-// messaging the writeable before |startWithWriteable:| returns, in the same thread. That is the
-// only place where the writer can be paused or stopped prematurely.
-//
-// If a paused writer of this class is resumed, it will start messaging the writeable, in the same
-// thread, before |setState:| returns. Because the object can't be legally accessed concurrently,
-// that's the only place where it can be paused again (or stopped).
+/**
+ * Utility to construct GRXWriter instances from values that are immediately available when
+ * required.
+ *
+ * Thread-safety:
+ *
+ * An object of this class shouldn't be messaged concurrently by more than one thread. It will start
+ * messaging the writeable before |startWithWriteable:| returns, in the same thread. That is the
+ * only place where the writer can be paused or stopped prematurely.
+ *
+ * If a paused writer of this class is resumed, it will start messaging the writeable, in the same
+ * thread, before |setState:| returns. Because the object can't be legally accessed concurrently,
+ * that's the only place where it can be paused again (or stopped).
+ */
@interface GRXImmediateWriter : GRXWriter
-// Returns a writer that pulls values from the passed NSEnumerator instance and pushes them to
-// its writeable. The NSEnumerator is released when it finishes.
+/**
+ * Returns a writer that pulls values from the passed NSEnumerator instance and pushes them to
+ * its writeable. The NSEnumerator is released when it finishes.
+ */
+ (GRXWriter *)writerWithEnumerator:(NSEnumerator *)enumerator;
-// Returns a writer that pushes to its writeable the successive values returned by the passed
-// block. When the block first returns nil, it is released.
+/**
+ * Returns a writer that pushes to its writeable the successive values returned by the passed
+ * block. When the block first returns nil, it is released.
+ */
+ (GRXWriter *)writerWithValueSupplier:(id (^)())block;
-// Returns a writer that iterates over the values of the passed container and pushes them to
-// its writeable. The container is released when the iteration is over.
-//
-// Note that the usual speed gain of NSFastEnumeration over NSEnumerator results from not having to
-// call one method per element. Because GRXWriteable instances accept values one by one, that speed
-// gain doesn't happen here.
+/**
+ * Returns a writer that iterates over the values of the passed container and pushes them to
+ * its writeable. The container is released when the iteration is over.
+ *
+ * Note that the usual speed gain of NSFastEnumeration over NSEnumerator results from not having to
+ * call one method per element. Because GRXWriteable instances accept values one by one, that speed
+ * gain doesn't happen here.
+ */
+ (GRXWriter *)writerWithContainer:(id<NSFastEnumeration>)container;
-// Returns a writer that sends the passed value to its writeable and then finishes (releasing the
-// value).
+/**
+ * Returns a writer that sends the passed value to its writeable and then finishes (releasing the
+ * value).
+ */
+ (GRXWriter *)writerWithValue:(id)value;
-// Returns a writer that, as part of its start method, sends the passed error to the writeable
-// (then releasing the error).
+/**
+ * Returns a writer that, as part of its start method, sends the passed error to the writeable
+ * (then releasing the error).
+ */
+ (GRXWriter *)writerWithError:(NSError *)error;
-// Returns a writer that, as part of its start method, finishes immediately without sending any
-// values to its writeable.
+/**
+ * Returns a writer that, as part of its start method, finishes immediately without sending any
+ * values to its writeable.
+ */
+ (GRXWriter *)emptyWriter;
@end
diff --git a/src/objective-c/RxLibrary/GRXWriteable.h b/src/objective-c/RxLibrary/GRXWriteable.h
index 45613d6dd0..7fe805c663 100644
--- a/src/objective-c/RxLibrary/GRXWriteable.h
+++ b/src/objective-c/RxLibrary/GRXWriteable.h
@@ -33,16 +33,20 @@
#import <Foundation/Foundation.h>
-// A GRXWriteable is an object to which a sequence of values can be sent. The
-// sequence finishes with an optional error.
+/**
+ * A GRXWriteable is an object to which a sequence of values can be sent. The
+ * sequence finishes with an optional error.
+ */
@protocol GRXWriteable <NSObject>
-// Push the next value of the sequence to the receiving object.
+/** Push the next value of the sequence to the receiving object. */
- (void)writeValue:(id)value;
-// Signal that the sequence is completed, or that an error ocurred. After this
-// message is sent to the instance, neither it nor writeValue: may be
-// called again.
+/**
+ * Signal that the sequence is completed, or that an error ocurred. After this
+ * message is sent to the instance, neither it nor writeValue: may be
+ * called again.
+ */
- (void)writesFinishedWithError:(NSError *)errorOrNil;
@end
@@ -51,8 +55,10 @@ typedef void (^GRXCompletionHandler)(NSError *errorOrNil);
typedef void (^GRXSingleHandler)(id value, NSError *errorOrNil);
typedef void (^GRXEventHandler)(BOOL done, id value, NSError *error);
-// Utility to create objects that conform to the GRXWriteable protocol, from
-// blocks that handle each of the two methods of the protocol.
+/**
+ * Utility to create objects that conform to the GRXWriteable protocol, from
+ * blocks that handle each of the two methods of the protocol.
+ */
@interface GRXWriteable : NSObject<GRXWriteable>
+ (instancetype)writeableWithSingleHandler:(GRXSingleHandler)handler;
diff --git a/src/objective-c/RxLibrary/GRXWriter+Immediate.h b/src/objective-c/RxLibrary/GRXWriter+Immediate.h
index b75c0a5a64..be880151f4 100644
--- a/src/objective-c/RxLibrary/GRXWriter+Immediate.h
+++ b/src/objective-c/RxLibrary/GRXWriter+Immediate.h
@@ -35,32 +35,44 @@
@interface GRXWriter (Immediate)
-// Returns a writer that pulls values from the passed NSEnumerator instance and pushes them to
-// its writeable. The NSEnumerator is released when it finishes.
+/**
+ * Returns a writer that pulls values from the passed NSEnumerator instance and pushes them to
+ * its writeable. The NSEnumerator is released when it finishes.
+ */
+ (instancetype)writerWithEnumerator:(NSEnumerator *)enumerator;
-// Returns a writer that pushes to its writeable the successive values returned by the passed
-// block. When the block first returns nil, it is released.
+/**
+ * Returns a writer that pushes to its writeable the successive values returned by the passed
+ * block. When the block first returns nil, it is released.
+ */
+ (instancetype)writerWithValueSupplier:(id (^)())block;
-// Returns a writer that iterates over the values of the passed container and pushes them to
-// its writeable. The container is released when the iteration is over.
-//
-// Note that the usual speed gain of NSFastEnumeration over NSEnumerator results from not having to
-// call one method per element. Because GRXWriteable instances accept values one by one, that speed
-// gain doesn't happen here.
+/**
+ * Returns a writer that iterates over the values of the passed container and pushes them to
+ * its writeable. The container is released when the iteration is over.
+ *
+ * Note that the usual speed gain of NSFastEnumeration over NSEnumerator results from not having to
+ * call one method per element. Because GRXWriteable instances accept values one by one, that speed
+ * gain doesn't happen here.
+ */
+ (instancetype)writerWithContainer:(id<NSFastEnumeration>)container;
-// Returns a writer that sends the passed value to its writeable and then finishes (releasing the
-// value).
+/**
+ * Returns a writer that sends the passed value to its writeable and then finishes (releasing the
+ * value).
+ */
+ (instancetype)writerWithValue:(id)value;
-// Returns a writer that, as part of its start method, sends the passed error to the writeable
-// (then releasing the error).
+/**
+ * Returns a writer that, as part of its start method, sends the passed error to the writeable
+ * (then releasing the error).
+ */
+ (instancetype)writerWithError:(NSError *)error;
-// Returns a writer that, as part of its start method, finishes immediately without sending any
-// values to its writeable.
+/**
+ * Returns a writer that, as part of its start method, finishes immediately without sending any
+ * values to its writeable.
+ */
+ (instancetype)emptyWriter;
@end
diff --git a/src/objective-c/RxLibrary/GRXWriter+Transformations.h b/src/objective-c/RxLibrary/GRXWriter+Transformations.h
index 60c4da37d6..17d61e7541 100644
--- a/src/objective-c/RxLibrary/GRXWriter+Transformations.h
+++ b/src/objective-c/RxLibrary/GRXWriter+Transformations.h
@@ -35,8 +35,10 @@
@interface GRXWriter (Transformations)
-// Returns a writer that wraps the receiver, and has all the values the receiver would write
-// transformed by the provided mapping function.
+/**
+ * Returns a writer that wraps the receiver, and has all the values the receiver would write
+ * transformed by the provided mapping function.
+ */
- (GRXWriter *)map:(id (^)(id value))map;
@end
diff --git a/src/objective-c/RxLibrary/GRXWriter.h b/src/objective-c/RxLibrary/GRXWriter.h
index b1c994aa38..ff81268446 100644
--- a/src/objective-c/RxLibrary/GRXWriter.h
+++ b/src/objective-c/RxLibrary/GRXWriter.h
@@ -35,73 +35,87 @@
#import "GRXWriteable.h"
-// States of a writer.
+/** States of a writer. */
typedef NS_ENUM(NSInteger, GRXWriterState) {
- // The writer has not yet been given a writeable to which it can push its values. To have a writer
- // transition to the Started state, send it a startWithWriteable: message.
- //
- // A writer's state cannot be manually set to this value.
+ /**
+ * The writer has not yet been given a writeable to which it can push its values. To have a writer
+ * transition to the Started state, send it a startWithWriteable: message.
+ *
+ * A writer's state cannot be manually set to this value.
+ */
GRXWriterStateNotStarted,
- // The writer might push values to the writeable at any moment.
+ /** The writer might push values to the writeable at any moment. */
GRXWriterStateStarted,
- // The writer is temporarily paused, and won't send any more values to the writeable unless its
- // state is set back to Started. The writer might still transition to the Finished state at any
- // moment, and is allowed to send writesFinishedWithError: to its writeable.
+ /**
+ * The writer is temporarily paused, and won't send any more values to the writeable unless its
+ * state is set back to Started. The writer might still transition to the Finished state at any
+ * moment, and is allowed to send writesFinishedWithError: to its writeable.
+ */
GRXWriterStatePaused,
- // The writer has released its writeable and won't interact with it anymore.
- //
- // One seldomly wants to set a writer's state to this value, as its writeable isn't notified with
- // a writesFinishedWithError: message. Instead, sending finishWithError: to the writer will make
- // it notify the writeable and then transition to this state.
+ /**
+ * The writer has released its writeable and won't interact with it anymore.
+ *
+ * One seldomly wants to set a writer's state to this value, as its writeable isn't notified with
+ * a writesFinishedWithError: message. Instead, sending finishWithError: to the writer will make
+ * it notify the writeable and then transition to this state.
+ */
GRXWriterStateFinished
};
-// An GRXWriter object can produce, on demand, a sequence of values. The sequence may be produced
-// asynchronously, and it may consist of any number of elements, including none or an infinite
-// number.
-//
-// GRXWriter is the active dual of NSEnumerator. The difference between them is thus whether the
-// object plays an active or passive role during usage: A user of NSEnumerator pulls values off it,
-// and passes the values to a writeable. A user of GRXWriter, though, just gives it a writeable, and
-// the GRXWriter instance pushes values to the writeable. This makes this protocol suitable to
-// represent a sequence of future values, as well as collections with internal iteration.
-//
-// An instance of GRXWriter can start producing values after a writeable is passed to it. It can
-// also be commanded to finish the sequence immediately (with an optional error). Finally, it can be
-// asked to pause, and resumed later. All GRXWriter objects support pausing and early termination.
-//
-// Thread-safety:
-//
-// State transitions take immediate effect if the object is used from a single thread. Subclasses
-// might offer stronger guarantees.
-//
-// Unless otherwise indicated by a conforming subclass, no messages should be sent concurrently to a
-// GRXWriter. I.e., conforming classes aren't required to be thread-safe.
+/**
+ * An GRXWriter object can produce, on demand, a sequence of values. The sequence may be produced
+ * asynchronously, and it may consist of any number of elements, including none or an infinite
+ * number.
+ *
+ * GRXWriter is the active dual of NSEnumerator. The difference between them is thus whether the
+ * object plays an active or passive role during usage: A user of NSEnumerator pulls values off it,
+ * and passes the values to a writeable. A user of GRXWriter, though, just gives it a writeable, and
+ * the GRXWriter instance pushes values to the writeable. This makes this protocol suitable to
+ * represent a sequence of future values, as well as collections with internal iteration.
+ *
+ * An instance of GRXWriter can start producing values after a writeable is passed to it. It can
+ * also be commanded to finish the sequence immediately (with an optional error). Finally, it can be
+ * asked to pause, and resumed later. All GRXWriter objects support pausing and early termination.
+ *
+ * Thread-safety:
+ *
+ * State transitions take immediate effect if the object is used from a single thread. Subclasses
+ * might offer stronger guarantees.
+ *
+ * Unless otherwise indicated by a conforming subclass, no messages should be sent concurrently to a
+ * GRXWriter. I.e., conforming classes aren't required to be thread-safe.
+ */
@interface GRXWriter : NSObject
-// This property can be used to query the current state of the writer, which determines how it might
-// currently use its writeable. Some state transitions can be triggered by setting this property to
-// the corresponding value, and that's useful for advanced use cases like pausing an writer. For
-// more details, see the documentation of the enum further down.
+/**
+ * This property can be used to query the current state of the writer, which determines how it might
+ * currently use its writeable. Some state transitions can be triggered by setting this property to
+ * the corresponding value, and that's useful for advanced use cases like pausing an writer. For
+ * more details, see the documentation of the enum further down.
+ */
@property(nonatomic) GRXWriterState state;
-// Transition to the Started state, and start sending messages to the writeable (a reference to it
-// is retained). Messages to the writeable may be sent before the method returns, or they may be
-// sent later in the future. See GRXWriteable.h for the different messages a writeable can receive.
-//
-// If this writer draws its values from an external source (e.g. from the filesystem or from a
-// server), calling this method will commonly trigger side effects (like network connections).
-//
-// This method might only be called on writers in the NotStarted state.
+/**
+ * Transition to the Started state, and start sending messages to the writeable (a reference to it
+ * is retained). Messages to the writeable may be sent before the method returns, or they may be
+ * sent later in the future. See GRXWriteable.h for the different messages a writeable can receive.
+ *
+ * If this writer draws its values from an external source (e.g. from the filesystem or from a
+ * server), calling this method will commonly trigger side effects (like network connections).
+ *
+ * This method might only be called on writers in the NotStarted state.
+ */
- (void)startWithWriteable:(id<GRXWriteable>)writeable;
-// Send writesFinishedWithError:errorOrNil to the writeable. Then release the reference to it and
-// transition to the Finished state.
-//
-// This method might only be called on writers in the Started or Paused state.
+/**
+ * Send writesFinishedWithError:errorOrNil to the writeable. Then release the reference to it and
+ * transition to the Finished state.
+ *
+ * This method might only be called on writers in the Started or Paused state.
+ */
- (void)finishWithError:(NSError *)errorOrNil;
@end
diff --git a/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h b/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h
index 400e834c6a..0622f7067c 100644
--- a/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h
+++ b/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h
@@ -35,17 +35,23 @@
@interface NSEnumerator (GRXUtil)
-// Returns a NSEnumerator instance that iterates through the elements of the passed container that
-// supports fast enumeration. Note that this negates the speed benefits of fast enumeration over
-// NSEnumerator. It's only intended for the rare cases when one needs the latter and only has the
-// former, e.g. for iteration that needs to be paused and resumed later.
+/**
+ * Returns a NSEnumerator instance that iterates through the elements of the passed container that
+ * supports fast enumeration. Note that this negates the speed benefits of fast enumeration over
+ * NSEnumerator. It's only intended for the rare cases when one needs the latter and only has the
+ * former, e.g. for iteration that needs to be paused and resumed later.
+ */
+ (NSEnumerator *)grx_enumeratorWithContainer:(id<NSFastEnumeration>)container;
-// Returns a NSEnumerator instance that provides a single object before finishing. The value is then
-// released.
+/**
+ * Returns a NSEnumerator instance that provides a single object before finishing. The value is then
+ * released.
+ */
+ (NSEnumerator *)grx_enumeratorWithSingleValue:(id)value;
-// Returns a NSEnumerator instance that delegates the invocations of nextObject to the passed block.
-// When the block first returns nil, it is released.
+/**
+ * Returns a NSEnumerator instance that delegates the invocations of nextObject to the passed block.
+ * When the block first returns nil, it is released.
+ */
+ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)())block;
@end
diff --git a/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h b/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h
index 34cfc4d8a7..fb50c37863 100644
--- a/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h
+++ b/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h
@@ -33,10 +33,14 @@
#import <Foundation/Foundation.h>
-// Concrete subclass of NSEnumerator that delegates the invocations of nextObject to a block passed
-// on initialization.
+/**
+ * Concrete subclass of NSEnumerator that delegates the invocations of nextObject to a block passed
+ * on initialization.
+ */
@interface GRXNSBlockEnumerator : NSEnumerator
-// The first time the passed block returns nil, the enumeration will end and the block will be
-// released.
+/**
+ * The first time the passed block returns nil, the enumeration will end and the block will be
+ * released.
+ */
- (instancetype)initWithValueSupplier:(id (^)())block;
@end
diff --git a/src/objective-c/RxLibrary/private/GRXNSFastEnumerator.h b/src/objective-c/RxLibrary/private/GRXNSFastEnumerator.h
index 1565029205..62c27dbc7f 100644
--- a/src/objective-c/RxLibrary/private/GRXNSFastEnumerator.h
+++ b/src/objective-c/RxLibrary/private/GRXNSFastEnumerator.h
@@ -33,11 +33,15 @@
#import <Foundation/Foundation.h>
-// This is a bridge to interact through NSEnumerator's interface with objects that only conform to
-// NSFastEnumeration. (There's nothing specifically fast about it - you certainly don't win any
-// speed by using this instead of a NSEnumerator provided by your container).
+/**
+ * This is a bridge to interact through NSEnumerator's interface with objects that only conform to
+ * NSFastEnumeration. (There's nothing specifically fast about it - you certainly don't win any
+ * speed by using this instead of a NSEnumerator provided by your container).
+ */
@interface GRXNSFastEnumerator : NSEnumerator
-// After the iteration of the container (via the NSFastEnumeration protocol) is over, the container
-// is released. If the container is modified during enumeration, an exception is thrown.
+/**
+ * After the iteration of the container (via the NSFastEnumeration protocol) is over, the container
+ * is released. If the container is modified during enumeration, an exception is thrown.
+ */
- (instancetype)initWithContainer:(id<NSFastEnumeration>)container;
@end
diff --git a/src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.h b/src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.h
index 12aa51e213..24a21a1b22 100644
--- a/src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.h
+++ b/src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.h
@@ -33,9 +33,11 @@
#import <Foundation/Foundation.h>
-// Concrete subclass of NSEnumerator whose instances return a single object before finishing.
+/** Concrete subclass of NSEnumerator whose instances return a single object before finishing. */
@interface GRXNSScalarEnumerator : NSEnumerator
-// Param value: the single object this instance will produce. After the first invocation of
-// nextObject, the value is released.
+/**
+ * Param value: the single object this instance will produce. After the first invocation of
+ * nextObject, the value is released.
+ */
- (instancetype)initWithValue:(id)value;
@end
diff --git a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h
index 43b8706864..01a15e2a43 100644
--- a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h
+++ b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h
@@ -33,7 +33,7 @@
#import "RxLibrary/GRXForwardingWriter.h"
-// A "proxy" writer that transforms all the values of its input writer by using a mapping function.
+/** A "proxy" writer that transforms all the values of its input writer by using a mapping function. */
@interface GRXMappingWriter : GRXForwardingWriter
- (instancetype)initWithWriter:(GRXWriter *)writer map:(id (^)(id value))map
NS_DESIGNATED_INITIALIZER;
diff --git a/src/objective-c/change-comments.py b/src/objective-c/change-comments.py
new file mode 100755
index 0000000000..9aa0e0c9f5
--- /dev/null
+++ b/src/objective-c/change-comments.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python2.7
+# 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.
+
+"""Change comments style of source files from // to /** */"""
+
+import re
+import sys
+
+
+if len(sys.argv) < 2:
+ print("Please provide at least one source file name as argument.")
+ sys.exit()
+
+for file_name in sys.argv[1:]:
+
+ print("Modifying format of {file} comments in place...".format(
+ file=file_name,
+ ))
+
+
+ # Input
+
+ with open(file_name, "r") as input_file:
+ lines = input_file.readlines()
+
+ def peek():
+ return lines[0]
+
+ def read_line():
+ return lines.pop(0)
+
+ def more_input_available():
+ return lines
+
+
+ # Output
+
+ output_lines = []
+
+ def write(line):
+ output_lines.append(line)
+
+ def flush_output():
+ with open(file_name, "w") as output_file:
+ for line in output_lines:
+ output_file.write(line)
+
+
+ # Pattern matching
+
+ comment_regex = r'^(\s*)//\s(.*)$'
+
+ def is_comment(line):
+ return re.search(comment_regex, line)
+
+ def isnt_comment(line):
+ return not is_comment(line)
+
+ def next_line(predicate):
+ return more_input_available() and predicate(peek())
+
+
+ # Transformation
+
+ def indentation_of(line):
+ match = re.search(comment_regex, line)
+ return match.group(1)
+
+ def content(line):
+ match = re.search(comment_regex, line)
+ return match.group(2)
+
+ def format_as_block(comment_block):
+ if len(comment_block) == 0:
+ return []
+
+ indent = indentation_of(comment_block[0])
+
+ if len(comment_block) == 1:
+ return [indent + "/** " + content(comment_block[0]) + " */\n"]
+
+ block = ["/**"] + [" * " + content(line) for line in comment_block] + [" */"]
+ return [indent + line.rstrip() + "\n" for line in block]
+
+
+ # Main algorithm
+
+ while more_input_available():
+ while next_line(isnt_comment):
+ write(read_line())
+
+ comment_block = []
+ # Get all lines in the same comment block. We could restrict the indentation
+ # to be the same as the first line of the block, but it's probably ok.
+ while (next_line(is_comment)):
+ comment_block.append(read_line())
+
+ for line in format_as_block(comment_block):
+ write(line)
+
+ flush_output()
diff --git a/src/python/grpcio_test/grpc_test/early_adopter/__init__.py b/src/objective-c/format-all-comments.sh
index 7086519106..e6b6b5a0b4 100644
--- a/src/python/grpcio_test/grpc_test/early_adopter/__init__.py
+++ b/src/objective-c/format-all-comments.sh
@@ -1,3 +1,4 @@
+#!/bin/bash
# Copyright 2015, Google Inc.
# All rights reserved.
#
@@ -27,4 +28,4 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+find . -type f -name "*.h" ! -path "*/Pods/*" ! -path "./generated_libraries/*" ! -path "./examples/*" ! -path "./tests/*" | xargs ./change-comments.py
diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m
index 09a55e0704..00c4b8830d 100644
--- a/src/objective-c/tests/GRPCClientTests.m
+++ b/src/objective-c/tests/GRPCClientTests.m
@@ -42,9 +42,6 @@
#import <RxLibrary/GRXWriteable.h>
#import <RxLibrary/GRXWriter+Immediate.h>
-// These are a few tests similar to InteropTests, but which use the generic gRPC client (GRPCCall)
-// rather than a generated proto library on top of it.
-
static NSString * const kHostAddress = @"localhost:5050";
static NSString * const kPackage = @"grpc.testing";
static NSString * const kService = @"TestService";
@@ -53,11 +50,10 @@ static ProtoMethod *kInexistentMethod;
static ProtoMethod *kEmptyCallMethod;
static ProtoMethod *kUnaryCallMethod;
-// This is an observer class for testing that responseMetadata is KVO-compliant
-
+/** Observer class for testing that responseMetadata is KVO-compliant */
@interface PassthroughObserver : NSObject
-
-- (instancetype) initWithCallback:(void (^)(NSString*, id, NSDictionary*))callback;
+- (instancetype) initWithCallback:(void (^)(NSString*, id, NSDictionary*))callback
+ NS_DESIGNATED_INITIALIZER;
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change
context:(void *)context;
@@ -67,23 +63,38 @@ static ProtoMethod *kUnaryCallMethod;
void (^_callback)(NSString*, id, NSDictionary*);
}
+- (instancetype)init {
+ return [self initWithCallback:nil];
+}
+
- (instancetype)initWithCallback:(void (^)(NSString *, id, NSDictionary *))callback {
- self = [super init];
- if (self) {
+ if (!callback) {
+ return nil;
+ }
+ if ((self = [super init])) {
_callback = callback;
}
return self;
-
}
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
-{
+- (void)observeValueForKeyPath:(NSString *)keyPath
+ ofObject:(id)object
+ change:(NSDictionary *)change
+ context:(void *)context {
_callback(keyPath, object, change);
[object removeObserver:self forKeyPath:keyPath];
}
@end
+# pragma mark Tests
+
+/**
+ * A few tests similar to InteropTests, but which use the generic gRPC client (GRPCCall) rather than
+ * a generated proto library on top of it. Its RPCs are sent to a local cleartext server.
+ *
+ * TODO(jcanizales): Run them also against a local SSL server and against a remote server.
+ */
@interface GRPCClientTests : XCTestCase
@end
@@ -180,6 +191,7 @@ static ProtoMethod *kUnaryCallMethod;
[self waitForExpectationsWithTimeout:8 handler:nil];
}
+// TODO(jcanizales): Activate this test against the remote server.
- (void)testMetadata {
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."];
diff --git a/src/objective-c/tests/InteropTests.h b/src/objective-c/tests/InteropTests.h
index 1045c3d124..6d54343b13 100644
--- a/src/objective-c/tests/InteropTests.h
+++ b/src/objective-c/tests/InteropTests.h
@@ -33,11 +33,17 @@
#import <XCTest/XCTest.h>
-// Implements tests as described here:
-// https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md
-
+/**
+ * Implements tests as described here:
+ * https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md
+ *
+ * This is an abstract class that needs to be subclassed. See |+host|.
+ */
@interface InteropTests : XCTestCase
-// Returns @"grpc-test.sandbox.google.com".
-// Override in a subclass to perform the same tests against a different address.
+/**
+ * Host to send the RPCs to. The base implementation returns nil, which would make all tests to
+ * fail.
+ * Override in a subclass to perform these tests against a specific address.
+ */
+ (NSString *)host;
@end
diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index af58e2bd04..26877b1ae8 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -78,21 +78,20 @@
#pragma mark Tests
-static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.google.com";
-
@implementation InteropTests {
RMTTestService *_service;
}
+ (NSString *)host {
- return kRemoteSSLHost;
+ return nil;
}
- (void)setUp {
- _service = [RMTTestService serviceWithHost:self.class.host];
+ _service = self.class.host ? [RMTTestService serviceWithHost:self.class.host] : nil;
}
- (void)testEmptyUnaryRPC {
+ XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"];
RMTEmpty *request = [RMTEmpty message];
@@ -110,6 +109,7 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.google.com";
}
- (void)testLargeUnaryRPC {
+ XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"];
RMTSimpleRequest *request = [RMTSimpleRequest message];
@@ -132,6 +132,7 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.google.com";
}
- (void)testClientStreamingRPC {
+ XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"ClientStreaming"];
RMTStreamingInputCallRequest *request1 = [RMTStreamingInputCallRequest message];
@@ -164,6 +165,7 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.google.com";
}
- (void)testServerStreamingRPC {
+ XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"ServerStreaming"];
NSArray *expectedSizes = @[@31415, @9, @2653, @58979];
@@ -200,6 +202,7 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.google.com";
}
- (void)testPingPongRPC {
+ XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
NSArray *requests = @[@27182, @8, @1828, @45904];
@@ -243,6 +246,7 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.google.com";
}
- (void)testEmptyStreamRPC {
+ XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"];
[_service fullDuplexCallWithRequestsWriter:[GRXWriter emptyWriter]
eventHandler:^(BOOL done,
@@ -256,6 +260,7 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.google.com";
}
- (void)testCancelAfterBeginRPC {
+ XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"];
// A buffered pipe to which we never write any value acts as a writer that just hangs.
@@ -273,6 +278,7 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.google.com";
}
- (void)testCancelAfterFirstResponseRPC {
+ XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterFirstResponse"];
// A buffered pipe to which we write a single value but never close
diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m
index 2d7d3c4b2c..56927a8af6 100644
--- a/src/objective-c/tests/InteropTestsLocalCleartext.m
+++ b/src/objective-c/tests/InteropTestsLocalCleartext.m
@@ -31,15 +31,13 @@
*
*/
-// Repeat of the tests in InteropTests.m, but sending the RPCs to a local cleartext server instead
-// of the remote SSL one.
-
#import <GRPCClient/GRPCCall+Tests.h>
#import "InteropTests.h"
static NSString * const kLocalCleartextHost = @"localhost:5050";
+/** Tests in InteropTests.m, sending the RPCs to a local cleartext server. */
@interface InteropTestsLocalCleartext : InteropTests
@end
diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m
index f69f806dcf..9d7afefbfe 100644
--- a/src/objective-c/tests/InteropTestsLocalSSL.m
+++ b/src/objective-c/tests/InteropTestsLocalSSL.m
@@ -31,15 +31,13 @@
*
*/
-// Repeat of the tests in InteropTests.m, but sending the RPCs to a local SSL server instead of the
-// remote one.
-
#import <GRPCClient/GRPCCall+Tests.h>
#import "InteropTests.h"
static NSString * const kLocalSSLHost = @"localhost:5051";
+/** Tests in InteropTests.m, sending the RPCs to a local SSL server. */
@interface InteropTestsLocalSSL : InteropTests
@end
diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m
new file mode 100644
index 0000000000..a67be98431
--- /dev/null
+++ b/src/objective-c/tests/InteropTestsRemote.m
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#import <GRPCClient/GRPCCall+Tests.h>
+
+#import "InteropTests.h"
+
+static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.google.com";
+
+/** Tests in InteropTests.m, sending the RPCs to a remote SSL server. */
+@interface InteropTestsRemote : InteropTests
+@end
+
+@implementation InteropTestsRemote
+
++ (NSString *)host {
+ return kRemoteSSLHost;
+}
+
+@end
diff --git a/src/objective-c/tests/LocalClearTextTests.m b/src/objective-c/tests/LocalClearTextTests.m
deleted file mode 100644
index 976fff55bc..0000000000
--- a/src/objective-c/tests/LocalClearTextTests.m
+++ /dev/null
@@ -1,164 +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.
- *
- */
-
-#import <UIKit/UIKit.h>
-#import <XCTest/XCTest.h>
-
-#import <GRPCClient/GRPCCall.h>
-#import <ProtoRPC/ProtoMethod.h>
-#import <RouteGuide/RouteGuide.pbobjc.h>
-#import <RouteGuide/RouteGuide.pbrpc.h>
-#import <RxLibrary/GRXWriteable.h>
-#import <RxLibrary/GRXWriter+Immediate.h>
-
-// These tests require a gRPC "RouteGuide" sample server to be running locally. You can compile and
-// run one by following the instructions here: https://github.com/grpc/grpc/blob/master/examples/cpp/cpptutorial.md#try-it-out
-// Be sure to have the C gRPC library installed in your system (for example, by having followed the
-// instructions at https://github.com/grpc/homebrew-grpc
-
-static NSString * const kRouteGuideHost = @"http://localhost:50051";
-static NSString * const kPackage = @"routeguide";
-static NSString * const kService = @"RouteGuide";
-
-@interface LocalClearTextTests : XCTestCase
-@end
-
-@implementation LocalClearTextTests
-
-// This test currently fails: see Issue #1907.
-//- (void)testConnectionToLocalServer {
-// __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Server reachable."];
-//
-// // This method isn't implemented by the local server.
-// GRPCMethodName *method = [[GRPCMethodName alloc] initWithPackage:kPackage
-// interface:kService
-// method:@"EmptyCall"];
-//
-// GRXWriter *requestsWriter = [GRXWriter writerWithValue:[NSData data]];
-//
-// GRPCCall *call = [[GRPCCall alloc] initWithHost:kRouteGuideHost
-// method:method
-// requestsWriter:requestsWriter];
-//
-// id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
-// XCTFail(@"Received unexpected response: %@", value);
-// } completionHandler:^(NSError *errorOrNil) {
-// XCTAssertNotNil(errorOrNil, @"Finished without error!");
-// XCTAssertEqual(errorOrNil.code, 12, @"Finished with unexpected error: %@", errorOrNil);
-// [expectation fulfill];
-// }];
-//
-// [call startWithWriteable:responsesWriteable];
-//
-// [self waitForExpectationsWithTimeout:8.0 handler:nil];
-//}
-
-- (void)testEmptyRPC {
- __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
- __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
-
- ProtoMethod *method = [[ProtoMethod alloc] initWithPackage:kPackage
- service:kService
- method:@"RecordRoute"];
-
- GRXWriter *requestsWriter = [GRXWriter emptyWriter];
-
- GRPCCall *call = [[GRPCCall alloc] initWithHost:kRouteGuideHost
- path:method.HTTPPath
- requestsWriter:requestsWriter];
-
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTAssertNotNil(value, @"nil value received as response.");
- XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
- [response fulfill];
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
- [completion fulfill];
- }];
-
- [call startWithWriteable:responsesWriteable];
-
- [self waitForExpectationsWithTimeout:2.0 handler:nil];
-}
-
-- (void)testSimpleProtoRPC {
- __weak XCTestExpectation *response = [self expectationWithDescription:@"Response received."];
- __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."];
-
- ProtoMethod *method = [[ProtoMethod alloc] initWithPackage:kPackage
- service:kService
- method:@"GetFeature"];
-
- RGDPoint *point = [RGDPoint message];
- point.latitude = 28E7;
- point.longitude = -15E7;
- GRXWriter *requestsWriter = [GRXWriter writerWithValue:[point data]];
-
- GRPCCall *call = [[GRPCCall alloc] initWithHost:kRouteGuideHost
- path:method.HTTPPath
- requestsWriter:requestsWriter];
-
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTAssertNotNil(value, @"nil value received as response.");
- RGDFeature *feature = [RGDFeature parseFromData:value error:NULL];
- XCTAssertEqualObjects(point, feature.location);
- XCTAssertNotNil(feature.name, @"Response's name is nil.");
- [response fulfill];
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
- [completion fulfill];
- }];
-
- [call startWithWriteable:responsesWriteable];
-
- [self waitForExpectationsWithTimeout:2.0 handler:nil];
-}
-
-- (void)testSimpleProtoRPCUsingGeneratedService {
- __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."];
-
- RGDPoint *point = [RGDPoint message];
- point.latitude = 28E7;
- point.longitude = -15E7;
-
- RGDRouteGuide *service = [[RGDRouteGuide alloc] initWithHost:kRouteGuideHost];
- [service getFeatureWithRequest:point handler:^(RGDFeature *response, NSError *error) {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- XCTAssertEqualObjects(point, response.location);
- XCTAssertNotNil(response.name, @"Response's name is nil.");
- [completion fulfill];
- }];
-
- [self waitForExpectationsWithTimeout:2.0 handler:nil];
-}
-@end
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index 2aa837f764..2a9b894cf6 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -6,10 +6,26 @@ pod 'gRPC', :path => "../../.."
pod 'RemoteTest', :path => "../generated_libraries/RemoteTestClient"
pod 'RouteGuide', :path => "../generated_libraries/RouteGuideClient"
-link_with 'AllTests'
+link_with 'AllTests',
+ 'RxLibraryUnitTests',
+ 'InteropTests',
+ 'InteropTestsLocalSSL',
+ 'InteropTestsLocalCleartext'
target 'Tests' do
end
target 'AllTests' do
end
+
+target 'RxLibraryUnitTests' do
+end
+
+target 'InteropTestsRemote' do
+end
+
+target 'InteropTestsLocalSSL' do
+end
+
+target 'InteropTestsLocalCleartext' do
+end
diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
index 3a1c3d940a..b0429617c0 100644
--- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
+++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
@@ -7,16 +7,33 @@
objects = {
/* Begin PBXBuildFile section */
+ 036D953EE34B1FD523647ACD /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
+ 08A8BB02D19A53D902B214B8 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
+ 50267643BA114A2A724D4FDF /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; };
- 63175DFF1B1B9FAF00027841 /* LocalClearTextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63175DFE1B1B9FAF00027841 /* LocalClearTextTests.m */; };
63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
- 63423F511B151B77006CF63C /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; };
635697CD1B14FC11007A7283 /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635697CC1B14FC11007A7283 /* Tests.m */; };
635ED2EC1B1A3BC400FDE5C3 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
63715F561B780C020029CB0B /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; };
+ 6379CC4D1BE1662A001BC0A1 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; settings = {ASSET_TAGS = (); }; };
+ 6379CC4E1BE1662B001BC0A1 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; settings = {ASSET_TAGS = (); }; };
+ 6379CC501BE16703001BC0A1 /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; settings = {ASSET_TAGS = (); }; };
+ 6379CC511BE1683B001BC0A1 /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; settings = {ASSET_TAGS = (); }; };
+ 6379CC531BE17709001BC0A1 /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; settings = {ASSET_TAGS = (); }; };
+ 63DC84181BE15179000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; settings = {ASSET_TAGS = (); }; };
+ 63DC841E1BE15180000708E8 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; settings = {ASSET_TAGS = (); }; };
+ 63DC84281BE15267000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; settings = {ASSET_TAGS = (); }; };
+ 63DC842E1BE15278000708E8 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; settings = {ASSET_TAGS = (); }; };
+ 63DC842F1BE1527D000708E8 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; settings = {ASSET_TAGS = (); }; };
+ 63DC84391BE15294000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; settings = {ASSET_TAGS = (); }; };
+ 63DC84481BE152B5000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; settings = {ASSET_TAGS = (); }; };
+ 63DC844E1BE15350000708E8 /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; settings = {ASSET_TAGS = (); }; };
+ 63DC844F1BE15353000708E8 /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; settings = {ASSET_TAGS = (); }; };
+ 63DC84501BE153AA000708E8 /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; settings = {ASSET_TAGS = (); }; };
63E240CE1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; };
63E240D01B6C63DC005F3B0E /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; };
7D8A186224D39101F90230F6 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
+ DCFAE001609CCBFE69DFA6A1 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -27,6 +44,34 @@
remoteGlobalIDString = 635697C61B14FC11007A7283;
remoteInfo = Tests;
};
+ 63DC84191BE15179000708E8 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 635697BF1B14FC11007A7283 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 635697C61B14FC11007A7283;
+ remoteInfo = Tests;
+ };
+ 63DC84291BE15267000708E8 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 635697BF1B14FC11007A7283 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 635697C61B14FC11007A7283;
+ remoteInfo = Tests;
+ };
+ 63DC843A1BE15294000708E8 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 635697BF1B14FC11007A7283 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 635697C61B14FC11007A7283;
+ remoteInfo = Tests;
+ };
+ 63DC84491BE152B5000708E8 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 635697BF1B14FC11007A7283 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 635697C61B14FC11007A7283;
+ remoteInfo = Tests;
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -45,7 +90,6 @@
0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = "<group>"; };
- 63175DFE1B1B9FAF00027841 /* LocalClearTextTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LocalClearTextTests.m; sourceTree = "<group>"; };
63423F441B150A5F006CF63C /* AllTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AllTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
63423F501B151B77006CF63C /* RxLibraryUnitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLibraryUnitTests.m; sourceTree = "<group>"; };
635697C71B14FC11007A7283 /* libTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTests.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -53,6 +97,11 @@
635697D81B14FC11007A7283 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTests.m; sourceTree = "<group>"; };
63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsLocalCleartext.m; sourceTree = "<group>"; };
+ 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsRemote.m; sourceTree = "<group>"; };
+ 63DC84131BE15179000708E8 /* RxLibraryUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RxLibraryUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 63DC84231BE15267000708E8 /* InteropTestsRemote.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemote.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 63DC84341BE15294000708E8 /* InteropTestsLocalSSL.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalSSL.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 63DC84431BE152B5000708E8 /* InteropTestsLocalCleartext.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalCleartext.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
63E240CC1B6C4D3A005F3B0E /* InteropTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InteropTests.h; sourceTree = "<group>"; };
63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsLocalSSL.m; sourceTree = "<group>"; };
63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TestCertificates.bundle; sourceTree = "<group>"; };
@@ -76,6 +125,42 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 63DC84101BE15179000708E8 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63DC84181BE15179000708E8 /* libTests.a in Frameworks */,
+ 036D953EE34B1FD523647ACD /* libPods.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 63DC84201BE15267000708E8 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63DC84281BE15267000708E8 /* libTests.a in Frameworks */,
+ DCFAE001609CCBFE69DFA6A1 /* libPods.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 63DC84311BE15294000708E8 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63DC84391BE15294000708E8 /* libTests.a in Frameworks */,
+ 08A8BB02D19A53D902B214B8 /* libPods.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 63DC84401BE152B5000708E8 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63DC84481BE152B5000708E8 /* libTests.a in Frameworks */,
+ 50267643BA114A2A724D4FDF /* libPods.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -112,6 +197,10 @@
children = (
635697C71B14FC11007A7283 /* libTests.a */,
63423F441B150A5F006CF63C /* AllTests.xctest */,
+ 63DC84131BE15179000708E8 /* RxLibraryUnitTests.xctest */,
+ 63DC84231BE15267000708E8 /* InteropTestsRemote.xctest */,
+ 63DC84341BE15294000708E8 /* InteropTestsLocalSSL.xctest */,
+ 63DC84431BE152B5000708E8 /* InteropTestsLocalCleartext.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -122,10 +211,10 @@
6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */,
63E240CC1B6C4D3A005F3B0E /* InteropTests.h */,
635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */,
+ 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */,
63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */,
63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */,
63423F501B151B77006CF63C /* RxLibraryUnitTests.m */,
- 63175DFE1B1B9FAF00027841 /* LocalClearTextTests.m */,
635697CC1B14FC11007A7283 /* Tests.m */,
635697D71B14FC11007A7283 /* Supporting Files */,
);
@@ -152,6 +241,7 @@
63423F411B150A5F006CF63C /* Frameworks */,
63423F421B150A5F006CF63C /* Resources */,
A441F71824DCB9D0CA297748 /* Copy Pods Resources */,
+ 5F14F59509E10C2852014F9E /* Embed Pods Frameworks */,
);
buildRules = (
);
@@ -180,6 +270,90 @@
productReference = 635697C71B14FC11007A7283 /* libTests.a */;
productType = "com.apple.product-type.library.static";
};
+ 63DC84121BE15179000708E8 /* RxLibraryUnitTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 63DC841B1BE15179000708E8 /* Build configuration list for PBXNativeTarget "RxLibraryUnitTests" */;
+ buildPhases = (
+ B2986CEEE8CDD4901C97598B /* Check Pods Manifest.lock */,
+ 63DC840F1BE15179000708E8 /* Sources */,
+ 63DC84101BE15179000708E8 /* Frameworks */,
+ 63DC84111BE15179000708E8 /* Resources */,
+ 4F5690DC0E6AD6663FE78B8B /* Embed Pods Frameworks */,
+ C977426A8727267BBAC7D48E /* Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 63DC841A1BE15179000708E8 /* PBXTargetDependency */,
+ );
+ name = RxLibraryUnitTests;
+ productName = RxLibraryUnitTests;
+ productReference = 63DC84131BE15179000708E8 /* RxLibraryUnitTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 63DC84221BE15267000708E8 /* InteropTestsRemote */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 63DC842B1BE15267000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsRemote" */;
+ buildPhases = (
+ 4C406327D3907A5E5FBA8AC9 /* Check Pods Manifest.lock */,
+ 63DC841F1BE15267000708E8 /* Sources */,
+ 63DC84201BE15267000708E8 /* Frameworks */,
+ 63DC84211BE15267000708E8 /* Resources */,
+ 900B6EDD4D16BE7D765C3885 /* Embed Pods Frameworks */,
+ C2E09DC4BD239F71160F0CC1 /* Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 63DC842A1BE15267000708E8 /* PBXTargetDependency */,
+ );
+ name = InteropTestsRemote;
+ productName = InteropTests;
+ productReference = 63DC84231BE15267000708E8 /* InteropTestsRemote.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 63DC84331BE15294000708E8 /* InteropTestsLocalSSL */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 63DC843C1BE15294000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSL" */;
+ buildPhases = (
+ 5C20DCCB71C3991E6FE78C22 /* Check Pods Manifest.lock */,
+ 63DC84301BE15294000708E8 /* Sources */,
+ 63DC84311BE15294000708E8 /* Frameworks */,
+ 63DC84321BE15294000708E8 /* Resources */,
+ C591129ACE9F6CC5EE03FCDE /* Embed Pods Frameworks */,
+ 693DD0B453431D64EA24FD66 /* Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 63DC843B1BE15294000708E8 /* PBXTargetDependency */,
+ );
+ name = InteropTestsLocalSSL;
+ productName = InteropTestsLocalSSL;
+ productReference = 63DC84341BE15294000708E8 /* InteropTestsLocalSSL.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 63DC84421BE152B5000708E8 /* InteropTestsLocalCleartext */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 63DC844B1BE152B5000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartext" */;
+ buildPhases = (
+ 7418AC7B3844B29E48D24FC7 /* Check Pods Manifest.lock */,
+ 63DC843F1BE152B5000708E8 /* Sources */,
+ 63DC84401BE152B5000708E8 /* Frameworks */,
+ 63DC84411BE152B5000708E8 /* Resources */,
+ A8E3AC66DF770B774114A30E /* Embed Pods Frameworks */,
+ 8AD3130D3C58A0FB32FF2A36 /* Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 63DC844A1BE152B5000708E8 /* PBXTargetDependency */,
+ );
+ name = InteropTestsLocalCleartext;
+ productName = InteropTestsLocalCleartext;
+ productReference = 63DC84431BE152B5000708E8 /* InteropTestsLocalCleartext.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -195,6 +369,18 @@
635697C61B14FC11007A7283 = {
CreatedOnToolsVersion = 6.3.1;
};
+ 63DC84121BE15179000708E8 = {
+ CreatedOnToolsVersion = 7.0.1;
+ };
+ 63DC84221BE15267000708E8 = {
+ CreatedOnToolsVersion = 7.0.1;
+ };
+ 63DC84331BE15294000708E8 = {
+ CreatedOnToolsVersion = 7.0.1;
+ };
+ 63DC84421BE152B5000708E8 = {
+ CreatedOnToolsVersion = 7.0.1;
+ };
};
};
buildConfigurationList = 635697C21B14FC11007A7283 /* Build configuration list for PBXProject "Tests" */;
@@ -211,6 +397,10 @@
targets = (
635697C61B14FC11007A7283 /* Tests */,
63423F431B150A5F006CF63C /* AllTests */,
+ 63DC84121BE15179000708E8 /* RxLibraryUnitTests */,
+ 63DC84221BE15267000708E8 /* InteropTestsRemote */,
+ 63DC84331BE15294000708E8 /* InteropTestsLocalSSL */,
+ 63DC84421BE152B5000708E8 /* InteropTestsLocalCleartext */,
);
};
/* End PBXProject section */
@@ -224,9 +414,158 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 63DC84111BE15179000708E8 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 63DC84211BE15267000708E8 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 63DC84321BE15294000708E8 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 6379CC531BE17709001BC0A1 /* TestCertificates.bundle in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 63DC84411BE152B5000708E8 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
+ 4C406327D3907A5E5FBA8AC9 /* Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ 4F5690DC0E6AD6663FE78B8B /* Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 5C20DCCB71C3991E6FE78C22 /* Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ 5F14F59509E10C2852014F9E /* Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 693DD0B453431D64EA24FD66 /* Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 7418AC7B3844B29E48D24FC7 /* Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ 8AD3130D3C58A0FB32FF2A36 /* Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 900B6EDD4D16BE7D765C3885 /* Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
914ADDD7106BA9BB8A7E569F /* Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -257,6 +596,81 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
showEnvVarsInLog = 0;
};
+ A8E3AC66DF770B774114A30E /* Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ B2986CEEE8CDD4901C97598B /* Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ C2E09DC4BD239F71160F0CC1 /* Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ C591129ACE9F6CC5EE03FCDE /* Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ C977426A8727267BBAC7D48E /* Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -265,11 +679,11 @@
buildActionMask = 2147483647;
files = (
63715F561B780C020029CB0B /* InteropTestsLocalCleartext.m in Sources */,
- 63175DFF1B1B9FAF00027841 /* LocalClearTextTests.m in Sources */,
- 63423F511B151B77006CF63C /* RxLibraryUnitTests.m in Sources */,
+ 6379CC511BE1683B001BC0A1 /* InteropTestsRemote.m in Sources */,
63E240CE1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m in Sources */,
6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */,
635ED2EC1B1A3BC400FDE5C3 /* InteropTests.m in Sources */,
+ 63DC842E1BE15278000708E8 /* RxLibraryUnitTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -281,6 +695,42 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 63DC840F1BE15179000708E8 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63DC841E1BE15180000708E8 /* RxLibraryUnitTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 63DC841F1BE15267000708E8 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63DC842F1BE1527D000708E8 /* InteropTests.m in Sources */,
+ 6379CC501BE16703001BC0A1 /* InteropTestsRemote.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 63DC84301BE15294000708E8 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63DC844F1BE15353000708E8 /* InteropTestsLocalSSL.m in Sources */,
+ 6379CC4D1BE1662A001BC0A1 /* InteropTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 63DC843F1BE152B5000708E8 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63DC84501BE153AA000708E8 /* GRPCClientTests.m in Sources */,
+ 63DC844E1BE15350000708E8 /* InteropTestsLocalCleartext.m in Sources */,
+ 6379CC4E1BE1662B001BC0A1 /* InteropTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
@@ -289,6 +739,26 @@
target = 635697C61B14FC11007A7283 /* Tests */;
targetProxy = 63423F4B1B150A5F006CF63C /* PBXContainerItemProxy */;
};
+ 63DC841A1BE15179000708E8 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 635697C61B14FC11007A7283 /* Tests */;
+ targetProxy = 63DC84191BE15179000708E8 /* PBXContainerItemProxy */;
+ };
+ 63DC842A1BE15267000708E8 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 635697C61B14FC11007A7283 /* Tests */;
+ targetProxy = 63DC84291BE15267000708E8 /* PBXContainerItemProxy */;
+ };
+ 63DC843B1BE15294000708E8 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 635697C61B14FC11007A7283 /* Tests */;
+ targetProxy = 63DC843A1BE15294000708E8 /* PBXContainerItemProxy */;
+ };
+ 63DC844A1BE152B5000708E8 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 635697C61B14FC11007A7283 /* Tests */;
+ targetProxy = 63DC84491BE152B5000708E8 /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
@@ -418,6 +888,110 @@
};
name = Release;
};
+ 63DC841C1BE15179000708E8 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_TESTABILITY = YES;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.RxLibraryUnitTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 63DC841D1BE15179000708E8 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */;
+ buildSettings = {
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.RxLibraryUnitTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+ 63DC842C1BE15267000708E8 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_TESTABILITY = YES;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 63DC842D1BE15267000708E8 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */;
+ buildSettings = {
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+ 63DC843D1BE15294000708E8 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_TESTABILITY = YES;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSL;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 63DC843E1BE15294000708E8 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */;
+ buildSettings = {
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSL;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+ 63DC844C1BE152B5000708E8 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_TESTABILITY = YES;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartext;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 63DC844D1BE152B5000708E8 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */;
+ buildSettings = {
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartext;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -448,6 +1022,42 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 63DC841B1BE15179000708E8 /* Build configuration list for PBXNativeTarget "RxLibraryUnitTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 63DC841C1BE15179000708E8 /* Debug */,
+ 63DC841D1BE15179000708E8 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 63DC842B1BE15267000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsRemote" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 63DC842C1BE15267000708E8 /* Debug */,
+ 63DC842D1BE15267000708E8 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 63DC843C1BE15294000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSL" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 63DC843D1BE15294000708E8 /* Debug */,
+ 63DC843E1BE15294000708E8 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 63DC844B1BE152B5000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartext" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 63DC844C1BE152B5000708E8 /* Debug */,
+ 63DC844D1BE152B5000708E8 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = 635697BF1B14FC11007A7283 /* Project object */;
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme
index a7e0ed110e..e6a052a8ce 100644
--- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme
@@ -23,10 +23,10 @@
</BuildActionEntries>
</BuildAction>
<TestAction
+ buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES"
- buildConfiguration = "Debug">
+ shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
@@ -45,6 +45,9 @@
Identifier = "GRPCClientTests/testMetadata">
</Test>
<Test
+ Identifier = "InteropTests">
+ </Test>
+ <Test
Identifier = "LocalClearTextTests">
</Test>
<Test
@@ -62,15 +65,18 @@
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
</TestAction>
<LaunchAction
+ buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
- buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
@@ -85,10 +91,10 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
+ buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
- buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme
new file mode 100644
index 0000000000..ce358bf69f
--- /dev/null
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0700"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "NO"
+ buildForArchiving = "NO"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84421BE152B5000708E8"
+ BuildableName = "InteropTestsLocalCleartext.xctest"
+ BlueprintName = "InteropTestsLocalCleartext"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84421BE152B5000708E8"
+ BuildableName = "InteropTestsLocalCleartext.xctest"
+ BlueprintName = "InteropTestsLocalCleartext"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ <SkippedTests>
+ <Test
+ Identifier = "GRPCClientTests/testConnectionToRemoteServer">
+ </Test>
+ <Test
+ Identifier = "GRPCClientTests/testMetadata">
+ </Test>
+ <Test
+ Identifier = "InteropTests">
+ </Test>
+ </SkippedTests>
+ </TestableReference>
+ </Testables>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84421BE152B5000708E8"
+ BuildableName = "InteropTestsLocalCleartext.xctest"
+ BlueprintName = "InteropTestsLocalCleartext"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84421BE152B5000708E8"
+ BuildableName = "InteropTestsLocalCleartext.xctest"
+ BlueprintName = "InteropTestsLocalCleartext"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme
new file mode 100644
index 0000000000..f268da1fb0
--- /dev/null
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0700"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "NO"
+ buildForArchiving = "NO"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84331BE15294000708E8"
+ BuildableName = "InteropTestsLocalSSL.xctest"
+ BlueprintName = "InteropTestsLocalSSL"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84331BE15294000708E8"
+ BuildableName = "InteropTestsLocalSSL.xctest"
+ BlueprintName = "InteropTestsLocalSSL"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ <SkippedTests>
+ <Test
+ Identifier = "InteropTests">
+ </Test>
+ </SkippedTests>
+ </TestableReference>
+ </Testables>
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84331BE15294000708E8"
+ BuildableName = "InteropTestsLocalSSL.xctest"
+ BlueprintName = "InteropTestsLocalSSL"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84331BE15294000708E8"
+ BuildableName = "InteropTestsLocalSSL.xctest"
+ BlueprintName = "InteropTestsLocalSSL"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme
new file mode 100644
index 0000000000..186d7208e0
--- /dev/null
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0700"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "NO"
+ buildForArchiving = "NO"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84221BE15267000708E8"
+ BuildableName = "InteropTestsRemote.xctest"
+ BlueprintName = "InteropTestsRemote"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84221BE15267000708E8"
+ BuildableName = "InteropTestsRemote.xctest"
+ BlueprintName = "InteropTestsRemote"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ <SkippedTests>
+ <Test
+ Identifier = "InteropTests">
+ </Test>
+ </SkippedTests>
+ </TestableReference>
+ </Testables>
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84221BE15267000708E8"
+ BuildableName = "InteropTestsRemote.xctest"
+ BlueprintName = "InteropTestsRemote"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84221BE15267000708E8"
+ BuildableName = "InteropTestsRemote.xctest"
+ BlueprintName = "InteropTestsRemote"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/RxLibraryUnitTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/RxLibraryUnitTests.xcscheme
new file mode 100644
index 0000000000..3abc1d42e4
--- /dev/null
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/RxLibraryUnitTests.xcscheme
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0700"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "NO"
+ buildForArchiving = "NO"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84121BE15179000708E8"
+ BuildableName = "RxLibraryUnitTests.xctest"
+ BlueprintName = "RxLibraryUnitTests"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84121BE15179000708E8"
+ BuildableName = "RxLibraryUnitTests.xctest"
+ BlueprintName = "RxLibraryUnitTests"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84121BE15179000708E8"
+ BuildableName = "RxLibraryUnitTests.xctest"
+ BlueprintName = "RxLibraryUnitTests"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "63DC84121BE15179000708E8"
+ BuildableName = "RxLibraryUnitTests.xctest"
+ BlueprintName = "RxLibraryUnitTests"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/src/php/README.md b/src/php/README.md
index a054258782..b1823b9226 100644
--- a/src/php/README.md
+++ b/src/php/README.md
@@ -14,18 +14,21 @@ Prerequisite: PHP 5.5 or later, `phpunit`, `pecl`
**Linux:**
```sh
-$ sudo apt-get install php5 php5-dev phpunit php-pear
+$ sudo apt-get install php5 php5-dev php-pear
```
**Mac OS X:**
```sh
+$ curl -O http://pear.php.net/go-pear.phar
+$ sudo php -d detect_unicode=0 go-pear.phar
+```
+
+**PHPUnit: (Both Linux and Mac OS X)**
+```sh
$ curl https://phar.phpunit.de/phpunit.phar -o phpunit.phar
$ chmod +x phpunit.phar
$ sudo mv phpunit.phar /usr/local/bin/phpunit
-
-$ curl -O http://pear.php.net/go-pear.phar
-$ sudo php -d detect_unicode=0 go-pear.phar
```
## Quick Install
diff --git a/src/php/bin/run_gen_code_test.sh b/src/php/bin/run_gen_code_test.sh
index 5dfebb42b6..1c18756ed2 100755
--- a/src/php/bin/run_gen_code_test.sh
+++ b/src/php/bin/run_gen_code_test.sh
@@ -32,7 +32,7 @@ set -e
cd $(dirname $0)
source ./determine_extension_dir.sh
export GRPC_TEST_HOST=localhost:50051
-php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug --strict \
+php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \
../tests/generated_code/GeneratedCodeTest.php
-php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug --strict \
+php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \
../tests/generated_code/GeneratedCodeWithCallbackTest.php
diff --git a/src/python/grpcio_test/grpc_test/framework/base/__init__.py b/src/php/bin/run_php_cs_fixer.sh
index 7086519106..3e11a12bc1 100644..100755
--- a/src/python/grpcio_test/grpc_test/framework/base/__init__.py
+++ b/src/php/bin/run_php_cs_fixer.sh
@@ -1,3 +1,4 @@
+#!/bin/bash
# Copyright 2015, Google Inc.
# All rights reserved.
#
@@ -27,4 +28,13 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+set -e
+command -v php-cs-fixer > /dev/null || {
+ echo "Cannot find php-cs-fixer. Exiting..."
+ exit 1
+}
+cd $(dirname $0)/..
+php-cs-fixer fix lib/Grpc || true
+php-cs-fixer fix tests/generated_code || true
+php-cs-fixer fix tests/interop || true
+php-cs-fixer fix tests/unit_tests || true
diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh
index 5adc77879a..2a7335e20a 100755
--- a/src/php/bin/run_tests.sh
+++ b/src/php/bin/run_tests.sh
@@ -37,5 +37,5 @@ cd src/php/bin
source ./determine_extension_dir.sh
# in some jenkins macos machine, somehow the PHP build script can't find libgrpc.dylib
export DYLD_LIBRARY_PATH=$root/libs/$config
-php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug --strict \
+php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \
../tests/unit_tests
diff --git a/src/php/ext/grpc/credentials.c b/src/php/ext/grpc/credentials.c
index 8e3b7ff212..e413070b45 100644
--- a/src/php/ext/grpc/credentials.c
+++ b/src/php/ext/grpc/credentials.c
@@ -111,21 +111,21 @@ PHP_METHOD(Credentials, createDefault) {
* @return Credentials The new SSL credentials object
*/
PHP_METHOD(Credentials, createSsl) {
- char *pem_root_certs;
+ char *pem_root_certs = NULL;
grpc_ssl_pem_key_cert_pair pem_key_cert_pair;
- int root_certs_length, private_key_length = 0, cert_chain_length = 0;
+ int root_certs_length = 0, private_key_length = 0, cert_chain_length = 0;
pem_key_cert_pair.private_key = pem_key_cert_pair.cert_chain = NULL;
- /* "s|s!s! == 1 string, 2 optional nullable strings */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!s!",
+ /* "|s!s!s! == 3 optional nullable strings */
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!",
&pem_root_certs, &root_certs_length,
&pem_key_cert_pair.private_key, &private_key_length,
&pem_key_cert_pair.cert_chain,
&cert_chain_length) == FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException,
- "createSsl expects 1 to 3 strings", 1 TSRMLS_CC);
+ "createSsl expects 3 optional strings", 1 TSRMLS_CC);
return;
}
grpc_credentials *creds = grpc_ssl_credentials_create(
diff --git a/src/php/lib/Grpc/AbstractCall.php b/src/php/lib/Grpc/AbstractCall.php
index a3c7a9e017..53849d51fc 100644
--- a/src/php/lib/Grpc/AbstractCall.php
+++ b/src/php/lib/Grpc/AbstractCall.php
@@ -31,65 +31,79 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+
namespace Grpc;
-abstract class AbstractCall {
+abstract class AbstractCall
+{
+ protected $call;
+ protected $deserialize;
+ protected $metadata;
- protected $call;
- protected $deserialize;
- protected $metadata;
+ /**
+ * Create a new Call wrapper object.
+ *
+ * @param Channel $channel The channel to communicate on
+ * @param string $method The method to call on the
+ * remote server
+ * @param callback $deserialize A callback function to deserialize
+ * the response
+ * @param (optional) long $timeout Timeout in microseconds
+ */
+ public function __construct(Channel $channel,
+ $method,
+ $deserialize,
+ $timeout = false)
+ {
+ if ($timeout) {
+ $now = Timeval::now();
+ $delta = new Timeval($timeout);
+ $deadline = $now->add($delta);
+ } else {
+ $deadline = Timeval::infFuture();
+ }
+ $this->call = new Call($channel, $method, $deadline);
+ $this->deserialize = $deserialize;
+ $this->metadata = null;
+ }
- /**
- * Create a new Call wrapper object.
- * @param Channel $channel The channel to communicate on
- * @param string $method The method to call on the remote server
- * @param callback $deserialize A callback function to deserialize
- * the response
- * @param (optional) long $timeout Timeout in microseconds
- */
- public function __construct(Channel $channel, $method, $deserialize, $timeout = false) {
- if ($timeout) {
- $now = Timeval::now();
- $delta = new Timeval($timeout);
- $deadline = $now->add($delta);
- } else {
- $deadline = Timeval::infFuture();
+ /**
+ * @return The metadata sent by the server.
+ */
+ public function getMetadata()
+ {
+ return $this->metadata;
}
- $this->call = new Call($channel, $method, $deadline);
- $this->deserialize = $deserialize;
- $this->metadata = null;
- }
- /**
- * @return The metadata sent by the server.
- */
- public function getMetadata() {
- return $this->metadata;
- }
+ /**
+ * @return string The URI of the endpoint.
+ */
+ public function getPeer()
+ {
+ return $this->call->getPeer();
+ }
- /**
- * @return string The URI of the endpoint.
- */
- public function getPeer() {
- return $this->call->getPeer();
- }
+ /**
+ * Cancels the call.
+ */
+ public function cancel()
+ {
+ $this->call->cancel();
+ }
- /**
- * Cancels the call
- */
- public function cancel() {
- $this->call->cancel();
- }
+ /**
+ * Deserialize a response value to an object.
+ *
+ * @param string $value The binary value to deserialize
+ *
+ * @return The deserialized value
+ */
+ protected function deserializeResponse($value)
+ {
+ if ($value === null) {
+ return;
+ }
- /**
- * Deserialize a response value to an object.
- * @param string $value The binary value to deserialize
- * @return The deserialized value
- */
- protected function deserializeResponse($value) {
- if ($value === null) {
- return null;
+ return call_user_func($this->deserialize, $value);
}
- return call_user_func($this->deserialize, $value);
- }
}
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index 0a3e1f78bf..c26be607ff 100755
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -31,253 +31,308 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+
namespace Grpc;
/**
* Base class for generated client stubs. Stub methods are expected to call
* _simpleRequest or _streamRequest and return the result.
*/
-class BaseStub {
+class BaseStub
+{
+ private $hostname;
+ private $channel;
- private $hostname;
- private $channel;
+ // a callback function
+ private $update_metadata;
- // a callback function
- private $update_metadata;
+ /**
+ * @param $hostname string
+ * @param $opts array
+ * - 'update_metadata': (optional) a callback function which takes in a
+ * metadata array, and returns an updated metadata array
+ */
+ public function __construct($hostname, $opts)
+ {
+ $this->hostname = $hostname;
+ $this->update_metadata = null;
+ if (isset($opts['update_metadata'])) {
+ if (is_callable($opts['update_metadata'])) {
+ $this->update_metadata = $opts['update_metadata'];
+ }
+ unset($opts['update_metadata']);
+ }
+ $package_config = json_decode(
+ file_get_contents(dirname(__FILE__).'/../../composer.json'), true);
+ $opts['grpc.primary_user_agent'] =
+ 'grpc-php/'.$package_config['version'];
+ $this->channel = new Channel($hostname, $opts);
+ }
- /**
- * @param $hostname string
- * @param $opts array
- * - 'update_metadata': (optional) a callback function which takes in a
- * metadata array, and returns an updated metadata array
- */
- public function __construct($hostname, $opts) {
- $this->hostname = $hostname;
- $this->update_metadata = null;
- if (isset($opts['update_metadata'])) {
- if (is_callable($opts['update_metadata'])) {
- $this->update_metadata = $opts['update_metadata'];
- }
- unset($opts['update_metadata']);
+ /**
+ * @return string The URI of the endpoint.
+ */
+ public function getTarget()
+ {
+ return $this->channel->getTarget();
}
- $package_config = json_decode(
- file_get_contents(dirname(__FILE__) . '/../../composer.json'), true);
- $opts['grpc.primary_user_agent'] =
- 'grpc-php/' . $package_config['version'];
- $this->channel = new Channel($hostname, $opts);
- }
- /**
- * @return string The URI of the endpoint.
- */
- public function getTarget() {
- return $this->channel->getTarget();
- }
+ /**
+ * @param $try_to_connect bool
+ *
+ * @return int The grpc connectivity state
+ */
+ public function getConnectivityState($try_to_connect = false)
+ {
+ return $this->channel->getConnectivityState($try_to_connect);
+ }
- /**
- * @param $try_to_connect bool
- * @return int The grpc connectivity state
- */
- public function getConnectivityState($try_to_connect = false) {
- return $this->channel->getConnectivityState($try_to_connect);
- }
+ /**
+ * @param $timeout in microseconds
+ *
+ * @return bool true if channel is ready
+ * @throw Exception if channel is in FATAL_ERROR state
+ */
+ public function waitForReady($timeout)
+ {
+ $new_state = $this->getConnectivityState(true);
+ if ($this->_checkConnectivityState($new_state)) {
+ return true;
+ }
- /**
- * @param $timeout in microseconds
- * @return bool true if channel is ready
- * @throw Exception if channel is in FATAL_ERROR state
- */
- public function waitForReady($timeout) {
- $new_state = $this->getConnectivityState(true);
- if ($this->_checkConnectivityState($new_state)) {
- return true;
- }
+ $now = Timeval::now();
+ $delta = new Timeval($timeout);
+ $deadline = $now->add($delta);
- $now = Timeval::now();
- $delta = new Timeval($timeout);
- $deadline = $now->add($delta);
+ while ($this->channel->watchConnectivityState($new_state, $deadline)) {
+ // state has changed before deadline
+ $new_state = $this->getConnectivityState();
+ if ($this->_checkConnectivityState($new_state)) {
+ return true;
+ }
+ }
+ // deadline has passed
+ $new_state = $this->getConnectivityState();
- while ($this->channel->watchConnectivityState($new_state, $deadline)) {
- // state has changed before deadline
- $new_state = $this->getConnectivityState();
- if ($this->_checkConnectivityState($new_state)) {
- return true;
- }
+ return $this->_checkConnectivityState($new_state);
}
- // deadline has passed
- $new_state = $this->getConnectivityState();
- return $this->_checkConnectivityState($new_state);
- }
- private function _checkConnectivityState($new_state) {
- if ($new_state == \Grpc\CHANNEL_READY) {
- return true;
+ private function _checkConnectivityState($new_state)
+ {
+ if ($new_state == \Grpc\CHANNEL_READY) {
+ return true;
+ }
+ if ($new_state == \Grpc\CHANNEL_FATAL_FAILURE) {
+ throw new \Exception('Failed to connect to server');
+ }
+
+ return false;
}
- if ($new_state == \Grpc\CHANNEL_FATAL_FAILURE) {
- throw new \Exception('Failed to connect to server');
+
+ /**
+ * Close the communication channel associated with this stub.
+ */
+ public function close()
+ {
+ $this->channel->close();
}
- return false;
- }
- /**
- * Close the communication channel associated with this stub
- */
- public function close() {
- $channel->close();
- }
+ /**
+ * constructs the auth uri for the jwt.
+ */
+ private function _get_jwt_aud_uri($method)
+ {
+ $last_slash_idx = strrpos($method, '/');
+ if ($last_slash_idx === false) {
+ throw new \InvalidArgumentException(
+ 'service name must have a slash');
+ }
+ $service_name = substr($method, 0, $last_slash_idx);
- /**
- * constructs the auth uri for the jwt
- */
- private function _get_jwt_aud_uri($method) {
- $last_slash_idx = strrpos($method, '/');
- if ($last_slash_idx === false) {
- return false;
+ return 'https://'.$this->hostname.$service_name;
}
- $service_name = substr($method, 0, $last_slash_idx);
- return "https://" . $this->hostname . $service_name;
- }
- /**
- * extract $timeout from $metadata
- * @param $metadata The metadata map
- * @return list($metadata_copy, $timeout)
- */
- private function _extract_timeout_from_metadata($metadata) {
- $timeout = false;
- $metadata_copy = $metadata;
- if (isset($metadata['timeout'])) {
- $timeout = $metadata['timeout'];
- unset($metadata_copy['timeout']);
+ /**
+ * extract $timeout from $metadata.
+ *
+ * @param $metadata The metadata map
+ *
+ * @return list($metadata_copy, $timeout)
+ */
+ private function _extract_timeout_from_metadata($metadata)
+ {
+ $timeout = false;
+ $metadata_copy = $metadata;
+ if (isset($metadata['timeout'])) {
+ $timeout = $metadata['timeout'];
+ unset($metadata_copy['timeout']);
+ }
+
+ return [$metadata_copy, $timeout];
}
- return array($metadata_copy, $timeout);
- }
- /**
- * validate and normalize the metadata array
- * @param $metadata The metadata map
- * @return $metadata Validated and key-normalized metadata map
- * @throw InvalidArgumentException if key contains invalid characters
- */
- private function _validate_and_normalize_metadata($metadata) {
- $metadata_copy = array();
- foreach ($metadata as $key => $value) {
- if (!preg_match('/^[A-Za-z\d_-]+$/', $key)) {
- throw new \InvalidArgumentException(
- 'Metadata keys must be nonempty strings containing only '.
- 'alphanumeric characters, hyphens and underscores');
- }
- $metadata_copy[strtolower($key)] = $value;
+ /**
+ * validate and normalize the metadata array.
+ *
+ * @param $metadata The metadata map
+ *
+ * @return $metadata Validated and key-normalized metadata map
+ * @throw InvalidArgumentException if key contains invalid characters
+ */
+ private function _validate_and_normalize_metadata($metadata)
+ {
+ $metadata_copy = [];
+ foreach ($metadata as $key => $value) {
+ if (!preg_match('/^[A-Za-z\d_-]+$/', $key)) {
+ throw new \InvalidArgumentException(
+ 'Metadata keys must be nonempty strings containing only '.
+ 'alphanumeric characters, hyphens and underscores');
+ }
+ $metadata_copy[strtolower($key)] = $value;
+ }
+
+ return $metadata_copy;
}
- return $metadata_copy;
- }
- /* This class is intended to be subclassed by generated code, so all functions
- begin with "_" to avoid name collisions. */
+ /* This class is intended to be subclassed by generated code, so
+ * all functions begin with "_" to avoid name collisions. */
- /**
- * Call a remote method that takes a single argument and has a single output
- *
- * @param string $method The name of the method to call
- * @param $argument The argument to the method
- * @param callable $deserialize A function that deserializes the response
- * @param array $metadata A metadata map to send to the server
- * @return SimpleSurfaceActiveCall The active call object
- */
- public function _simpleRequest($method,
- $argument,
- callable $deserialize,
- $metadata = array(),
- $options = array()) {
- list($actual_metadata, $timeout) = $this->_extract_timeout_from_metadata($metadata);
- $call = new UnaryCall($this->channel, $method, $deserialize, $timeout);
- $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
- if (is_callable($this->update_metadata)) {
- $actual_metadata = call_user_func($this->update_metadata,
+ /**
+ * Call a remote method that takes a single argument and has a
+ * single output.
+ *
+ * @param string $method The name of the method to call
+ * @param $argument The argument to the method
+ * @param callable $deserialize A function that deserializes the response
+ * @param array $metadata A metadata map to send to the server
+ *
+ * @return SimpleSurfaceActiveCall The active call object
+ */
+ public function _simpleRequest($method,
+ $argument,
+ callable $deserialize,
+ $metadata = [],
+ $options = [])
+ {
+ list($actual_metadata, $timeout) =
+ $this->_extract_timeout_from_metadata($metadata);
+ $call = new UnaryCall($this->channel,
+ $method,
+ $deserialize,
+ $timeout);
+ $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
+ if (is_callable($this->update_metadata)) {
+ $actual_metadata = call_user_func($this->update_metadata,
$actual_metadata,
$jwt_aud_uri);
+ }
+ $actual_metadata = $this->_validate_and_normalize_metadata(
+ $actual_metadata);
+ $call->start($argument, $actual_metadata, $options);
+
+ return $call;
}
- $actual_metadata = $this->_validate_and_normalize_metadata($actual_metadata);
- $call->start($argument, $actual_metadata, $options);
- return $call;
- }
- /**
- * Call a remote method that takes a stream of arguments and has a single
- * output
- *
- * @param string $method The name of the method to call
- * @param $arguments An array or Traversable of arguments to stream to the
- * server
- * @param callable $deserialize A function that deserializes the response
- * @param array $metadata A metadata map to send to the server
- * @return ClientStreamingSurfaceActiveCall The active call object
- */
- public function _clientStreamRequest($method,
- callable $deserialize,
- $metadata = array()) {
- list($actual_metadata, $timeout) = $this->_extract_timeout_from_metadata($metadata);
- $call = new ClientStreamingCall($this->channel, $method, $deserialize, $timeout);
- $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
- if (is_callable($this->update_metadata)) {
- $actual_metadata = call_user_func($this->update_metadata,
+ /**
+ * Call a remote method that takes a stream of arguments and has a single
+ * output.
+ *
+ * @param string $method The name of the method to call
+ * @param $arguments An array or Traversable of arguments to stream to the
+ * server
+ * @param callable $deserialize A function that deserializes the response
+ * @param array $metadata A metadata map to send to the server
+ *
+ * @return ClientStreamingSurfaceActiveCall The active call object
+ */
+ public function _clientStreamRequest($method,
+ callable $deserialize,
+ $metadata = [])
+ {
+ list($actual_metadata, $timeout) =
+ $this->_extract_timeout_from_metadata($metadata);
+ $call = new ClientStreamingCall($this->channel,
+ $method,
+ $deserialize,
+ $timeout);
+ $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
+ if (is_callable($this->update_metadata)) {
+ $actual_metadata = call_user_func($this->update_metadata,
$actual_metadata,
$jwt_aud_uri);
+ }
+ $actual_metadata = $this->_validate_and_normalize_metadata(
+ $actual_metadata);
+ $call->start($actual_metadata);
+
+ return $call;
}
- $actual_metadata = $this->_validate_and_normalize_metadata($actual_metadata);
- $call->start($actual_metadata);
- return $call;
- }
- /**
- * Call a remote method that takes a single argument and returns a stream of
- * responses
- *
- * @param string $method The name of the method to call
- * @param $argument The argument to the method
- * @param callable $deserialize A function that deserializes the responses
- * @param array $metadata A metadata map to send to the server
- * @return ServerStreamingSurfaceActiveCall The active call object
- */
- public function _serverStreamRequest($method,
- $argument,
- callable $deserialize,
- $metadata = array(),
- $options = array()) {
- list($actual_metadata, $timeout) = $this->_extract_timeout_from_metadata($metadata);
- $call = new ServerStreamingCall($this->channel, $method, $deserialize, $timeout);
- $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
- if (is_callable($this->update_metadata)) {
- $actual_metadata = call_user_func($this->update_metadata,
+ /**
+ * Call a remote method that takes a single argument and returns a stream of
+ * responses.
+ *
+ * @param string $method The name of the method to call
+ * @param $argument The argument to the method
+ * @param callable $deserialize A function that deserializes the responses
+ * @param array $metadata A metadata map to send to the server
+ *
+ * @return ServerStreamingSurfaceActiveCall The active call object
+ */
+ public function _serverStreamRequest($method,
+ $argument,
+ callable $deserialize,
+ $metadata = [],
+ $options = [])
+ {
+ list($actual_metadata, $timeout) =
+ $this->_extract_timeout_from_metadata($metadata);
+ $call = new ServerStreamingCall($this->channel,
+ $method,
+ $deserialize,
+ $timeout);
+ $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
+ if (is_callable($this->update_metadata)) {
+ $actual_metadata = call_user_func($this->update_metadata,
$actual_metadata,
$jwt_aud_uri);
+ }
+ $actual_metadata = $this->_validate_and_normalize_metadata(
+ $actual_metadata);
+ $call->start($argument, $actual_metadata, $options);
+
+ return $call;
}
- $actual_metadata = $this->_validate_and_normalize_metadata($actual_metadata);
- $call->start($argument, $actual_metadata, $options);
- return $call;
- }
- /**
- * Call a remote method with messages streaming in both directions
- *
- * @param string $method The name of the method to call
- * @param callable $deserialize A function that deserializes the responses
- * @param array $metadata A metadata map to send to the server
- * @return BidiStreamingSurfaceActiveCall The active call object
- */
- public function _bidiRequest($method,
- callable $deserialize,
- $metadata = array()) {
- list($actual_metadata, $timeout) = $this->_extract_timeout_from_metadata($metadata);
- $call = new BidiStreamingCall($this->channel, $method, $deserialize, $timeout);
- $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
- if (is_callable($this->update_metadata)) {
- $actual_metadata = call_user_func($this->update_metadata,
+ /**
+ * Call a remote method with messages streaming in both directions.
+ *
+ * @param string $method The name of the method to call
+ * @param callable $deserialize A function that deserializes the responses
+ * @param array $metadata A metadata map to send to the server
+ *
+ * @return BidiStreamingSurfaceActiveCall The active call object
+ */
+ public function _bidiRequest($method,
+ callable $deserialize,
+ $metadata = [])
+ {
+ list($actual_metadata, $timeout) =
+ $this->_extract_timeout_from_metadata($metadata);
+ $call = new BidiStreamingCall($this->channel,
+ $method,
+ $deserialize,
+ $timeout);
+ $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
+ if (is_callable($this->update_metadata)) {
+ $actual_metadata = call_user_func($this->update_metadata,
$actual_metadata,
$jwt_aud_uri);
+ }
+ $actual_metadata = $this->_validate_and_normalize_metadata(
+ $actual_metadata);
+ $call->start($actual_metadata);
+
+ return $call;
}
- $actual_metadata = $this->_validate_and_normalize_metadata($actual_metadata);
- $call->start($actual_metadata);
- return $call;
- }
}
diff --git a/src/php/lib/Grpc/BidiStreamingCall.php b/src/php/lib/Grpc/BidiStreamingCall.php
index c432fd52d8..bf813c12e7 100644
--- a/src/php/lib/Grpc/BidiStreamingCall.php
+++ b/src/php/lib/Grpc/BidiStreamingCall.php
@@ -31,68 +31,87 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+
namespace Grpc;
/**
* Represents an active call that allows for sending and recieving messages in
* streams in any order.
*/
-class BidiStreamingCall extends AbstractCall {
- /**
- * Start the call
- * @param array $metadata Metadata to send with the call, if applicable
- */
- public function start($metadata = array()) {
- $this->call->startBatch([OP_SEND_INITIAL_METADATA => $metadata]);
- }
+class BidiStreamingCall extends AbstractCall
+{
+ /**
+ * Start the call.
+ *
+ * @param array $metadata Metadata to send with the call, if applicable
+ */
+ public function start($metadata = [])
+ {
+ $this->call->startBatch([
+ OP_SEND_INITIAL_METADATA => $metadata,
+ ]);
+ }
+
+ /**
+ * Reads the next value from the server.
+ *
+ * @return The next value from the server, or null if there is none
+ */
+ public function read()
+ {
+ $batch = [OP_RECV_MESSAGE => true];
+ if ($this->metadata === null) {
+ $batch[OP_RECV_INITIAL_METADATA] = true;
+ }
+ $read_event = $this->call->startBatch($batch);
+ if ($this->metadata === null) {
+ $this->metadata = $read_event->metadata;
+ }
- /**
- * Reads the next value from the server.
- * @return The next value from the server, or null if there is none
- */
- public function read() {
- $batch = [OP_RECV_MESSAGE => true];
- if ($this->metadata === null) {
- $batch[OP_RECV_INITIAL_METADATA] = true;
+ return $this->deserializeResponse($read_event->message);
}
- $read_event = $this->call->startBatch($batch);
- if ($this->metadata === null) {
- $this->metadata = $read_event->metadata;
+
+ /**
+ * Write a single message to the server. This cannot be called after
+ * writesDone is called.
+ *
+ * @param ByteBuffer $data The data to write
+ * @param array $options an array of options, possible keys:
+ * 'flags' => a number
+ */
+ public function write($data, $options = [])
+ {
+ $message_array = ['message' => $data->serialize()];
+ if (isset($options['flags'])) {
+ $message_array['flags'] = $options['flags'];
+ }
+ $this->call->startBatch([
+ OP_SEND_MESSAGE => $message_array,
+ ]);
}
- return $this->deserializeResponse($read_event->message);
- }
- /**
- * Write a single message to the server. This cannot be called after
- * writesDone is called.
- * @param ByteBuffer $data The data to write
- * @param array $options an array of options, possible keys:
- * 'flags' => a number
- */
- public function write($data, $options = array()) {
- $message_array = ['message' => $data->serialize()];
- if (isset($options['flags'])) {
- $message_array['flags'] = $options['flags'];
+ /**
+ * Indicate that no more writes will be sent.
+ */
+ public function writesDone()
+ {
+ $this->call->startBatch([
+ OP_SEND_CLOSE_FROM_CLIENT => true,
+ ]);
}
- $this->call->startBatch([OP_SEND_MESSAGE => $message_array]);
- }
- /**
- * Indicate that no more writes will be sent.
- */
- public function writesDone() {
- $this->call->startBatch([OP_SEND_CLOSE_FROM_CLIENT => true]);
- }
+ /**
+ * Wait for the server to send the status, and return it.
+ *
+ * @return object The status object, with integer $code, string $details,
+ * and array $metadata members
+ */
+ public function getStatus()
+ {
+ $status_event = $this->call->startBatch([
+ OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
- /**
- * Wait for the server to send the status, and return it.
- * @return object The status object, with integer $code, string $details,
- * and array $metadata members
- */
- public function getStatus() {
- $status_event = $this->call->startBatch([
- OP_RECV_STATUS_ON_CLIENT => true
- ]);
- return $status_event->status;
- }
-} \ No newline at end of file
+ return $status_event->status;
+ }
+}
diff --git a/src/php/lib/Grpc/ClientStreamingCall.php b/src/php/lib/Grpc/ClientStreamingCall.php
index b96c17e751..500cfe0d7a 100644
--- a/src/php/lib/Grpc/ClientStreamingCall.php
+++ b/src/php/lib/Grpc/ClientStreamingCall.php
@@ -31,47 +31,61 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+
namespace Grpc;
/**
* Represents an active call that sends a stream of messages and then gets a
* single response.
*/
-class ClientStreamingCall extends AbstractCall {
- /**
- * Start the call.
- * @param array $metadata Metadata to send with the call, if applicable
- */
- public function start($metadata = array()) {
- $this->call->startBatch([OP_SEND_INITIAL_METADATA => $metadata]);
- }
+class ClientStreamingCall extends AbstractCall
+{
+ /**
+ * Start the call.
+ *
+ * @param array $metadata Metadata to send with the call, if applicable
+ */
+ public function start($metadata = [])
+ {
+ $this->call->startBatch([
+ OP_SEND_INITIAL_METADATA => $metadata,
+ ]);
+ }
- /**
- * Write a single message to the server. This cannot be called after
- * wait is called.
- * @param ByteBuffer $data The data to write
- * @param array $options an array of options, possible keys:
- * 'flags' => a number
- */
- public function write($data, $options = array()) {
- $message_array = ['message' => $data->serialize()];
- if (isset($options['flags'])) {
- $message_array['flags'] = $options['flags'];
+ /**
+ * Write a single message to the server. This cannot be called after
+ * wait is called.
+ *
+ * @param ByteBuffer $data The data to write
+ * @param array $options an array of options, possible keys:
+ * 'flags' => a number
+ */
+ public function write($data, $options = [])
+ {
+ $message_array = ['message' => $data->serialize()];
+ if (isset($options['flags'])) {
+ $message_array['flags'] = $options['flags'];
+ }
+ $this->call->startBatch([
+ OP_SEND_MESSAGE => $message_array,
+ ]);
}
- $this->call->startBatch([OP_SEND_MESSAGE => $message_array]);
- }
- /**
- * Wait for the server to respond with data and a status
- * @return [response data, status]
- */
- public function wait() {
- $event = $this->call->startBatch([
- OP_SEND_CLOSE_FROM_CLIENT => true,
- OP_RECV_INITIAL_METADATA => true,
- OP_RECV_MESSAGE => true,
- OP_RECV_STATUS_ON_CLIENT => true]);
- $this->metadata = $event->metadata;
- return array($this->deserializeResponse($event->message), $event->status);
- }
-} \ No newline at end of file
+ /**
+ * Wait for the server to respond with data and a status.
+ *
+ * @return [response data, status]
+ */
+ public function wait()
+ {
+ $event = $this->call->startBatch([
+ OP_SEND_CLOSE_FROM_CLIENT => true,
+ OP_RECV_INITIAL_METADATA => true,
+ OP_RECV_MESSAGE => true,
+ OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+ $this->metadata = $event->metadata;
+
+ return [$this->deserializeResponse($event->message), $event->status];
+ }
+}
diff --git a/src/php/lib/Grpc/ServerStreamingCall.php b/src/php/lib/Grpc/ServerStreamingCall.php
index a93c1a5d5e..da48523717 100644
--- a/src/php/lib/Grpc/ServerStreamingCall.php
+++ b/src/php/lib/Grpc/ServerStreamingCall.php
@@ -31,53 +31,66 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+
namespace Grpc;
/**
* Represents an active call that sends a single message and then gets a stream
- * of reponses
+ * of reponses.
*/
-class ServerStreamingCall extends AbstractCall {
- /**
- * Start the call
- * @param $data The data to send
- * @param array $metadata Metadata to send with the call, if applicable
- * @param array $options an array of options, possible keys:
- * 'flags' => a number
- */
- public function start($data, $metadata = array(), $options = array()) {
- $message_array = ['message' => $data->serialize()];
- if (isset($options['flags'])) {
- $message_array['flags'] = $options['flags'];
+class ServerStreamingCall extends AbstractCall
+{
+ /**
+ * Start the call.
+ *
+ * @param $data The data to send
+ * @param array $metadata Metadata to send with the call, if applicable
+ * @param array $options an array of options, possible keys:
+ * 'flags' => a number
+ */
+ public function start($data, $metadata = [], $options = [])
+ {
+ $message_array = ['message' => $data->serialize()];
+ if (isset($options['flags'])) {
+ $message_array['flags'] = $options['flags'];
+ }
+ $event = $this->call->startBatch([
+ OP_SEND_INITIAL_METADATA => $metadata,
+ OP_RECV_INITIAL_METADATA => true,
+ OP_SEND_MESSAGE => $message_array,
+ OP_SEND_CLOSE_FROM_CLIENT => true,
+ ]);
+ $this->metadata = $event->metadata;
}
- $event = $this->call->startBatch([
- OP_SEND_INITIAL_METADATA => $metadata,
- OP_RECV_INITIAL_METADATA => true,
- OP_SEND_MESSAGE => $message_array,
- OP_SEND_CLOSE_FROM_CLIENT => true]);
- $this->metadata = $event->metadata;
- }
- /**
- * @return An iterator of response values
- */
- public function responses() {
- $response = $this->call->startBatch([OP_RECV_MESSAGE => true])->message;
- while($response !== null) {
- yield $this->deserializeResponse($response);
- $response = $this->call->startBatch([OP_RECV_MESSAGE => true])->message;
+ /**
+ * @return An iterator of response values
+ */
+ public function responses()
+ {
+ $response = $this->call->startBatch([
+ OP_RECV_MESSAGE => true,
+ ])->message;
+ while ($response !== null) {
+ yield $this->deserializeResponse($response);
+ $response = $this->call->startBatch([
+ OP_RECV_MESSAGE => true,
+ ])->message;
+ }
}
- }
- /**
- * Wait for the server to send the status, and return it.
- * @return object The status object, with integer $code, string $details,
- * and array $metadata members
- */
- public function getStatus() {
- $status_event = $this->call->startBatch([
- OP_RECV_STATUS_ON_CLIENT => true
- ]);
- return $status_event->status;
- }
+ /**
+ * Wait for the server to send the status, and return it.
+ *
+ * @return object The status object, with integer $code, string $details,
+ * and array $metadata members
+ */
+ public function getStatus()
+ {
+ $status_event = $this->call->startBatch([
+ OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ return $status_event->status;
+ }
}
diff --git a/src/php/lib/Grpc/UnaryCall.php b/src/php/lib/Grpc/UnaryCall.php
index 38af6b1d74..b57903d6d0 100644
--- a/src/php/lib/Grpc/UnaryCall.php
+++ b/src/php/lib/Grpc/UnaryCall.php
@@ -31,41 +31,50 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+
namespace Grpc;
/**
* Represents an active call that sends a single message and then gets a single
* response.
*/
-class UnaryCall extends AbstractCall {
- /**
- * Start the call
- * @param $data The data to send
- * @param array $metadata Metadata to send with the call, if applicable
- * @param array $options an array of options, possible keys:
- * 'flags' => a number
- */
- public function start($data, $metadata = array(), $options = array()) {
- $message_array = ['message' => $data->serialize()];
- if (isset($options['flags'])) {
- $message_array['flags'] = $options['flags'];
+class UnaryCall extends AbstractCall
+{
+ /**
+ * Start the call.
+ *
+ * @param $data The data to send
+ * @param array $metadata Metadata to send with the call, if applicable
+ * @param array $options an array of options, possible keys:
+ * 'flags' => a number
+ */
+ public function start($data, $metadata = [], $options = [])
+ {
+ $message_array = ['message' => $data->serialize()];
+ if (isset($options['flags'])) {
+ $message_array['flags'] = $options['flags'];
+ }
+ $event = $this->call->startBatch([
+ OP_SEND_INITIAL_METADATA => $metadata,
+ OP_RECV_INITIAL_METADATA => true,
+ OP_SEND_MESSAGE => $message_array,
+ OP_SEND_CLOSE_FROM_CLIENT => true,
+ ]);
+ $this->metadata = $event->metadata;
}
- $event = $this->call->startBatch([
- OP_SEND_INITIAL_METADATA => $metadata,
- OP_RECV_INITIAL_METADATA => true,
- OP_SEND_MESSAGE => $message_array,
- OP_SEND_CLOSE_FROM_CLIENT => true]);
- $this->metadata = $event->metadata;
- }
- /**
- * Wait for the server to respond with data and a status
- * @return [response data, status]
- */
- public function wait() {
- $event = $this->call->startBatch([
- OP_RECV_MESSAGE => true,
- OP_RECV_STATUS_ON_CLIENT => true]);
- return array($this->deserializeResponse($event->message), $event->status);
- }
+ /**
+ * Wait for the server to respond with data and a status.
+ *
+ * @return [response data, status]
+ */
+ public function wait()
+ {
+ $event = $this->call->startBatch([
+ OP_RECV_MESSAGE => true,
+ OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ return [$this->deserializeResponse($event->message), $event->status];
+ }
}
diff --git a/src/php/phpunit.xml b/src/php/phpunit.xml
new file mode 100644
index 0000000000..52ea6e8f0e
--- /dev/null
+++ b/src/php/phpunit.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit bootstrap="tests/bootstrap.php" colors="true">
+ <testsuites>
+ <testsuite name="grpc-unit-tests">
+ <directory suffix="Test.php">tests/unit_tests</directory>
+ </testsuite>
+ <testsuite name="grpc-genereated-code-tests">
+ <file>tests/generated_code/GeneratedCodeTest.php</file>
+ <file>tests/generated_code/GeneratedCodeWithCallbackTest.php</file>
+ </testsuite>
+ </testsuites>
+ <filter>
+ <whitelist>
+ <directory suffix=".php">lib/Grpc</directory>
+ </whitelist>
+ </filter>
+ <logging>
+ <log type="coverage-html" target="./log/codeCoverage" charset="UTF-8"
+ yui="true" highlight="true"
+ lowUpperBound="75" highLowerBound="95"/>
+ </logging>
+</phpunit>
diff --git a/src/php/tests/bootstrap.php b/src/php/tests/bootstrap.php
new file mode 100644
index 0000000000..b61f2c40a5
--- /dev/null
+++ b/src/php/tests/bootstrap.php
@@ -0,0 +1,21 @@
+<?php
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+error_reporting(E_ALL | E_STRICT);
+require dirname(__DIR__) . '/vendor/autoload.php';
+date_default_timezone_set('UTC');
diff --git a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php
index 5cdba1e5a0..4a0bd6a1f1 100644
--- a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php
+++ b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php
@@ -31,100 +31,212 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-require_once realpath(dirname(__FILE__) . '/../../vendor/autoload.php');
-require 'math.php';
-abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase {
- /* These tests require that a server exporting the math service must be
- * running on $GRPC_TEST_HOST */
- protected static $client;
- protected static $timeout;
-
- public function testWaitForNotReady() {
- $this->assertFalse(self::$client->waitForReady(1));
- }
-
- public function testWaitForReady() {
- $this->assertTrue(self::$client->waitForReady(250000));
- }
-
- public function testGetTarget() {
- $this->assertTrue(is_string(self::$client->getTarget()));
- }
-
- /**
- * @expectedException InvalidArgumentException
- */
- public function testInvalidMetadata() {
- $div_arg = new math\DivArgs();
- $call = self::$client->Div($div_arg, array(' ' => 'abc123'));
- }
-
- public function testWriteFlags() {
- $div_arg = new math\DivArgs();
- $div_arg->setDividend(7);
- $div_arg->setDivisor(4);
- $call = self::$client->Div($div_arg, array(), array('flags' => Grpc\WRITE_NO_COMPRESS));
- $this->assertTrue(is_string($call->getPeer()));
- list($response, $status) = $call->wait();
- $this->assertSame(1, $response->getQuotient());
- $this->assertSame(3, $response->getRemainder());
- $this->assertSame(\Grpc\STATUS_OK, $status->code);
- }
-
- public function testSimpleRequest() {
- $div_arg = new math\DivArgs();
- $div_arg->setDividend(7);
- $div_arg->setDivisor(4);
- $call = self::$client->Div($div_arg);
- $this->assertTrue(is_string($call->getPeer()));
- list($response, $status) = $call->wait();
- $this->assertSame(1, $response->getQuotient());
- $this->assertSame(3, $response->getRemainder());
- $this->assertSame(\Grpc\STATUS_OK, $status->code);
- }
-
- public function testServerStreaming() {
- $fib_arg = new math\FibArgs();
- $fib_arg->setLimit(7);
- $call = self::$client->Fib($fib_arg);
- $this->assertTrue(is_string($call->getPeer()));
- $result_array = iterator_to_array($call->responses());
- $extract_num = function($num){
- return $num->getNum();
- };
- $values = array_map($extract_num, $result_array);
- $this->assertSame([1, 1, 2, 3, 5, 8, 13], $values);
- $status = $call->getStatus();
- $this->assertSame(\Grpc\STATUS_OK, $status->code);
- }
-
- public function testClientStreaming() {
- $call = self::$client->Sum();
- $this->assertTrue(is_string($call->getPeer()));
- for ($i = 0; $i < 7; $i++) {
- $num = new math\Num();
- $num->setNum($i);
- $call->write($num);
- }
- list($response, $status) = $call->wait();
- $this->assertSame(21, $response->getNum());
- $this->assertSame(\Grpc\STATUS_OK, $status->code);
- }
-
- public function testBidiStreaming() {
- $call = self::$client->DivMany();
- $this->assertTrue(is_string($call->getPeer()));
- for ($i = 0; $i < 7; $i++) {
- $div_arg = new math\DivArgs();
- $div_arg->setDividend(2 * $i + 1);
- $div_arg->setDivisor(2);
- $call->write($div_arg);
- $response = $call->read();
- $this->assertSame($i, $response->getQuotient());
- $this->assertSame(1, $response->getRemainder());
- }
- $call->writesDone();
- $status = $call->getStatus();
- $this->assertSame(\Grpc\STATUS_OK, $status->code);
- }
+require_once realpath(dirname(__FILE__).'/../../vendor/autoload.php');
+require_once dirname(__FILE__).'/math.php';
+
+abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * These tests require that a server exporting the math service must be
+ * running on $GRPC_TEST_HOST.
+ */
+ protected static $client;
+ protected static $timeout;
+
+ public function testWaitForNotReady()
+ {
+ $this->assertFalse(self::$client->waitForReady(1));
+ }
+
+ public function testWaitForReady()
+ {
+ $this->assertTrue(self::$client->waitForReady(250000));
+ }
+
+ public function testAlreadyReady()
+ {
+ $this->assertTrue(self::$client->waitForReady(250000));
+ $this->assertTrue(self::$client->waitForReady(100));
+ }
+
+ public function testGetTarget()
+ {
+ $this->assertTrue(is_string(self::$client->getTarget()));
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testClose()
+ {
+ self::$client->close();
+ $div_arg = new math\DivArgs();
+ $call = self::$client->Div($div_arg);
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testInvalidMetadata()
+ {
+ $div_arg = new math\DivArgs();
+ $call = self::$client->Div($div_arg, [' ' => 'abc123']);
+ }
+
+ public function testGetCallMetadata()
+ {
+ $div_arg = new math\DivArgs();
+ $call = self::$client->Div($div_arg);
+ $this->assertTrue(is_array($call->getMetadata()));
+ }
+
+ public function testTimeout()
+ {
+ $div_arg = new math\DivArgs();
+ $call = self::$client->Div($div_arg, ['timeout' => 100]);
+ list($response, $status) = $call->wait();
+ $this->assertSame(\Grpc\STATUS_DEADLINE_EXCEEDED, $status->code);
+ }
+
+ public function testCancel()
+ {
+ $div_arg = new math\DivArgs();
+ $call = self::$client->Div($div_arg);
+ $call->cancel();
+ list($response, $status) = $call->wait();
+ $this->assertSame(\Grpc\STATUS_CANCELLED, $status->code);
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testInvalidMethodName()
+ {
+ $invalid_client = new DummyInvalidClient('host', []);
+ $div_arg = new math\DivArgs();
+ $invalid_client->InvalidUnaryCall($div_arg);
+ }
+
+ public function testWriteFlags()
+ {
+ $div_arg = new math\DivArgs();
+ $div_arg->setDividend(7);
+ $div_arg->setDivisor(4);
+ $call = self::$client->Div($div_arg, [],
+ ['flags' => Grpc\WRITE_NO_COMPRESS]);
+ $this->assertTrue(is_string($call->getPeer()));
+ list($response, $status) = $call->wait();
+ $this->assertSame(1, $response->getQuotient());
+ $this->assertSame(3, $response->getRemainder());
+ $this->assertSame(\Grpc\STATUS_OK, $status->code);
+ }
+
+ public function testWriteFlagsServerStreaming()
+ {
+ $fib_arg = new math\FibArgs();
+ $fib_arg->setLimit(7);
+ $call = self::$client->Fib($fib_arg, [],
+ ['flags' => Grpc\WRITE_NO_COMPRESS]);
+ $result_array = iterator_to_array($call->responses());
+ $status = $call->getStatus();
+ $this->assertSame(\Grpc\STATUS_OK, $status->code);
+ }
+
+ public function testWriteFlagsClientStreaming()
+ {
+ $call = self::$client->Sum();
+ $num = new math\Num();
+ $num->setNum(1);
+ $call->write($num, ['flags' => Grpc\WRITE_NO_COMPRESS]);
+ list($response, $status) = $call->wait();
+ $this->assertSame(\Grpc\STATUS_OK, $status->code);
+ }
+
+ public function testWriteFlagsBidiStreaming()
+ {
+ $call = self::$client->DivMany();
+ $div_arg = new math\DivArgs();
+ $div_arg->setDividend(7);
+ $div_arg->setDivisor(4);
+ $call->write($div_arg, ['flags' => Grpc\WRITE_NO_COMPRESS]);
+ $response = $call->read();
+ $call->writesDone();
+ $status = $call->getStatus();
+ $this->assertSame(\Grpc\STATUS_OK, $status->code);
+ }
+
+ public function testSimpleRequest()
+ {
+ $div_arg = new math\DivArgs();
+ $div_arg->setDividend(7);
+ $div_arg->setDivisor(4);
+ $call = self::$client->Div($div_arg);
+ $this->assertTrue(is_string($call->getPeer()));
+ list($response, $status) = $call->wait();
+ $this->assertSame(1, $response->getQuotient());
+ $this->assertSame(3, $response->getRemainder());
+ $this->assertSame(\Grpc\STATUS_OK, $status->code);
+ }
+
+ public function testServerStreaming()
+ {
+ $fib_arg = new math\FibArgs();
+ $fib_arg->setLimit(7);
+ $call = self::$client->Fib($fib_arg);
+ $this->assertTrue(is_string($call->getPeer()));
+ $result_array = iterator_to_array($call->responses());
+ $extract_num = function ($num) {
+ return $num->getNum();
+ };
+ $values = array_map($extract_num, $result_array);
+ $this->assertSame([1, 1, 2, 3, 5, 8, 13], $values);
+ $status = $call->getStatus();
+ $this->assertSame(\Grpc\STATUS_OK, $status->code);
+ }
+
+ public function testClientStreaming()
+ {
+ $call = self::$client->Sum();
+ $this->assertTrue(is_string($call->getPeer()));
+ for ($i = 0; $i < 7; ++$i) {
+ $num = new math\Num();
+ $num->setNum($i);
+ $call->write($num);
+ }
+ list($response, $status) = $call->wait();
+ $this->assertSame(21, $response->getNum());
+ $this->assertSame(\Grpc\STATUS_OK, $status->code);
+ }
+
+ public function testBidiStreaming()
+ {
+ $call = self::$client->DivMany();
+ $this->assertTrue(is_string($call->getPeer()));
+ for ($i = 0; $i < 7; ++$i) {
+ $div_arg = new math\DivArgs();
+ $div_arg->setDividend(2 * $i + 1);
+ $div_arg->setDivisor(2);
+ $call->write($div_arg);
+ $response = $call->read();
+ $this->assertSame($i, $response->getQuotient());
+ $this->assertSame(1, $response->getRemainder());
+ }
+ $call->writesDone();
+ $status = $call->getStatus();
+ $this->assertSame(\Grpc\STATUS_OK, $status->code);
+ }
+}
+
+class DummyInvalidClient extends \Grpc\BaseStub
+{
+ public function InvalidUnaryCall(\math\DivArgs $argument,
+ $metadata = [],
+ $options = [])
+ {
+ return $this->_simpleRequest('invalidMethodName',
+ $argument,
+ function () {},
+ $metadata,
+ $options);
+ }
}
diff --git a/src/php/tests/generated_code/GeneratedCodeTest.php b/src/php/tests/generated_code/GeneratedCodeTest.php
index a1a2ce81db..7043e8e1d1 100755
--- a/src/php/tests/generated_code/GeneratedCodeTest.php
+++ b/src/php/tests/generated_code/GeneratedCodeTest.php
@@ -31,11 +31,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-require 'AbstractGeneratedCodeTest.php';
+require_once dirname(__FILE__).'/AbstractGeneratedCodeTest.php';
-class GeneratedCodeTest extends AbstractGeneratedCodeTest {
- public static function setUpBeforeClass() {
- self::$client = new math\MathClient(
+class GeneratedCodeTest extends AbstractGeneratedCodeTest
+{
+ public function setUp()
+ {
+ self::$client = new math\MathClient(
getenv('GRPC_TEST_HOST'), []);
- }
+ }
+
+ public static function tearDownAfterClass()
+ {
+ self::$client->close();
+ }
}
diff --git a/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php b/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
index 68f57d34ad..5a20e684c7 100644
--- a/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
+++ b/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
@@ -31,17 +31,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-require 'AbstractGeneratedCodeTest.php';
+require_once dirname(__FILE__).'/AbstractGeneratedCodeTest.php';
-class GeneratedCodeWithCallbackTest extends AbstractGeneratedCodeTest {
- public static function setUpBeforeClass() {
- self::$client = new math\MathClient(
- getenv('GRPC_TEST_HOST'), ['update_metadata' =>
- function($a_hash,
- $client = array()) {
- $a_copy = $a_hash;
- $a_copy['foo'] = ['bar'];
- return $a_copy;
- }]);
- }
+class GeneratedCodeWithCallbackTest extends AbstractGeneratedCodeTest
+{
+ public function setUp()
+ {
+ self::$client = new math\MathClient(
+ getenv('GRPC_TEST_HOST'),
+ ['update_metadata' => function ($a_hash,
+ $client = []) {
+ $a_copy = $a_hash;
+ $a_copy['foo'] = ['bar'];
+
+ return $a_copy;
+ }]);
+ }
+
+ public static function tearDownAfterClass()
+ {
+ self::$client->close();
+ }
}
diff --git a/src/php/tests/generated_code/math_client.php b/src/php/tests/generated_code/math_client.php
index 7bc78287be..76ccabc068 100644
--- a/src/php/tests/generated_code/math_client.php
+++ b/src/php/tests/generated_code/math_client.php
@@ -36,31 +36,32 @@
include 'vendor/autoload.php';
include 'tests/generated_code/math.php';
-function p($line) {
- print("$line<br/>\n");
+function p($line)
+{
+ print("$line<br/>\n");
}
-$host = "localhost:50051";
+$host = 'localhost:50051';
p("Connecting to host: $host");
$client = new math\MathClient($host, []);
-p("Client class: ".get_class($client));
+p('Client class: '.get_class($client));
p('');
-p("Running unary call test:");
+p('Running unary call test:');
$dividend = 7;
$divisor = 4;
$div_arg = new math\DivArgs();
$div_arg->setDividend($dividend);
$div_arg->setDivisor($divisor);
$call = $client->Div($div_arg);
-p("Call peer: ".$call->getPeer());
+p('Call peer: '.$call->getPeer());
p("Dividing $dividend by $divisor");
list($response, $status) = $call->wait();
-p("quotient = ".$response->getQuotient());
-p("remainder = ".$response->getRemainder());
+p('quotient = '.$response->getQuotient());
+p('remainder = '.$response->getRemainder());
p('');
-p("Running server streaming test:");
+p('Running server streaming test:');
$limit = 7;
$fib_arg = new math\FibArgs();
$fib_arg->setLimit($limit);
@@ -68,35 +69,35 @@ $call = $client->Fib($fib_arg);
$result_array = iterator_to_array($call->responses());
$result = '';
foreach ($result_array as $num) {
- $result .= ' '.$num->getNum();
+ $result .= ' '.$num->getNum();
}
p("The first $limit Fibonacci numbers are:".$result);
p('');
-p("Running client streaming test:");
+p('Running client streaming test:');
$call = $client->Sum();
-for ($i = 0; $i <= $limit; $i++) {
- $num = new math\Num();
- $num->setNum($i);
- $call->write($num);
+for ($i = 0; $i <= $limit; ++$i) {
+ $num = new math\Num();
+ $num->setNum($i);
+ $call->write($num);
}
list($response, $status) = $call->wait();
-p(sprintf("The first %d positive integers sum to: %d",
+p(sprintf('The first %d positive integers sum to: %d',
$limit, $response->getNum()));
p('');
-p("Running bidi-streaming test:");
+p('Running bidi-streaming test:');
$call = $client->DivMany();
-for ($i = 0; $i < 7; $i++) {
- $div_arg = new math\DivArgs();
- $dividend = 2 * $i + 1;
- $divisor = 3;
- $div_arg->setDividend($dividend);
- $div_arg->setDivisor($divisor);
- $call->write($div_arg);
- p("client writing: $dividend / $divisor");
- $response = $call->read();
- p(sprintf("server writing: quotient = %d, remainder = %d",
+for ($i = 0; $i < 7; ++$i) {
+ $div_arg = new math\DivArgs();
+ $dividend = 2 * $i + 1;
+ $divisor = 3;
+ $div_arg->setDividend($dividend);
+ $div_arg->setDivisor($divisor);
+ $call->write($div_arg);
+ p("client writing: $dividend / $divisor");
+ $response = $call->read();
+ p(sprintf('server writing: quotient = %d, remainder = %d',
$response->getQuotient(), $response->getRemainder()));
}
$call->writesDone();
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index 6670ef3ab9..3019866561 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -31,9 +31,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-require_once realpath(dirname(__FILE__) . '/../../vendor/autoload.php');
+require_once realpath(dirname(__FILE__).'/../../vendor/autoload.php');
require 'empty.php';
-require 'message_set.php';
require 'messages.php';
require 'test.php';
use Google\Auth\CredentialsLoader;
@@ -42,395 +41,427 @@ use GuzzleHttp\ClientInterface;
/**
* Assertion function that always exits with an error code if the assertion is
- * falsy
+ * falsy.
+ *
* @param $value Assertion value. Should be true.
* @param $error_message Message to display if the assertion is false
*/
-function hardAssert($value, $error_message) {
- if (!$value) {
- echo $error_message . "\n";
- exit(1);
- }
+function hardAssert($value, $error_message)
+{
+ if (!$value) {
+ echo $error_message."\n";
+ exit(1);
+ }
}
/**
* Run the empty_unary test.
+ *
* @param $stub Stub object that has service methods
*/
-function emptyUnary($stub) {
- list($result, $status) = $stub->EmptyCall(new grpc\testing\EmptyMessage())->wait();
- hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully');
- hardAssert($result !== null, 'Call completed with a null response');
+function emptyUnary($stub)
+{
+ list($result, $status) = $stub->EmptyCall(new grpc\testing\EmptyMessage())->wait();
+ hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully');
+ hardAssert($result !== null, 'Call completed with a null response');
}
/**
* Run the large_unary test.
+ *
* @param $stub Stub object that has service methods
*/
-function largeUnary($stub) {
- performLargeUnary($stub);
+function largeUnary($stub)
+{
+ performLargeUnary($stub);
}
/**
- * Shared code between large unary test and auth test
+ * 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,
- $metadata = array()) {
- $request_len = 271828;
- $response_len = 314159;
-
- $request = new grpc\testing\SimpleRequest();
- $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
- $request->setResponseSize($response_len);
- $payload = new grpc\testing\Payload();
- $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, $metadata)->wait();
- hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully');
- hardAssert($result !== null, 'Call returned a null response');
- $payload = $result->getPayload();
- hardAssert($payload->getType() === grpc\testing\PayloadType::COMPRESSABLE,
+ $metadata = [])
+{
+ $request_len = 271828;
+ $response_len = 314159;
+
+ $request = new grpc\testing\SimpleRequest();
+ $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
+ $request->setResponseSize($response_len);
+ $payload = new grpc\testing\Payload();
+ $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, $metadata)->wait();
+ hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully');
+ hardAssert($result !== null, 'Call returned a null response');
+ $payload = $result->getPayload();
+ hardAssert($payload->getType() === grpc\testing\PayloadType::COMPRESSABLE,
'Payload had the wrong type');
- hardAssert(strlen($payload->getBody()) === $response_len,
+ hardAssert(strlen($payload->getBody()) === $response_len,
'Payload had the wrong length');
- hardAssert($payload->getBody() === str_repeat("\0", $response_len),
+ hardAssert($payload->getBody() === str_repeat("\0", $response_len),
'Payload had the wrong content');
- return $result;
+
+ return $result;
}
/**
* Run the service account credentials auth test.
+ *
* @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(CredentialsLoader::ENV_VAR)),
- true);
- $result = performLargeUnary($stub, $fillUsername=true, $fillOauthScope=true);
- hardAssert($result->getUsername() == $jsonKey['client_email'],
+function serviceAccountCreds($stub, $args)
+{
+ if (!array_key_exists('oauth_scope', $args)) {
+ throw new Exception('Missing oauth scope');
+ }
+ $jsonKey = json_decode(
+ file_get_contents(getenv(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,
+ hardAssert(strpos($args['oauth_scope'], $result->getOauthScope()) !== false,
'invalid oauth scope returned');
}
/**
* Run the compute engine credentials auth test.
- * Has not been run from gcloud as of 2015-05-05
+ * Has not been run from gcloud as of 2015-05-05.
+ *
* @param $stub Stub object that has service methods
* @param $args array command line args
*/
-function computeEngineCreds($stub, $args) {
- if (!array_key_exists('oauth_scope', $args)) {
- throw new Exception('Missing oauth scope');
- }
- if (!array_key_exists('default_service_account', $args)) {
- throw new Exception('Missing default_service_account');
- }
- $result = performLargeUnary($stub, $fillUsername=true, $fillOauthScope=true);
- hardAssert($args['default_service_account'] == $result->getUsername(),
+function computeEngineCreds($stub, $args)
+{
+ if (!array_key_exists('oauth_scope', $args)) {
+ throw new Exception('Missing oauth scope');
+ }
+ if (!array_key_exists('default_service_account', $args)) {
+ throw new Exception('Missing default_service_account');
+ }
+ $result = performLargeUnary($stub, $fillUsername = true, $fillOauthScope = true);
+ hardAssert($args['default_service_account'] == $result->getUsername(),
'invalid email returned');
}
/**
* Run the jwt token credentials auth test.
+ *
* @param $stub Stub object that has service methods
* @param $args array command line args
*/
-function jwtTokenCreds($stub, $args) {
- $jsonKey = json_decode(
- file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
- true);
- $result = performLargeUnary($stub, $fillUsername=true, $fillOauthScope=true);
- hardAssert($result->getUsername() == $jsonKey['client_email'],
+function jwtTokenCreds($stub, $args)
+{
+ $jsonKey = json_decode(
+ file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
+ true);
+ $result = performLargeUnary($stub, $fillUsername = true, $fillOauthScope = true);
+ hardAssert($result->getUsername() == $jsonKey['client_email'],
'invalid email returned');
}
/**
* Run the oauth2_auth_token auth test.
+ *
* @param $stub Stub object that has service methods
* @param $args array command line args
*/
-function oauth2AuthToken($stub, $args) {
- $jsonKey = json_decode(
- file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
- true);
- $result = performLargeUnary($stub, $fillUsername=true, $fillOauthScope=true);
- hardAssert($result->getUsername() == $jsonKey['client_email'],
+function oauth2AuthToken($stub, $args)
+{
+ $jsonKey = json_decode(
+ file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
+ true);
+ $result = performLargeUnary($stub, $fillUsername = true, $fillOauthScope = true);
+ hardAssert($result->getUsername() == $jsonKey['client_email'],
'invalid email returned');
}
/**
* Run the per_rpc_creds auth test.
+ *
* @param $stub Stub object that has service methods
* @param $args array command line args
*/
-function perRpcCreds($stub, $args) {
- $jsonKey = json_decode(
- file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
- true);
- $auth_credentials = ApplicationDefaultCredentials::getCredentials(
- $args['oauth_scope']
- );
- $token = $auth_credentials->fetchAuthToken();
- $metadata = array(CredentialsLoader::AUTH_METADATA_KEY =>
- array(sprintf("%s %s",
- $token['token_type'],
- $token['access_token'])));
- $result = performLargeUnary($stub, $fillUsername=true, $fillOauthScope=true,
+function perRpcCreds($stub, $args)
+{
+ $jsonKey = json_decode(
+ file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
+ true);
+ $auth_credentials = ApplicationDefaultCredentials::getCredentials(
+ $args['oauth_scope']
+ );
+ $token = $auth_credentials->fetchAuthToken();
+ $metadata = [CredentialsLoader::AUTH_METADATA_KEY => [sprintf('%s %s',
+ $token['token_type'],
+ $token['access_token'])]];
+ $result = performLargeUnary($stub, $fillUsername = true, $fillOauthScope = true,
$metadata);
- hardAssert($result->getUsername() == $jsonKey['client_email'],
+ hardAssert($result->getUsername() == $jsonKey['client_email'],
'invalid email returned');
}
/**
* Run the client_streaming test.
+ *
* @param $stub Stub object that has service methods
*/
-function clientStreaming($stub) {
- $request_lengths = array(27182, 8, 1828, 45904);
-
- $requests = array_map(
- function($length) {
- $request = new grpc\testing\StreamingInputCallRequest();
- $payload = new grpc\testing\Payload();
- $payload->setBody(str_repeat("\0", $length));
- $request->setPayload($payload);
- return $request;
- }, $request_lengths);
-
- $call = $stub->StreamingInputCall();
- foreach ($requests as $request) {
- $call->write($request);
- }
- list($result, $status) = $call->wait();
- hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully');
- hardAssert($result->getAggregatedPayloadSize() === 74922,
+function clientStreaming($stub)
+{
+ $request_lengths = [27182, 8, 1828, 45904];
+
+ $requests = array_map(
+ function ($length) {
+ $request = new grpc\testing\StreamingInputCallRequest();
+ $payload = new grpc\testing\Payload();
+ $payload->setBody(str_repeat("\0", $length));
+ $request->setPayload($payload);
+
+ return $request;
+ }, $request_lengths);
+
+ $call = $stub->StreamingInputCall();
+ foreach ($requests as $request) {
+ $call->write($request);
+ }
+ list($result, $status) = $call->wait();
+ hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully');
+ hardAssert($result->getAggregatedPayloadSize() === 74922,
'aggregated_payload_size was incorrect');
}
/**
* Run the server_streaming test.
+ *
* @param $stub Stub object that has service methods.
*/
-function serverStreaming($stub) {
- $sizes = array(31415, 9, 2653, 58979);
-
- $request = new grpc\testing\StreamingOutputCallRequest();
- $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
- foreach($sizes as $size) {
- $response_parameters = new grpc\testing\ResponseParameters();
- $response_parameters->setSize($size);
- $request->addResponseParameters($response_parameters);
- }
+function serverStreaming($stub)
+{
+ $sizes = [31415, 9, 2653, 58979];
- $call = $stub->StreamingOutputCall($request);
- $i = 0;
- foreach($call->responses() as $value) {
- hardAssert($i < 4, 'Too many responses');
- $payload = $value->getPayload();
- hardAssert($payload->getType() === grpc\testing\PayloadType::COMPRESSABLE,
- 'Payload ' . $i . ' had the wrong type');
- hardAssert(strlen($payload->getBody()) === $sizes[$i],
- 'Response ' . $i . ' had the wrong length');
- $i += 1;
- }
- hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
+ $request = new grpc\testing\StreamingOutputCallRequest();
+ $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
+ foreach ($sizes as $size) {
+ $response_parameters = new grpc\testing\ResponseParameters();
+ $response_parameters->setSize($size);
+ $request->addResponseParameters($response_parameters);
+ }
+
+ $call = $stub->StreamingOutputCall($request);
+ $i = 0;
+ foreach ($call->responses() as $value) {
+ hardAssert($i < 4, 'Too many responses');
+ $payload = $value->getPayload();
+ hardAssert($payload->getType() === grpc\testing\PayloadType::COMPRESSABLE,
+ 'Payload '.$i.' had the wrong type');
+ hardAssert(strlen($payload->getBody()) === $sizes[$i],
+ 'Response '.$i.' had the wrong length');
+ $i += 1;
+ }
+ hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
'Call did not complete successfully');
}
/**
* Run the ping_pong test.
+ *
* @param $stub Stub object that has service methods.
*/
-function pingPong($stub) {
- $request_lengths = array(27182, 8, 1828, 45904);
- $response_lengths = array(31415, 9, 2653, 58979);
-
- $call = $stub->FullDuplexCall();
- for($i = 0; $i < 4; $i++) {
- $request = new grpc\testing\StreamingOutputCallRequest();
- $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
- $response_parameters = new grpc\testing\ResponseParameters();
- $response_parameters->setSize($response_lengths[$i]);
- $request->addResponseParameters($response_parameters);
- $payload = new grpc\testing\Payload();
- $payload->setBody(str_repeat("\0", $request_lengths[$i]));
- $request->setPayload($payload);
-
- $call->write($request);
- $response = $call->read();
+function pingPong($stub)
+{
+ $request_lengths = [27182, 8, 1828, 45904];
+ $response_lengths = [31415, 9, 2653, 58979];
+
+ $call = $stub->FullDuplexCall();
+ for ($i = 0; $i < 4; ++$i) {
+ $request = new grpc\testing\StreamingOutputCallRequest();
+ $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
+ $response_parameters = new grpc\testing\ResponseParameters();
+ $response_parameters->setSize($response_lengths[$i]);
+ $request->addResponseParameters($response_parameters);
+ $payload = new grpc\testing\Payload();
+ $payload->setBody(str_repeat("\0", $request_lengths[$i]));
+ $request->setPayload($payload);
- hardAssert($response !== null, 'Server returned too few responses');
- $payload = $response->getPayload();
- hardAssert($payload->getType() === grpc\testing\PayloadType::COMPRESSABLE,
- 'Payload ' . $i . ' had the wrong type');
- hardAssert(strlen($payload->getBody()) === $response_lengths[$i],
- 'Payload ' . $i . ' had the wrong length');
- }
- $call->writesDone();
- hardAssert($call->read() === null, 'Server returned too many responses');
- hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
+ $call->write($request);
+ $response = $call->read();
+
+ hardAssert($response !== null, 'Server returned too few responses');
+ $payload = $response->getPayload();
+ hardAssert($payload->getType() === grpc\testing\PayloadType::COMPRESSABLE,
+ 'Payload '.$i.' had the wrong type');
+ hardAssert(strlen($payload->getBody()) === $response_lengths[$i],
+ 'Payload '.$i.' had the wrong length');
+ }
+ $call->writesDone();
+ hardAssert($call->read() === null, 'Server returned too many responses');
+ hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
'Call did not complete successfully');
}
/**
* Run the empty_stream test.
+ *
* @param $stub Stub object that has service methods.
*/
-function emptyStream($stub) {
- $call = $stub->FullDuplexCall();
- $call->writesDone();
- hardAssert($call->read() === null, 'Server returned too many responses');
- hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
+function emptyStream($stub)
+{
+ $call = $stub->FullDuplexCall();
+ $call->writesDone();
+ hardAssert($call->read() === null, 'Server returned too many responses');
+ hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
'Call did not complete successfully');
}
/**
* Run the cancel_after_begin test.
+ *
* @param $stub Stub object that has service methods.
*/
-function cancelAfterBegin($stub) {
- $call = $stub->StreamingInputCall();
- $call->cancel();
- list($result, $status) = $call->wait();
- hardAssert($status->code === Grpc\STATUS_CANCELLED,
+function cancelAfterBegin($stub)
+{
+ $call = $stub->StreamingInputCall();
+ $call->cancel();
+ list($result, $status) = $call->wait();
+ hardAssert($status->code === Grpc\STATUS_CANCELLED,
'Call status was not CANCELLED');
}
/**
* Run the cancel_after_first_response test.
+ *
* @param $stub Stub object that has service methods.
*/
-function cancelAfterFirstResponse($stub) {
- $call = $stub->FullDuplexCall();
- $request = new grpc\testing\StreamingOutputCallRequest();
- $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
- $response_parameters = new grpc\testing\ResponseParameters();
- $response_parameters->setSize(31415);
- $request->addResponseParameters($response_parameters);
- $payload = new grpc\testing\Payload();
- $payload->setBody(str_repeat("\0", 27182));
- $request->setPayload($payload);
-
- $call->write($request);
- $response = $call->read();
-
- $call->cancel();
- hardAssert($call->getStatus()->code === Grpc\STATUS_CANCELLED,
+function cancelAfterFirstResponse($stub)
+{
+ $call = $stub->FullDuplexCall();
+ $request = new grpc\testing\StreamingOutputCallRequest();
+ $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
+ $response_parameters = new grpc\testing\ResponseParameters();
+ $response_parameters->setSize(31415);
+ $request->addResponseParameters($response_parameters);
+ $payload = new grpc\testing\Payload();
+ $payload->setBody(str_repeat("\0", 27182));
+ $request->setPayload($payload);
+
+ $call->write($request);
+ $response = $call->read();
+
+ $call->cancel();
+ hardAssert($call->getStatus()->code === Grpc\STATUS_CANCELLED,
'Call status was not CANCELLED');
}
-function timeoutOnSleepingServer($stub) {
- $call = $stub->FullDuplexCall(array('timeout' => 1000));
- $request = new grpc\testing\StreamingOutputCallRequest();
- $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
- $response_parameters = new grpc\testing\ResponseParameters();
- $response_parameters->setSize(8);
- $request->addResponseParameters($response_parameters);
- $payload = new grpc\testing\Payload();
- $payload->setBody(str_repeat("\0", 9));
- $request->setPayload($payload);
-
- $call->write($request);
- $response = $call->read();
-
- hardAssert($call->getStatus()->code === Grpc\STATUS_DEADLINE_EXCEEDED,
+function timeoutOnSleepingServer($stub)
+{
+ $call = $stub->FullDuplexCall(['timeout' => 1000]);
+ $request = new grpc\testing\StreamingOutputCallRequest();
+ $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
+ $response_parameters = new grpc\testing\ResponseParameters();
+ $response_parameters->setSize(8);
+ $request->addResponseParameters($response_parameters);
+ $payload = new grpc\testing\Payload();
+ $payload->setBody(str_repeat("\0", 9));
+ $request->setPayload($payload);
+
+ $call->write($request);
+ $response = $call->read();
+
+ hardAssert($call->getStatus()->code === Grpc\STATUS_DEADLINE_EXCEEDED,
'Call status was not DEADLINE_EXCEEDED');
}
-$args = getopt('', array('server_host:', 'server_port:', 'test_case:',
- 'use_tls::', 'use_test_ca::',
- 'server_host_override:', 'oauth_scope:',
- 'default_service_account:'));
+$args = getopt('', ['server_host:', 'server_port:', 'test_case:',
+ 'use_tls::', 'use_test_ca::',
+ 'server_host_override:', 'oauth_scope:',
+ 'default_service_account:', ]);
if (!array_key_exists('server_host', $args)) {
- throw new Exception('Missing argument: --server_host is required');
+ throw new Exception('Missing argument: --server_host is required');
}
if (!array_key_exists('server_port', $args)) {
- throw new Exception('Missing argument: --server_port is required');
+ throw new Exception('Missing argument: --server_port is required');
}
if (!array_key_exists('test_case', $args)) {
- throw new Exception('Missing argument: --test_case is required');
+ throw new Exception('Missing argument: --test_case is required');
}
if ($args['server_port'] == 443) {
- $server_address = $args['server_host'];
+ $server_address = $args['server_host'];
} else {
- $server_address = $args['server_host'] . ':' . $args['server_port'];
+ $server_address = $args['server_host'].':'.$args['server_port'];
}
$test_case = $args['test_case'];
$host_override = 'foo.test.google.fr';
if (array_key_exists('server_host_override', $args)) {
- $host_override = $args['server_host_override'];
+ $host_override = $args['server_host_override'];
}
$use_tls = false;
if (array_key_exists('use_tls', $args) &&
$args['use_tls'] != 'false') {
- $use_tls = true;
+ $use_tls = true;
}
$use_test_ca = false;
if (array_key_exists('use_test_ca', $args) &&
$args['use_test_ca'] != 'false') {
- $use_test_ca = true;
+ $use_test_ca = true;
}
$opts = [];
if ($use_tls) {
- if ($use_test_ca) {
- $ssl_cert_file = dirname(__FILE__) . '/../data/ca.pem';
- } else {
- $ssl_cert_file = getenv('SSL_CERT_FILE');
- }
- $ssl_credentials = Grpc\Credentials::createSsl(
- file_get_contents($ssl_cert_file));
- $opts['credentials'] = $ssl_credentials;
- $opts['grpc.ssl_target_name_override'] = $host_override;
+ if ($use_test_ca) {
+ $ssl_credentials = Grpc\Credentials::createSsl(
+ file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
+ } else {
+ $ssl_credentials = Grpc\Credentials::createSsl();
+ }
+ $opts['credentials'] = $ssl_credentials;
+ $opts['grpc.ssl_target_name_override'] = $host_override;
}
-if (in_array($test_case, array('service_account_creds',
- 'compute_engine_creds', 'jwt_token_creds'))) {
- if ($test_case == 'jwt_token_creds') {
- $auth_credentials = ApplicationDefaultCredentials::getCredentials();
- } else {
- $auth_credentials = ApplicationDefaultCredentials::getCredentials(
- $args['oauth_scope']
- );
- }
- $opts['update_metadata'] = $auth_credentials->getUpdateMetadataFunc();
+if (in_array($test_case, ['service_account_creds',
+ 'compute_engine_creds', 'jwt_token_creds', ])) {
+ if ($test_case == 'jwt_token_creds') {
+ $auth_credentials = ApplicationDefaultCredentials::getCredentials();
+ } else {
+ $auth_credentials = ApplicationDefaultCredentials::getCredentials(
+ $args['oauth_scope']
+ );
+ }
+ $opts['update_metadata'] = $auth_credentials->getUpdateMetadataFunc();
}
if ($test_case == 'oauth2_auth_token') {
- $auth_credentials = ApplicationDefaultCredentials::getCredentials(
- $args['oauth_scope']
- );
- $token = $auth_credentials->fetchAuthToken();
- $update_metadata =
- function($metadata,
- $authUri = null,
- ClientInterface $client = null) use ($token) {
- $metadata_copy = $metadata;
- $metadata_copy[CredentialsLoader::AUTH_METADATA_KEY] =
- array(sprintf("%s %s",
- $token['token_type'],
- $token['access_token']));
- return $metadata_copy;
- };
- $opts['update_metadata'] = $update_metadata;
+ $auth_credentials = ApplicationDefaultCredentials::getCredentials(
+ $args['oauth_scope']
+ );
+ $token = $auth_credentials->fetchAuthToken();
+ $update_metadata =
+ function ($metadata,
+ $authUri = null,
+ ClientInterface $client = null) use ($token) {
+ $metadata_copy = $metadata;
+ $metadata_copy[CredentialsLoader::AUTH_METADATA_KEY] =
+ [sprintf('%s %s',
+ $token['token_type'],
+ $token['access_token'])];
+
+ return $metadata_copy;
+ };
+ $opts['update_metadata'] = $update_metadata;
}
$stub = new grpc\testing\TestServiceClient($server_address, $opts);
@@ -439,49 +470,49 @@ echo "Connecting to $server_address\n";
echo "Running test case $test_case\n";
switch ($test_case) {
- case 'empty_unary':
- emptyUnary($stub);
- break;
- case 'large_unary':
- largeUnary($stub);
- break;
- case 'client_streaming':
- clientStreaming($stub);
- break;
- case 'server_streaming':
- serverStreaming($stub);
- break;
- case 'ping_pong':
- pingPong($stub);
- break;
- case 'empty_stream':
- emptyStream($stub);
- break;
- case 'cancel_after_begin':
- cancelAfterBegin($stub);
- break;
- case 'cancel_after_first_response':
- cancelAfterFirstResponse($stub);
- break;
- case 'timeout_on_sleeping_server':
- timeoutOnSleepingServer($stub);
- break;
- case 'service_account_creds':
- serviceAccountCreds($stub, $args);
- break;
- case 'compute_engine_creds':
- computeEngineCreds($stub, $args);
- break;
- case 'jwt_token_creds':
- jwtTokenCreds($stub, $args);
- break;
- case 'oauth2_auth_token':
- oauth2AuthToken($stub, $args);
- break;
- case 'per_rpc_creds':
- perRpcCreds($stub, $args);
- break;
- default:
- echo "Unsupported test case $test_case\n";
- exit(1);
+ case 'empty_unary':
+ emptyUnary($stub);
+ break;
+ case 'large_unary':
+ largeUnary($stub);
+ break;
+ case 'client_streaming':
+ clientStreaming($stub);
+ break;
+ case 'server_streaming':
+ serverStreaming($stub);
+ break;
+ case 'ping_pong':
+ pingPong($stub);
+ break;
+ case 'empty_stream':
+ emptyStream($stub);
+ break;
+ case 'cancel_after_begin':
+ cancelAfterBegin($stub);
+ break;
+ case 'cancel_after_first_response':
+ cancelAfterFirstResponse($stub);
+ break;
+ case 'timeout_on_sleeping_server':
+ timeoutOnSleepingServer($stub);
+ break;
+ case 'service_account_creds':
+ serviceAccountCreds($stub, $args);
+ break;
+ case 'compute_engine_creds':
+ computeEngineCreds($stub, $args);
+ break;
+ case 'jwt_token_creds':
+ jwtTokenCreds($stub, $args);
+ break;
+ case 'oauth2_auth_token':
+ oauth2AuthToken($stub, $args);
+ break;
+ case 'per_rpc_creds':
+ perRpcCreds($stub, $args);
+ break;
+ default:
+ echo "Unsupported test case $test_case\n";
+ exit(1);
}
diff --git a/src/php/tests/interop/message_set.php b/src/php/tests/interop/message_set.php
deleted file mode 100755
index c35c6d74b2..0000000000
--- a/src/php/tests/interop/message_set.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0
-// Source: net/proto2/bridge/proto/message_set.proto
-// Date: 2014-12-03 22:02:20
-
-namespace proto2\bridge {
-
- class MessageSet extends \DrSlump\Protobuf\Message {
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'proto2.bridge.MessageSet');
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
- }
-}
-
diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php
index caff15ee11..3b697b50c3 100755
--- a/src/php/tests/unit_tests/CallTest.php
+++ b/src/php/tests/unit_tests/CallTest.php
@@ -31,56 +31,64 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-class CallTest extends PHPUnit_Framework_TestCase{
- static $server;
- static $port;
+class CallTest extends PHPUnit_Framework_TestCase
+{
+ public static $server;
+ public static $port;
- public static function setUpBeforeClass() {
- self::$server = new Grpc\Server([]);
- self::$port = self::$server->addHttp2Port('0.0.0.0:0');
- }
+ public static function setUpBeforeClass()
+ {
+ self::$server = new Grpc\Server([]);
+ self::$port = self::$server->addHttp2Port('0.0.0.0:0');
+ }
- public function setUp() {
- $this->channel = new Grpc\Channel('localhost:' . self::$port, []);
- $this->call = new Grpc\Call($this->channel,
- '/foo',
- Grpc\Timeval::infFuture());
- }
+ public function setUp()
+ {
+ $this->channel = new Grpc\Channel('localhost:'.self::$port, []);
+ $this->call = new Grpc\Call($this->channel,
+ '/foo',
+ Grpc\Timeval::infFuture());
+ }
- public function testAddEmptyMetadata() {
- $batch = [
- Grpc\OP_SEND_INITIAL_METADATA => []
- ];
- $result = $this->call->startBatch($batch);
- $this->assertTrue($result->send_metadata);
- }
+ public function testAddEmptyMetadata()
+ {
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ ];
+ $result = $this->call->startBatch($batch);
+ $this->assertTrue($result->send_metadata);
+ }
- public function testAddSingleMetadata() {
- $batch = [
- Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value']]
- ];
- $result = $this->call->startBatch($batch);
- $this->assertTrue($result->send_metadata);
- }
+ public function testAddSingleMetadata()
+ {
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value']],
+ ];
+ $result = $this->call->startBatch($batch);
+ $this->assertTrue($result->send_metadata);
+ }
- public function testAddMultiValueMetadata() {
- $batch = [
- Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value1', 'value2']]
- ];
- $result = $this->call->startBatch($batch);
- $this->assertTrue($result->send_metadata);
- }
+ public function testAddMultiValueMetadata()
+ {
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value1', 'value2']],
+ ];
+ $result = $this->call->startBatch($batch);
+ $this->assertTrue($result->send_metadata);
+ }
- public function testAddSingleAndMultiValueMetadata() {
- $batch = [
- Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'],
- 'key2' => ['value2', 'value3']]
- ];
- $result = $this->call->startBatch($batch);
- $this->assertTrue($result->send_metadata);
- }
+ public function testAddSingleAndMultiValueMetadata()
+ {
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'],
+ 'key2' => ['value2', 'value3'], ],
+ ];
+ $result = $this->call->startBatch($batch);
+ $this->assertTrue($result->send_metadata);
+ }
- public function testGetPeer() {
- $this->assertTrue(is_string($this->call->getPeer()));
- }
+ public function testGetPeer()
+ {
+ $this->assertTrue(is_string($this->call->getPeer()));
+ }
}
diff --git a/src/php/tests/unit_tests/EndToEndTest.php b/src/php/tests/unit_tests/EndToEndTest.php
index b65366233a..5a38262451 100755
--- a/src/php/tests/unit_tests/EndToEndTest.php
+++ b/src/php/tests/unit_tests/EndToEndTest.php
@@ -31,217 +31,228 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-class EndToEndTest extends PHPUnit_Framework_TestCase{
- public function setUp() {
- $this->server = new Grpc\Server([]);
- $this->port = $this->server->addHttp2Port('0.0.0.0:0');
- $this->channel = new Grpc\Channel('localhost:' . $this->port, []);
- $this->server->start();
- }
-
- public function tearDown() {
- unset($this->channel);
- unset($this->server);
- }
-
- public function testSimpleRequestBody() {
- $deadline = Grpc\Timeval::infFuture();
- $status_text = 'xyz';
- $call = new Grpc\Call($this->channel,
- 'dummy_method',
- $deadline);
-
- $event = $call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_CLOSE_FROM_CLIENT => true
- ]);
-
- $this->assertTrue($event->send_metadata);
- $this->assertTrue($event->send_close);
-
- $event = $this->server->requestCall();
- $this->assertSame('dummy_method', $event->method);
- $server_call = $event->call;
-
- $event = $server_call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_STATUS_FROM_SERVER => [
- 'metadata' => [],
- 'code' => Grpc\STATUS_OK,
- 'details' => $status_text
- ],
- Grpc\OP_RECV_CLOSE_ON_SERVER => true
- ]);
-
- $this->assertTrue($event->send_metadata);
- $this->assertTrue($event->send_status);
- $this->assertFalse($event->cancelled);
-
- $event = $call->startBatch([
- Grpc\OP_RECV_INITIAL_METADATA => true,
- Grpc\OP_RECV_STATUS_ON_CLIENT => true
- ]);
-
- $status = $event->status;
- $this->assertSame([], $status->metadata);
- $this->assertSame(Grpc\STATUS_OK, $status->code);
- $this->assertSame($status_text, $status->details);
-
- unset($call);
- unset($server_call);
- }
-
- public function testMessageWriteFlags() {
- $deadline = Grpc\Timeval::infFuture();
- $req_text = 'message_write_flags_test';
- $status_text = 'xyz';
- $call = new Grpc\Call($this->channel,
- 'dummy_method',
- $deadline);
-
- $event = $call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_MESSAGE => ['message' => $req_text,
- 'flags' => Grpc\WRITE_NO_COMPRESS],
- Grpc\OP_SEND_CLOSE_FROM_CLIENT => true
- ]);
-
- $this->assertTrue($event->send_metadata);
- $this->assertTrue($event->send_close);
-
- $event = $this->server->requestCall();
- $this->assertSame('dummy_method', $event->method);
- $server_call = $event->call;
-
- $event = $server_call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_STATUS_FROM_SERVER => [
- 'metadata' => [],
- 'code' => Grpc\STATUS_OK,
- 'details' => $status_text
- ],
- ]);
-
- $event = $call->startBatch([
- Grpc\OP_RECV_INITIAL_METADATA => true,
- Grpc\OP_RECV_STATUS_ON_CLIENT => true
- ]);
-
- $status = $event->status;
- $this->assertSame([], $status->metadata);
- $this->assertSame(Grpc\STATUS_OK, $status->code);
- $this->assertSame($status_text, $status->details);
-
- unset($call);
- unset($server_call);
- }
-
- public function testClientServerFullRequestResponse() {
- $deadline = Grpc\Timeval::infFuture();
- $req_text = 'client_server_full_request_response';
- $reply_text = 'reply:client_server_full_request_response';
- $status_text = 'status:client_server_full_response_text';
-
- $call = new Grpc\Call($this->channel,
- 'dummy_method',
- $deadline);
-
- $event = $call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
- Grpc\OP_SEND_MESSAGE => ['message' => $req_text],
- ]);
-
- $this->assertTrue($event->send_metadata);
- $this->assertTrue($event->send_close);
- $this->assertTrue($event->send_message);
-
- $event = $this->server->requestCall();
- $this->assertSame('dummy_method', $event->method);
- $server_call = $event->call;
-
- $event = $server_call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_MESSAGE => ['message' => $reply_text],
- Grpc\OP_SEND_STATUS_FROM_SERVER => [
- 'metadata' => [],
- 'code' => Grpc\STATUS_OK,
- 'details' => $status_text
- ],
- Grpc\OP_RECV_MESSAGE => true,
- Grpc\OP_RECV_CLOSE_ON_SERVER => true,
- ]);
-
- $this->assertTrue($event->send_metadata);
- $this->assertTrue($event->send_status);
- $this->assertTrue($event->send_message);
- $this->assertFalse($event->cancelled);
- $this->assertSame($req_text, $event->message);
-
- $event = $call->startBatch([
- Grpc\OP_RECV_INITIAL_METADATA => true,
- Grpc\OP_RECV_MESSAGE => true,
- Grpc\OP_RECV_STATUS_ON_CLIENT => true,
- ]);
-
- $this->assertSame([], $event->metadata);
- $this->assertSame($reply_text, $event->message);
- $status = $event->status;
- $this->assertSame([], $status->metadata);
- $this->assertSame(Grpc\STATUS_OK, $status->code);
- $this->assertSame($status_text, $status->details);
-
- unset($call);
- unset($server_call);
- }
-
- public function testGetTarget() {
- $this->assertTrue(is_string($this->channel->getTarget()));
- }
-
- public function testGetConnectivityState() {
- $this->assertTrue($this->channel->getConnectivityState() == Grpc\CHANNEL_IDLE);
- }
-
- public function testWatchConnectivityStateFailed() {
- $idle_state = $this->channel->getConnectivityState();
- $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
-
- $now = Grpc\Timeval::now();
- $delta = new Grpc\Timeval(500000); // should timeout
- $deadline = $now->add($delta);
-
- $this->assertFalse($this->channel->watchConnectivityState(
+class EndToEndTest extends PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ $this->server = new Grpc\Server([]);
+ $this->port = $this->server->addHttp2Port('0.0.0.0:0');
+ $this->channel = new Grpc\Channel('localhost:'.$this->port, []);
+ $this->server->start();
+ }
+
+ public function tearDown()
+ {
+ unset($this->channel);
+ unset($this->server);
+ }
+
+ public function testSimpleRequestBody()
+ {
+ $deadline = Grpc\Timeval::infFuture();
+ $status_text = 'xyz';
+ $call = new Grpc\Call($this->channel,
+ 'dummy_method',
+ $deadline);
+
+ $event = $call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+
+ $event = $this->server->requestCall();
+ $this->assertSame('dummy_method', $event->method);
+ $server_call = $event->call;
+
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text,
+ ],
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertFalse($event->cancelled);
+
+ $event = $call->startBatch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
+ $this->assertSame(Grpc\STATUS_OK, $status->code);
+ $this->assertSame($status_text, $status->details);
+
+ unset($call);
+ unset($server_call);
+ }
+
+ public function testMessageWriteFlags()
+ {
+ $deadline = Grpc\Timeval::infFuture();
+ $req_text = 'message_write_flags_test';
+ $status_text = 'xyz';
+ $call = new Grpc\Call($this->channel,
+ 'dummy_method',
+ $deadline);
+
+ $event = $call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_MESSAGE => ['message' => $req_text,
+ 'flags' => Grpc\WRITE_NO_COMPRESS, ],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+
+ $event = $this->server->requestCall();
+ $this->assertSame('dummy_method', $event->method);
+ $server_call = $event->call;
+
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text,
+ ],
+ ]);
+
+ $event = $call->startBatch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
+ $this->assertSame(Grpc\STATUS_OK, $status->code);
+ $this->assertSame($status_text, $status->details);
+
+ unset($call);
+ unset($server_call);
+ }
+
+ public function testClientServerFullRequestResponse()
+ {
+ $deadline = Grpc\Timeval::infFuture();
+ $req_text = 'client_server_full_request_response';
+ $reply_text = 'reply:client_server_full_request_response';
+ $status_text = 'status:client_server_full_response_text';
+
+ $call = new Grpc\Call($this->channel,
+ 'dummy_method',
+ $deadline);
+
+ $event = $call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+ Grpc\OP_SEND_MESSAGE => ['message' => $req_text],
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+ $this->assertTrue($event->send_message);
+
+ $event = $this->server->requestCall();
+ $this->assertSame('dummy_method', $event->method);
+ $server_call = $event->call;
+
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_MESSAGE => ['message' => $reply_text],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text,
+ ],
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertTrue($event->send_message);
+ $this->assertFalse($event->cancelled);
+ $this->assertSame($req_text, $event->message);
+
+ $event = $call->startBatch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $this->assertSame($reply_text, $event->message);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
+ $this->assertSame(Grpc\STATUS_OK, $status->code);
+ $this->assertSame($status_text, $status->details);
+
+ unset($call);
+ unset($server_call);
+ }
+
+ public function testGetTarget()
+ {
+ $this->assertTrue(is_string($this->channel->getTarget()));
+ }
+
+ public function testGetConnectivityState()
+ {
+ $this->assertTrue($this->channel->getConnectivityState() == Grpc\CHANNEL_IDLE);
+ }
+
+ public function testWatchConnectivityStateFailed()
+ {
+ $idle_state = $this->channel->getConnectivityState();
+ $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
+
+ $now = Grpc\Timeval::now();
+ $delta = new Grpc\Timeval(500000); // should timeout
+ $deadline = $now->add($delta);
+
+ $this->assertFalse($this->channel->watchConnectivityState(
$idle_state, $deadline));
- }
+ }
- public function testWatchConnectivityStateSuccess() {
- $idle_state = $this->channel->getConnectivityState(true);
- $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
+ public function testWatchConnectivityStateSuccess()
+ {
+ $idle_state = $this->channel->getConnectivityState(true);
+ $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
- $now = Grpc\Timeval::now();
- $delta = new Grpc\Timeval(3000000); // should finish well before
- $deadline = $now->add($delta);
+ $now = Grpc\Timeval::now();
+ $delta = new Grpc\Timeval(3000000); // should finish well before
+ $deadline = $now->add($delta);
- $this->assertTrue($this->channel->watchConnectivityState(
+ $this->assertTrue($this->channel->watchConnectivityState(
$idle_state, $deadline));
- $new_state = $this->channel->getConnectivityState();
- $this->assertTrue($idle_state != $new_state);
- }
+ $new_state = $this->channel->getConnectivityState();
+ $this->assertTrue($idle_state != $new_state);
+ }
- public function testWatchConnectivityStateDoNothing() {
- $idle_state = $this->channel->getConnectivityState();
- $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
+ public function testWatchConnectivityStateDoNothing()
+ {
+ $idle_state = $this->channel->getConnectivityState();
+ $this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
- $now = Grpc\Timeval::now();
- $delta = new Grpc\Timeval(100000);
- $deadline = $now->add($delta);
+ $now = Grpc\Timeval::now();
+ $delta = new Grpc\Timeval(100000);
+ $deadline = $now->add($delta);
- $this->assertFalse($this->channel->watchConnectivityState(
+ $this->assertFalse($this->channel->watchConnectivityState(
$idle_state, $deadline));
- $new_state = $this->channel->getConnectivityState();
- $this->assertTrue($new_state == Grpc\CHANNEL_IDLE);
- }
+ $new_state = $this->channel->getConnectivityState();
+ $this->assertTrue($new_state == Grpc\CHANNEL_IDLE);
+ }
}
diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php
index d7fca14a0d..e66bde376c 100755
--- a/src/php/tests/unit_tests/SecureEndToEndTest.php
+++ b/src/php/tests/unit_tests/SecureEndToEndTest.php
@@ -31,186 +31,193 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-class SecureEndToEndTest extends PHPUnit_Framework_TestCase{
- public function setUp() {
- $credentials = Grpc\Credentials::createSsl(
- file_get_contents(dirname(__FILE__) . '/../data/ca.pem'));
- $server_credentials = Grpc\ServerCredentials::createSsl(
- null,
- file_get_contents(dirname(__FILE__) . '/../data/server1.key'),
- file_get_contents(dirname(__FILE__) . '/../data/server1.pem'));
- $this->server = new Grpc\Server();
- $this->port = $this->server->addSecureHttp2Port('0.0.0.0:0',
+class SecureEndToEndTest extends PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ $credentials = Grpc\Credentials::createSsl(
+ file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
+ $server_credentials = Grpc\ServerCredentials::createSsl(
+ null,
+ file_get_contents(dirname(__FILE__).'/../data/server1.key'),
+ file_get_contents(dirname(__FILE__).'/../data/server1.pem'));
+ $this->server = new Grpc\Server();
+ $this->port = $this->server->addSecureHttp2Port('0.0.0.0:0',
$server_credentials);
- $this->server->start();
- $this->host_override = 'foo.test.google.fr';
- $this->channel = new Grpc\Channel(
- 'localhost:' . $this->port,
- [
+ $this->server->start();
+ $this->host_override = 'foo.test.google.fr';
+ $this->channel = new Grpc\Channel(
+ 'localhost:'.$this->port,
+ [
'grpc.ssl_target_name_override' => $this->host_override,
'grpc.default_authority' => $this->host_override,
- 'credentials' => $credentials
- ]);
- }
-
- public function tearDown() {
- unset($this->channel);
- unset($this->server);
- }
-
- public function testSimpleRequestBody() {
- $deadline = Grpc\Timeval::infFuture();
- $status_text = 'xyz';
- $call = new Grpc\Call($this->channel,
- 'dummy_method',
- $deadline,
- $this->host_override);
-
- $event = $call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_CLOSE_FROM_CLIENT => true
- ]);
-
- $this->assertTrue($event->send_metadata);
- $this->assertTrue($event->send_close);
-
- $event = $this->server->requestCall();
- $this->assertSame('dummy_method', $event->method);
- $server_call = $event->call;
-
- $event = $server_call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_STATUS_FROM_SERVER => [
- 'metadata' => [],
- 'code' => Grpc\STATUS_OK,
- 'details' => $status_text
- ],
- Grpc\OP_RECV_CLOSE_ON_SERVER => true
- ]);
-
- $this->assertTrue($event->send_metadata);
- $this->assertTrue($event->send_status);
- $this->assertFalse($event->cancelled);
-
- $event = $call->startBatch([
- Grpc\OP_RECV_INITIAL_METADATA => true,
- Grpc\OP_RECV_STATUS_ON_CLIENT => true
- ]);
-
- $this->assertSame([], $event->metadata);
- $status = $event->status;
- $this->assertSame([], $status->metadata);
- $this->assertSame(Grpc\STATUS_OK, $status->code);
- $this->assertSame($status_text, $status->details);
-
- unset($call);
- unset($server_call);
- }
-
- public function testMessageWriteFlags() {
- $deadline = Grpc\Timeval::infFuture();
- $req_text = 'message_write_flags_test';
- $status_text = 'xyz';
- $call = new Grpc\Call($this->channel,
- 'dummy_method',
- $deadline,
- $this->host_override);
-
- $event = $call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_MESSAGE => ['message' => $req_text,
- 'flags' => Grpc\WRITE_NO_COMPRESS],
- Grpc\OP_SEND_CLOSE_FROM_CLIENT => true
- ]);
-
- $this->assertTrue($event->send_metadata);
- $this->assertTrue($event->send_close);
-
- $event = $this->server->requestCall();
- $this->assertSame('dummy_method', $event->method);
- $server_call = $event->call;
-
- $event = $server_call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_STATUS_FROM_SERVER => [
- 'metadata' => [],
- 'code' => Grpc\STATUS_OK,
- 'details' => $status_text
- ],
- ]);
-
- $event = $call->startBatch([
- Grpc\OP_RECV_INITIAL_METADATA => true,
- Grpc\OP_RECV_STATUS_ON_CLIENT => true
- ]);
-
- $this->assertSame([], $event->metadata);
- $status = $event->status;
- $this->assertSame([], $status->metadata);
- $this->assertSame(Grpc\STATUS_OK, $status->code);
- $this->assertSame($status_text, $status->details);
-
- unset($call);
- unset($server_call);
- }
-
- public function testClientServerFullRequestResponse() {
- $deadline = Grpc\Timeval::infFuture();
- $req_text = 'client_server_full_request_response';
- $reply_text = 'reply:client_server_full_request_response';
- $status_text = 'status:client_server_full_response_text';
-
- $call = new Grpc\Call($this->channel,
- 'dummy_method',
- $deadline,
- $this->host_override);
-
- $event = $call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
- Grpc\OP_SEND_MESSAGE => ['message' => $req_text]
- ]);
-
- $this->assertTrue($event->send_metadata);
- $this->assertTrue($event->send_close);
- $this->assertTrue($event->send_message);
-
- $event = $this->server->requestCall();
- $this->assertSame('dummy_method', $event->method);
- $server_call = $event->call;
-
- $event = $server_call->startBatch([
- Grpc\OP_SEND_INITIAL_METADATA => [],
- Grpc\OP_SEND_MESSAGE => ['message' => $reply_text],
- Grpc\OP_SEND_STATUS_FROM_SERVER => [
- 'metadata' => [],
- 'code' => Grpc\STATUS_OK,
- 'details' => $status_text
- ],
- Grpc\OP_RECV_MESSAGE => true,
- Grpc\OP_RECV_CLOSE_ON_SERVER => true,
- ]);
-
- $this->assertTrue($event->send_metadata);
- $this->assertTrue($event->send_status);
- $this->assertTrue($event->send_message);
- $this->assertFalse($event->cancelled);
- $this->assertSame($req_text, $event->message);
-
- $event = $call->startBatch([
- Grpc\OP_RECV_INITIAL_METADATA => true,
- Grpc\OP_RECV_MESSAGE => true,
- Grpc\OP_RECV_STATUS_ON_CLIENT => true,
- ]);
-
- $this->assertSame([], $event->metadata);
- $this->assertSame($reply_text, $event->message);
- $status = $event->status;
- $this->assertSame([], $status->metadata);
- $this->assertSame(Grpc\STATUS_OK, $status->code);
- $this->assertSame($status_text, $status->details);
-
- unset($call);
- unset($server_call);
- }
+ 'credentials' => $credentials,
+ ]
+ );
+ }
+
+ public function tearDown()
+ {
+ unset($this->channel);
+ unset($this->server);
+ }
+
+ public function testSimpleRequestBody()
+ {
+ $deadline = Grpc\Timeval::infFuture();
+ $status_text = 'xyz';
+ $call = new Grpc\Call($this->channel,
+ 'dummy_method',
+ $deadline,
+ $this->host_override);
+
+ $event = $call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+
+ $event = $this->server->requestCall();
+ $this->assertSame('dummy_method', $event->method);
+ $server_call = $event->call;
+
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text,
+ ],
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertFalse($event->cancelled);
+
+ $event = $call->startBatch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
+ $this->assertSame(Grpc\STATUS_OK, $status->code);
+ $this->assertSame($status_text, $status->details);
+
+ unset($call);
+ unset($server_call);
+ }
+
+ public function testMessageWriteFlags()
+ {
+ $deadline = Grpc\Timeval::infFuture();
+ $req_text = 'message_write_flags_test';
+ $status_text = 'xyz';
+ $call = new Grpc\Call($this->channel,
+ 'dummy_method',
+ $deadline,
+ $this->host_override);
+
+ $event = $call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_MESSAGE => ['message' => $req_text,
+ 'flags' => Grpc\WRITE_NO_COMPRESS, ],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+
+ $event = $this->server->requestCall();
+ $this->assertSame('dummy_method', $event->method);
+ $server_call = $event->call;
+
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text,
+ ],
+ ]);
+
+ $event = $call->startBatch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
+ $this->assertSame(Grpc\STATUS_OK, $status->code);
+ $this->assertSame($status_text, $status->details);
+
+ unset($call);
+ unset($server_call);
+ }
+
+ public function testClientServerFullRequestResponse()
+ {
+ $deadline = Grpc\Timeval::infFuture();
+ $req_text = 'client_server_full_request_response';
+ $reply_text = 'reply:client_server_full_request_response';
+ $status_text = 'status:client_server_full_response_text';
+
+ $call = new Grpc\Call($this->channel,
+ 'dummy_method',
+ $deadline,
+ $this->host_override);
+
+ $event = $call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+ Grpc\OP_SEND_MESSAGE => ['message' => $req_text],
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+ $this->assertTrue($event->send_message);
+
+ $event = $this->server->requestCall();
+ $this->assertSame('dummy_method', $event->method);
+ $server_call = $event->call;
+
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_MESSAGE => ['message' => $reply_text],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text,
+ ],
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertTrue($event->send_message);
+ $this->assertFalse($event->cancelled);
+ $this->assertSame($req_text, $event->message);
+
+ $event = $call->startBatch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $this->assertSame($reply_text, $event->message);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
+ $this->assertSame(Grpc\STATUS_OK, $status->code);
+ $this->assertSame($status_text, $status->details);
+
+ unset($call);
+ unset($server_call);
+ }
}
diff --git a/src/php/tests/unit_tests/TimevalTest.php b/src/php/tests/unit_tests/TimevalTest.php
index 7b4925cad6..1d2a8d303e 100755
--- a/src/php/tests/unit_tests/TimevalTest.php
+++ b/src/php/tests/unit_tests/TimevalTest.php
@@ -31,56 +31,64 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-class TimevalTest extends PHPUnit_Framework_TestCase{
- public function testCompareSame() {
- $zero = Grpc\Timeval::zero();
- $this->assertSame(0, Grpc\Timeval::compare($zero, $zero));
- }
+class TimevalTest extends PHPUnit_Framework_TestCase
+{
+ public function testCompareSame()
+ {
+ $zero = Grpc\Timeval::zero();
+ $this->assertSame(0, Grpc\Timeval::compare($zero, $zero));
+ }
- public function testPastIsLessThanZero() {
- $zero = Grpc\Timeval::zero();
- $past = Grpc\Timeval::infPast();
- $this->assertLessThan(0, Grpc\Timeval::compare($past, $zero));
- $this->assertGreaterThan(0, Grpc\Timeval::compare($zero, $past));
- }
+ public function testPastIsLessThanZero()
+ {
+ $zero = Grpc\Timeval::zero();
+ $past = Grpc\Timeval::infPast();
+ $this->assertLessThan(0, Grpc\Timeval::compare($past, $zero));
+ $this->assertGreaterThan(0, Grpc\Timeval::compare($zero, $past));
+ }
- public function testFutureIsGreaterThanZero() {
- $zero = Grpc\Timeval::zero();
- $future = Grpc\Timeval::infFuture();
- $this->assertLessThan(0, Grpc\Timeval::compare($zero, $future));
- $this->assertGreaterThan(0, Grpc\Timeval::compare($future, $zero));
- }
+ public function testFutureIsGreaterThanZero()
+ {
+ $zero = Grpc\Timeval::zero();
+ $future = Grpc\Timeval::infFuture();
+ $this->assertLessThan(0, Grpc\Timeval::compare($zero, $future));
+ $this->assertGreaterThan(0, Grpc\Timeval::compare($future, $zero));
+ }
- /**
- * @depends testFutureIsGreaterThanZero
- */
- public function testNowIsBetweenZeroAndFuture() {
- $zero = Grpc\Timeval::zero();
- $future = Grpc\Timeval::infFuture();
- $now = Grpc\Timeval::now();
- $this->assertLessThan(0, Grpc\Timeval::compare($zero, $now));
- $this->assertLessThan(0, Grpc\Timeval::compare($now, $future));
- }
+ /**
+ * @depends testFutureIsGreaterThanZero
+ */
+ public function testNowIsBetweenZeroAndFuture()
+ {
+ $zero = Grpc\Timeval::zero();
+ $future = Grpc\Timeval::infFuture();
+ $now = Grpc\Timeval::now();
+ $this->assertLessThan(0, Grpc\Timeval::compare($zero, $now));
+ $this->assertLessThan(0, Grpc\Timeval::compare($now, $future));
+ }
- public function testNowAndAdd() {
- $now = Grpc\Timeval::now();
- $delta = new Grpc\Timeval(1000);
- $deadline = $now->add($delta);
- $this->assertGreaterThan(0, Grpc\Timeval::compare($deadline, $now));
- }
+ public function testNowAndAdd()
+ {
+ $now = Grpc\Timeval::now();
+ $delta = new Grpc\Timeval(1000);
+ $deadline = $now->add($delta);
+ $this->assertGreaterThan(0, Grpc\Timeval::compare($deadline, $now));
+ }
- public function testNowAndSubtract() {
- $now = Grpc\Timeval::now();
- $delta = new Grpc\Timeval(1000);
- $deadline = $now->subtract($delta);
- $this->assertLessThan(0, Grpc\Timeval::compare($deadline, $now));
- }
+ public function testNowAndSubtract()
+ {
+ $now = Grpc\Timeval::now();
+ $delta = new Grpc\Timeval(1000);
+ $deadline = $now->subtract($delta);
+ $this->assertLessThan(0, Grpc\Timeval::compare($deadline, $now));
+ }
- public function testAddAndSubtract() {
- $now = Grpc\Timeval::now();
- $delta = new Grpc\Timeval(1000);
- $deadline = $now->add($delta);
- $back_to_now = $deadline->subtract($delta);
- $this->assertSame(0, Grpc\Timeval::compare($back_to_now, $now));
- }
+ public function testAddAndSubtract()
+ {
+ $now = Grpc\Timeval::now();
+ $delta = new Grpc\Timeval(1000);
+ $deadline = $now->add($delta);
+ $back_to_now = $deadline->subtract($delta);
+ $this->assertSame(0, Grpc\Timeval::compare($back_to_now, $now));
+ }
}
diff --git a/src/python/grpcio/grpc/early_adopter/__init__.py b/src/python/grpcio/grpc/early_adopter/__init__.py
index 7086519106..bff74be2c7 100644
--- a/src/python/grpcio/grpc/early_adopter/__init__.py
+++ b/src/python/grpcio/grpc/early_adopter/__init__.py
@@ -27,4 +27,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import warnings
+warnings.simplefilter('always', DeprecationWarning)
+warnings.warn('the alpha API (includes this package) is deprecated, '
+ 'unmaintained, and no longer tested. Please migrate to the beta '
+ 'API.', DeprecationWarning, stacklevel=2)
diff --git a/src/python/grpcio/grpc/framework/alpha/__init__.py b/src/python/grpcio/grpc/framework/alpha/__init__.py
index b89398809f..bff74be2c7 100644
--- a/src/python/grpcio/grpc/framework/alpha/__init__.py
+++ b/src/python/grpcio/grpc/framework/alpha/__init__.py
@@ -26,3 +26,10 @@
# 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.
+
+import warnings
+
+warnings.simplefilter('always', DeprecationWarning)
+warnings.warn('the alpha API (includes this package) is deprecated, '
+ 'unmaintained, and no longer tested. Please migrate to the beta '
+ 'API.', DeprecationWarning, stacklevel=2)
diff --git a/src/python/grpcio/grpc/framework/base/__init__.py b/src/python/grpcio/grpc/framework/base/__init__.py
index 7086519106..bff74be2c7 100644
--- a/src/python/grpcio/grpc/framework/base/__init__.py
+++ b/src/python/grpcio/grpc/framework/base/__init__.py
@@ -27,4 +27,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import warnings
+warnings.simplefilter('always', DeprecationWarning)
+warnings.warn('the alpha API (includes this package) is deprecated, '
+ 'unmaintained, and no longer tested. Please migrate to the beta '
+ 'API.', DeprecationWarning, stacklevel=2)
diff --git a/src/python/grpcio/grpc/framework/face/__init__.py b/src/python/grpcio/grpc/framework/face/__init__.py
index 7086519106..bff74be2c7 100644
--- a/src/python/grpcio/grpc/framework/face/__init__.py
+++ b/src/python/grpcio/grpc/framework/face/__init__.py
@@ -27,4 +27,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import warnings
+warnings.simplefilter('always', DeprecationWarning)
+warnings.warn('the alpha API (includes this package) is deprecated, '
+ 'unmaintained, and no longer tested. Please migrate to the beta '
+ 'API.', DeprecationWarning, stacklevel=2)
diff --git a/src/python/grpcio_health_checking/commands.py b/src/python/grpcio_health_checking/commands.py
index 6a95e679c4..3f4ea6e22f 100644
--- a/src/python/grpcio_health_checking/commands.py
+++ b/src/python/grpcio_health_checking/commands.py
@@ -50,7 +50,7 @@ class BuildProtoModules(setuptools.Command):
pass
def finalize_options(self):
- self.protoc_command = 'protoc'
+ self.protoc_command = distutils.spawn.find_executable('protoc')
self.grpc_python_plugin_command = distutils.spawn.find_executable(
'grpc_python_plugin')
@@ -69,7 +69,11 @@ class BuildProtoModules(setuptools.Command):
'--python_out={}'.format(root_directory),
'--python-grpc_out={}'.format(root_directory),
] + paths
- subprocess.check_call(' '.join(command), cwd=root_directory, shell=True)
+ try:
+ subprocess.check_output(' '.join(command), cwd=root_directory, shell=True,
+ stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as e:
+ raise Exception('{}\nOutput:\n{}'.format(e.message, e.output))
class BuildPy(build_py.build_py):
diff --git a/src/python/grpcio_test/.gitignore b/src/python/grpcio_test/.gitignore
index 4bb4d42dfe..6158313bde 100644
--- a/src/python/grpcio_test/.gitignore
+++ b/src/python/grpcio_test/.gitignore
@@ -5,6 +5,7 @@ dist/
*.egg
*.egg/
*.eggs/
+*_pb2.py
.coverage
.coverage.*
.cache/
diff --git a/src/python/grpcio_test/commands.py b/src/python/grpcio_test/commands.py
index c796d94c76..edaa2aa72d 100644
--- a/src/python/grpcio_test/commands.py
+++ b/src/python/grpcio_test/commands.py
@@ -29,11 +29,14 @@
"""Provides distutils command classes for the GRPC Python test setup process."""
+import distutils
import os
import os.path
+import subprocess
import sys
import setuptools
+from setuptools.command import build_py
class RunTests(setuptools.Command):
@@ -52,6 +55,52 @@ class RunTests(setuptools.Command):
# We import here to ensure that setup.py has had a chance to install the
# relevant package eggs first.
import pytest
+
+ self.run_command('build_proto_modules')
result = pytest.main(self.pytest_args)
if result != 0:
raise SystemExit(result)
+
+
+class BuildProtoModules(setuptools.Command):
+ """Command to generate project *_pb2.py modules from proto files."""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ self.protoc_command = distutils.spawn.find_executable('protoc')
+ self.grpc_python_plugin_command = distutils.spawn.find_executable(
+ 'grpc_python_plugin')
+
+ def run(self):
+ paths = []
+ root_directory = os.getcwd()
+ for walk_root, directories, filenames in os.walk(root_directory):
+ for filename in filenames:
+ if filename.endswith('.proto'):
+ paths.append(os.path.join(walk_root, filename))
+ command = [
+ self.protoc_command,
+ '--plugin=protoc-gen-python-grpc={}'.format(
+ self.grpc_python_plugin_command),
+ '-I {}'.format(root_directory),
+ '--python_out={}'.format(root_directory),
+ '--python-grpc_out={}'.format(root_directory),
+ ] + paths
+ try:
+ subprocess.check_output(' '.join(command), cwd=root_directory, shell=True,
+ stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as e:
+ raise Exception('{}\nOutput:\n{}'.format(e.message, e.output))
+
+
+class BuildPy(build_py.build_py):
+ """Custom project build command."""
+
+ def run(self):
+ self.run_command('build_proto_modules')
+ build_py.build_py.run(self)
diff --git a/src/python/grpcio_test/grpc_interop/_insecure_interop_test.py b/src/python/grpcio_test/grpc_interop/_insecure_interop_test.py
index 825988a072..5007be28ff 100644
--- a/src/python/grpcio_test/grpc_interop/_insecure_interop_test.py
+++ b/src/python/grpcio_test/grpc_interop/_insecure_interop_test.py
@@ -31,10 +31,12 @@
import unittest
-from grpc.early_adopter import implementations
+from grpc.beta import implementations
from grpc_interop import _interop_test_case
from grpc_interop import methods
+from grpc_interop import server
+from grpc_interop import test_pb2
class InsecureInteropTest(
@@ -42,15 +44,14 @@ class InsecureInteropTest(
unittest.TestCase):
def setUp(self):
- self.server = implementations.server(
- methods.SERVICE_NAME, methods.SERVER_METHODS, 0)
+ self.server = test_pb2.beta_create_TestService_server(methods.TestService())
+ port = self.server.add_insecure_port('[::]:0')
self.server.start()
- port = self.server.port()
- self.stub = implementations.stub(
- methods.SERVICE_NAME, methods.CLIENT_METHODS, 'localhost', port)
+ self.stub = test_pb2.beta_create_TestService_stub(
+ implementations.insecure_channel('[::]', port))
def tearDown(self):
- self.server.stop()
+ self.server.stop(0)
if __name__ == '__main__':
diff --git a/src/python/grpcio_test/grpc_interop/_secure_interop_test.py b/src/python/grpcio_test/grpc_interop/_secure_interop_test.py
index a2682dee99..108e15b0f9 100644
--- a/src/python/grpcio_test/grpc_interop/_secure_interop_test.py
+++ b/src/python/grpcio_test/grpc_interop/_secure_interop_test.py
@@ -31,11 +31,14 @@
import unittest
-from grpc.early_adopter import implementations
+from grpc.beta import implementations
+
+from grpc_test.beta import test_utilities
from grpc_interop import _interop_test_case
from grpc_interop import methods
from grpc_interop import resources
+from grpc_interop import test_pb2
_SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
@@ -45,19 +48,19 @@ class SecureInteropTest(
unittest.TestCase):
def setUp(self):
- self.server = implementations.server(
- methods.SERVICE_NAME, methods.SERVER_METHODS, 0,
- private_key=resources.private_key(),
- certificate_chain=resources.certificate_chain())
+ self.server = test_pb2.beta_create_TestService_server(methods.TestService())
+ port = self.server.add_secure_port(
+ '[::]:0', implementations.ssl_server_credentials(
+ [(resources.private_key(), resources.certificate_chain())]))
self.server.start()
- port = self.server.port()
- self.stub = implementations.stub(
- methods.SERVICE_NAME, methods.CLIENT_METHODS, 'localhost', port,
- secure=True, root_certificates=resources.test_root_certificates(),
- server_host_override=_SERVER_HOST_OVERRIDE)
+ self.stub = test_pb2.beta_create_TestService_stub(
+ test_utilities.not_really_secure_channel(
+ '[::]', port, implementations.ssl_client_credentials(
+ resources.test_root_certificates(), None, None),
+ _SERVER_HOST_OVERRIDE))
def tearDown(self):
- self.server.stop()
+ self.server.stop(0)
if __name__ == '__main__':
diff --git a/src/python/grpcio_test/grpc_interop/client.py b/src/python/grpcio_test/grpc_interop/client.py
index 01928886b4..b8d5047ca5 100644
--- a/src/python/grpcio_test/grpc_interop/client.py
+++ b/src/python/grpcio_test/grpc_interop/client.py
@@ -32,10 +32,13 @@
import argparse
from oauth2client import client as oauth2client_client
-from grpc.early_adopter import implementations
+from grpc.beta import implementations
+
+from grpc_test.beta import test_utilities
from grpc_interop import methods
from grpc_interop import resources
+from grpc_interop import test_pb2
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
@@ -71,12 +74,17 @@ def _oauth_access_token(args):
def _stub(args):
if args.oauth_scope:
if args.test_case == 'oauth2_auth_token':
+ # TODO(jtattermusch): This testcase sets the auth metadata key-value
+ # manually, which also means that the user would need to do the same
+ # thing every time he/she would like to use and out of band oauth token.
+ # The transformer function that produces the metadata key-value from
+ # the access token should be provided by gRPC auth library.
access_token = _oauth_access_token(args)
metadata_transformer = lambda x: [
- ('Authorization', 'Bearer %s' % access_token)]
+ ('authorization', 'Bearer %s' % access_token)]
else:
metadata_transformer = lambda x: [
- ('Authorization', 'Bearer %s' % _oauth_access_token(args))]
+ ('authorization', 'Bearer %s' % _oauth_access_token(args))]
else:
metadata_transformer = lambda x: []
if args.use_tls:
@@ -85,15 +93,16 @@ def _stub(args):
else:
root_certificates = resources.prod_root_certificates()
- stub = implementations.stub(
- methods.SERVICE_NAME, methods.CLIENT_METHODS, args.server_host,
- args.server_port, metadata_transformer=metadata_transformer,
- secure=True, root_certificates=root_certificates,
- server_host_override=args.server_host_override)
+ channel = test_utilities.not_really_secure_channel(
+ args.server_host, args.server_port,
+ implementations.ssl_client_credentials(root_certificates, None, None),
+ args.server_host_override)
+ stub = test_pb2.beta_create_TestService_stub(
+ channel, metadata_transformer=metadata_transformer)
else:
- stub = implementations.stub(
- methods.SERVICE_NAME, methods.CLIENT_METHODS, args.server_host,
- args.server_port, secure=False)
+ channel = implementations.insecure_channel(
+ args.server_host, args.server_port)
+ stub = test_pb2.beta_create_TestService_stub(channel)
return stub
diff --git a/src/python/grpcio_test/grpc_interop/empty.proto b/src/python/grpcio_test/grpc_interop/empty.proto
new file mode 100644
index 0000000000..6d0eb937d6
--- /dev/null
+++ b/src/python/grpcio_test/grpc_interop/empty.proto
@@ -0,0 +1,43 @@
+
+// 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.
+
+syntax = "proto3";
+
+package grpc.testing;
+
+// An empty message that you can re-use to avoid defining duplicated empty
+// messages in your project. A typical example is to use it as argument or the
+// return value of a service API. For instance:
+//
+// service Foo {
+// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
+// };
+//
+message Empty {}
diff --git a/src/python/grpcio_test/grpc_interop/empty_pb2.py b/src/python/grpcio_test/grpc_interop/empty_pb2.py
deleted file mode 100644
index 8c1ce2f13e..0000000000
--- a/src/python/grpcio_test/grpc_interop/empty_pb2.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: test/cpp/interop/empty.proto
-
-import sys
-_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
-from google.protobuf import descriptor as _descriptor
-from google.protobuf import message as _message
-from google.protobuf import reflection as _reflection
-from google.protobuf import symbol_database as _symbol_database
-from google.protobuf import descriptor_pb2
-# @@protoc_insertion_point(imports)
-
-_sym_db = _symbol_database.Default()
-
-
-
-
-DESCRIPTOR = _descriptor.FileDescriptor(
- name='test/cpp/interop/empty.proto',
- package='grpc.testing',
- serialized_pb=_b('\n\x1ctest/cpp/interop/empty.proto\x12\x0cgrpc.testing\"\x07\n\x05\x45mpty')
-)
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
-
-
-
-
-_EMPTY = _descriptor.Descriptor(
- name='Empty',
- full_name='grpc.testing.Empty',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=46,
- serialized_end=53,
-)
-
-DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
-
-Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), dict(
- DESCRIPTOR = _EMPTY,
- __module__ = 'test.cpp.interop.empty_pb2'
- # @@protoc_insertion_point(class_scope:grpc.testing.Empty)
- ))
-_sym_db.RegisterMessage(Empty)
-
-
-import abc
-from grpc.early_adopter import implementations
-from grpc.framework.alpha import utilities
-# @@protoc_insertion_point(module_scope)
diff --git a/src/python/grpcio_test/grpc_interop/messages.proto b/src/python/grpcio_test/grpc_interop/messages.proto
new file mode 100644
index 0000000000..193b6c4171
--- /dev/null
+++ b/src/python/grpcio_test/grpc_interop/messages.proto
@@ -0,0 +1,167 @@
+
+// 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.
+
+// Message definitions to be used by integration test service definitions.
+
+syntax = "proto3";
+
+package grpc.testing;
+
+// The type of payload that should be returned.
+enum PayloadType {
+ // Compressable text format.
+ COMPRESSABLE = 0;
+
+ // Uncompressable binary format.
+ UNCOMPRESSABLE = 1;
+
+ // Randomly chosen from all other formats defined in this enum.
+ RANDOM = 2;
+}
+
+// Compression algorithms
+enum CompressionType {
+ // No compression
+ NONE = 0;
+ GZIP = 1;
+ DEFLATE = 2;
+}
+
+// A block of data, to simply increase gRPC message size.
+message Payload {
+ // The type of data in body.
+ PayloadType type = 1;
+ // Primary contents of payload.
+ bytes body = 2;
+}
+
+// A protobuf representation for grpc status. This is used by test
+// clients to specify a status that the server should attempt to return.
+message EchoStatus {
+ int32 code = 1;
+ string message = 2;
+}
+
+// Unary request.
+message SimpleRequest {
+ // Desired payload type in the response from the server.
+ // If response_type is RANDOM, server randomly chooses one from other formats.
+ PayloadType response_type = 1;
+
+ // Desired payload size in the response from the server.
+ // If response_type is COMPRESSABLE, this denotes the size before compression.
+ int32 response_size = 2;
+
+ // Optional input payload sent along with the request.
+ Payload payload = 3;
+
+ // Whether SimpleResponse should include username.
+ bool fill_username = 4;
+
+ // Whether SimpleResponse should include OAuth scope.
+ bool fill_oauth_scope = 5;
+
+ // Compression algorithm to be used by the server for the response (stream)
+ CompressionType response_compression = 6;
+
+ // Whether server should return a given status
+ EchoStatus response_status = 7;
+}
+
+// Unary response, as configured by the request.
+message SimpleResponse {
+ // Payload to increase message size.
+ Payload payload = 1;
+ // The user the request came from, for verifying authentication was
+ // successful when the client expected it.
+ string username = 2;
+ // OAuth scope.
+ string oauth_scope = 3;
+}
+
+// Client-streaming request.
+message StreamingInputCallRequest {
+ // Optional input payload sent along with the request.
+ Payload payload = 1;
+
+ // Not expecting any payload from the response.
+}
+
+// Client-streaming response.
+message StreamingInputCallResponse {
+ // Aggregated size of payloads received from the client.
+ int32 aggregated_payload_size = 1;
+}
+
+// Configuration for a particular response.
+message ResponseParameters {
+ // Desired payload sizes in responses from the server.
+ // If response_type is COMPRESSABLE, this denotes the size before compression.
+ int32 size = 1;
+
+ // Desired interval between consecutive responses in the response stream in
+ // microseconds.
+ int32 interval_us = 2;
+}
+
+// Server-streaming request.
+message StreamingOutputCallRequest {
+ // Desired payload type in the response from the server.
+ // If response_type is RANDOM, the payload from each response in the stream
+ // might be of different types. This is to simulate a mixed type of payload
+ // stream.
+ PayloadType response_type = 1;
+
+ // Configuration for each expected response message.
+ repeated ResponseParameters response_parameters = 2;
+
+ // Optional input payload sent along with the request.
+ Payload payload = 3;
+
+ // Compression algorithm to be used by the server for the response (stream)
+ CompressionType response_compression = 6;
+
+ // Whether server should return a given status
+ EchoStatus response_status = 7;
+}
+
+// Server-streaming response, as configured by the request and parameters.
+message StreamingOutputCallResponse {
+ // Payload to increase response size.
+ Payload payload = 1;
+}
+
+// For reconnect interop test only.
+// Server tells client whether its reconnects are following the spec and the
+// reconnect backoffs it saw.
+message ReconnectInfo {
+ bool passed = 1;
+ repeated int32 backoff_ms = 2;
+}
diff --git a/src/python/grpcio_test/grpc_interop/messages_pb2.py b/src/python/grpcio_test/grpc_interop/messages_pb2.py
deleted file mode 100644
index 0bf3d86a31..0000000000
--- a/src/python/grpcio_test/grpc_interop/messages_pb2.py
+++ /dev/null
@@ -1,447 +0,0 @@
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: test/cpp/interop/messages.proto
-
-import sys
-_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
-from google.protobuf.internal import enum_type_wrapper
-from google.protobuf import descriptor as _descriptor
-from google.protobuf import message as _message
-from google.protobuf import reflection as _reflection
-from google.protobuf import symbol_database as _symbol_database
-from google.protobuf import descriptor_pb2
-# @@protoc_insertion_point(imports)
-
-_sym_db = _symbol_database.Default()
-
-
-
-
-DESCRIPTOR = _descriptor.FileDescriptor(
- name='test/cpp/interop/messages.proto',
- package='grpc.testing',
- serialized_pb=_b('\n\x1ftest/cpp/interop/messages.proto\x12\x0cgrpc.testing\"@\n\x07Payload\x12\'\n\x04type\x18\x01 \x01(\x0e\x32\x19.grpc.testing.PayloadType\x12\x0c\n\x04\x62ody\x18\x02 \x01(\x0c\"\xb1\x01\n\rSimpleRequest\x12\x30\n\rresponse_type\x18\x01 \x01(\x0e\x32\x19.grpc.testing.PayloadType\x12\x15\n\rresponse_size\x18\x02 \x01(\x05\x12&\n\x07payload\x18\x03 \x01(\x0b\x32\x15.grpc.testing.Payload\x12\x15\n\rfill_username\x18\x04 \x01(\x08\x12\x18\n\x10\x66ill_oauth_scope\x18\x05 \x01(\x08\"_\n\x0eSimpleResponse\x12&\n\x07payload\x18\x01 \x01(\x0b\x32\x15.grpc.testing.Payload\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x13\n\x0boauth_scope\x18\x03 \x01(\t\"C\n\x19StreamingInputCallRequest\x12&\n\x07payload\x18\x01 \x01(\x0b\x32\x15.grpc.testing.Payload\"=\n\x1aStreamingInputCallResponse\x12\x1f\n\x17\x61ggregated_payload_size\x18\x01 \x01(\x05\"7\n\x12ResponseParameters\x12\x0c\n\x04size\x18\x01 \x01(\x05\x12\x13\n\x0binterval_us\x18\x02 \x01(\x05\"\xb5\x01\n\x1aStreamingOutputCallRequest\x12\x30\n\rresponse_type\x18\x01 \x01(\x0e\x32\x19.grpc.testing.PayloadType\x12=\n\x13response_parameters\x18\x02 \x03(\x0b\x32 .grpc.testing.ResponseParameters\x12&\n\x07payload\x18\x03 \x01(\x0b\x32\x15.grpc.testing.Payload\"E\n\x1bStreamingOutputCallResponse\x12&\n\x07payload\x18\x01 \x01(\x0b\x32\x15.grpc.testing.Payload*?\n\x0bPayloadType\x12\x10\n\x0c\x43OMPRESSABLE\x10\x00\x12\x12\n\x0eUNCOMPRESSABLE\x10\x01\x12\n\n\x06RANDOM\x10\x02')
-)
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
-
-_PAYLOADTYPE = _descriptor.EnumDescriptor(
- name='PayloadType',
- full_name='grpc.testing.PayloadType',
- filename=None,
- file=DESCRIPTOR,
- values=[
- _descriptor.EnumValueDescriptor(
- name='COMPRESSABLE', index=0, number=0,
- options=None,
- type=None),
- _descriptor.EnumValueDescriptor(
- name='UNCOMPRESSABLE', index=1, number=1,
- options=None,
- type=None),
- _descriptor.EnumValueDescriptor(
- name='RANDOM', index=2, number=2,
- options=None,
- type=None),
- ],
- containing_type=None,
- options=None,
- serialized_start=836,
- serialized_end=899,
-)
-_sym_db.RegisterEnumDescriptor(_PAYLOADTYPE)
-
-PayloadType = enum_type_wrapper.EnumTypeWrapper(_PAYLOADTYPE)
-COMPRESSABLE = 0
-UNCOMPRESSABLE = 1
-RANDOM = 2
-
-
-
-_PAYLOAD = _descriptor.Descriptor(
- name='Payload',
- full_name='grpc.testing.Payload',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='type', full_name='grpc.testing.Payload.type', index=0,
- number=1, type=14, cpp_type=8, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='body', full_name='grpc.testing.Payload.body', index=1,
- number=2, type=12, cpp_type=9, label=1,
- has_default_value=False, default_value=_b(""),
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=49,
- serialized_end=113,
-)
-
-
-_SIMPLEREQUEST = _descriptor.Descriptor(
- name='SimpleRequest',
- full_name='grpc.testing.SimpleRequest',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='response_type', full_name='grpc.testing.SimpleRequest.response_type', index=0,
- number=1, type=14, cpp_type=8, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='response_size', full_name='grpc.testing.SimpleRequest.response_size', index=1,
- number=2, type=5, cpp_type=1, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='payload', full_name='grpc.testing.SimpleRequest.payload', index=2,
- number=3, type=11, cpp_type=10, label=1,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='fill_username', full_name='grpc.testing.SimpleRequest.fill_username', index=3,
- number=4, type=8, cpp_type=7, label=1,
- has_default_value=False, default_value=False,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='fill_oauth_scope', full_name='grpc.testing.SimpleRequest.fill_oauth_scope', index=4,
- number=5, type=8, cpp_type=7, label=1,
- has_default_value=False, default_value=False,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=116,
- serialized_end=293,
-)
-
-
-_SIMPLERESPONSE = _descriptor.Descriptor(
- name='SimpleResponse',
- full_name='grpc.testing.SimpleResponse',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='payload', full_name='grpc.testing.SimpleResponse.payload', index=0,
- number=1, type=11, cpp_type=10, label=1,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='username', full_name='grpc.testing.SimpleResponse.username', index=1,
- number=2, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=_b("").decode('utf-8'),
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='oauth_scope', full_name='grpc.testing.SimpleResponse.oauth_scope', index=2,
- number=3, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=_b("").decode('utf-8'),
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=295,
- serialized_end=390,
-)
-
-
-_STREAMINGINPUTCALLREQUEST = _descriptor.Descriptor(
- name='StreamingInputCallRequest',
- full_name='grpc.testing.StreamingInputCallRequest',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='payload', full_name='grpc.testing.StreamingInputCallRequest.payload', index=0,
- number=1, type=11, cpp_type=10, label=1,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=392,
- serialized_end=459,
-)
-
-
-_STREAMINGINPUTCALLRESPONSE = _descriptor.Descriptor(
- name='StreamingInputCallResponse',
- full_name='grpc.testing.StreamingInputCallResponse',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='aggregated_payload_size', full_name='grpc.testing.StreamingInputCallResponse.aggregated_payload_size', index=0,
- number=1, type=5, cpp_type=1, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=461,
- serialized_end=522,
-)
-
-
-_RESPONSEPARAMETERS = _descriptor.Descriptor(
- name='ResponseParameters',
- full_name='grpc.testing.ResponseParameters',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='size', full_name='grpc.testing.ResponseParameters.size', index=0,
- number=1, type=5, cpp_type=1, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='interval_us', full_name='grpc.testing.ResponseParameters.interval_us', index=1,
- number=2, type=5, cpp_type=1, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=524,
- serialized_end=579,
-)
-
-
-_STREAMINGOUTPUTCALLREQUEST = _descriptor.Descriptor(
- name='StreamingOutputCallRequest',
- full_name='grpc.testing.StreamingOutputCallRequest',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='response_type', full_name='grpc.testing.StreamingOutputCallRequest.response_type', index=0,
- number=1, type=14, cpp_type=8, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='response_parameters', full_name='grpc.testing.StreamingOutputCallRequest.response_parameters', index=1,
- number=2, type=11, cpp_type=10, label=3,
- has_default_value=False, default_value=[],
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='payload', full_name='grpc.testing.StreamingOutputCallRequest.payload', index=2,
- number=3, type=11, cpp_type=10, label=1,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=582,
- serialized_end=763,
-)
-
-
-_STREAMINGOUTPUTCALLRESPONSE = _descriptor.Descriptor(
- name='StreamingOutputCallResponse',
- full_name='grpc.testing.StreamingOutputCallResponse',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='payload', full_name='grpc.testing.StreamingOutputCallResponse.payload', index=0,
- number=1, type=11, cpp_type=10, label=1,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=765,
- serialized_end=834,
-)
-
-_PAYLOAD.fields_by_name['type'].enum_type = _PAYLOADTYPE
-_SIMPLEREQUEST.fields_by_name['response_type'].enum_type = _PAYLOADTYPE
-_SIMPLEREQUEST.fields_by_name['payload'].message_type = _PAYLOAD
-_SIMPLERESPONSE.fields_by_name['payload'].message_type = _PAYLOAD
-_STREAMINGINPUTCALLREQUEST.fields_by_name['payload'].message_type = _PAYLOAD
-_STREAMINGOUTPUTCALLREQUEST.fields_by_name['response_type'].enum_type = _PAYLOADTYPE
-_STREAMINGOUTPUTCALLREQUEST.fields_by_name['response_parameters'].message_type = _RESPONSEPARAMETERS
-_STREAMINGOUTPUTCALLREQUEST.fields_by_name['payload'].message_type = _PAYLOAD
-_STREAMINGOUTPUTCALLRESPONSE.fields_by_name['payload'].message_type = _PAYLOAD
-DESCRIPTOR.message_types_by_name['Payload'] = _PAYLOAD
-DESCRIPTOR.message_types_by_name['SimpleRequest'] = _SIMPLEREQUEST
-DESCRIPTOR.message_types_by_name['SimpleResponse'] = _SIMPLERESPONSE
-DESCRIPTOR.message_types_by_name['StreamingInputCallRequest'] = _STREAMINGINPUTCALLREQUEST
-DESCRIPTOR.message_types_by_name['StreamingInputCallResponse'] = _STREAMINGINPUTCALLRESPONSE
-DESCRIPTOR.message_types_by_name['ResponseParameters'] = _RESPONSEPARAMETERS
-DESCRIPTOR.message_types_by_name['StreamingOutputCallRequest'] = _STREAMINGOUTPUTCALLREQUEST
-DESCRIPTOR.message_types_by_name['StreamingOutputCallResponse'] = _STREAMINGOUTPUTCALLRESPONSE
-DESCRIPTOR.enum_types_by_name['PayloadType'] = _PAYLOADTYPE
-
-Payload = _reflection.GeneratedProtocolMessageType('Payload', (_message.Message,), dict(
- DESCRIPTOR = _PAYLOAD,
- __module__ = 'test.cpp.interop.messages_pb2'
- # @@protoc_insertion_point(class_scope:grpc.testing.Payload)
- ))
-_sym_db.RegisterMessage(Payload)
-
-SimpleRequest = _reflection.GeneratedProtocolMessageType('SimpleRequest', (_message.Message,), dict(
- DESCRIPTOR = _SIMPLEREQUEST,
- __module__ = 'test.cpp.interop.messages_pb2'
- # @@protoc_insertion_point(class_scope:grpc.testing.SimpleRequest)
- ))
-_sym_db.RegisterMessage(SimpleRequest)
-
-SimpleResponse = _reflection.GeneratedProtocolMessageType('SimpleResponse', (_message.Message,), dict(
- DESCRIPTOR = _SIMPLERESPONSE,
- __module__ = 'test.cpp.interop.messages_pb2'
- # @@protoc_insertion_point(class_scope:grpc.testing.SimpleResponse)
- ))
-_sym_db.RegisterMessage(SimpleResponse)
-
-StreamingInputCallRequest = _reflection.GeneratedProtocolMessageType('StreamingInputCallRequest', (_message.Message,), dict(
- DESCRIPTOR = _STREAMINGINPUTCALLREQUEST,
- __module__ = 'test.cpp.interop.messages_pb2'
- # @@protoc_insertion_point(class_scope:grpc.testing.StreamingInputCallRequest)
- ))
-_sym_db.RegisterMessage(StreamingInputCallRequest)
-
-StreamingInputCallResponse = _reflection.GeneratedProtocolMessageType('StreamingInputCallResponse', (_message.Message,), dict(
- DESCRIPTOR = _STREAMINGINPUTCALLRESPONSE,
- __module__ = 'test.cpp.interop.messages_pb2'
- # @@protoc_insertion_point(class_scope:grpc.testing.StreamingInputCallResponse)
- ))
-_sym_db.RegisterMessage(StreamingInputCallResponse)
-
-ResponseParameters = _reflection.GeneratedProtocolMessageType('ResponseParameters', (_message.Message,), dict(
- DESCRIPTOR = _RESPONSEPARAMETERS,
- __module__ = 'test.cpp.interop.messages_pb2'
- # @@protoc_insertion_point(class_scope:grpc.testing.ResponseParameters)
- ))
-_sym_db.RegisterMessage(ResponseParameters)
-
-StreamingOutputCallRequest = _reflection.GeneratedProtocolMessageType('StreamingOutputCallRequest', (_message.Message,), dict(
- DESCRIPTOR = _STREAMINGOUTPUTCALLREQUEST,
- __module__ = 'test.cpp.interop.messages_pb2'
- # @@protoc_insertion_point(class_scope:grpc.testing.StreamingOutputCallRequest)
- ))
-_sym_db.RegisterMessage(StreamingOutputCallRequest)
-
-StreamingOutputCallResponse = _reflection.GeneratedProtocolMessageType('StreamingOutputCallResponse', (_message.Message,), dict(
- DESCRIPTOR = _STREAMINGOUTPUTCALLRESPONSE,
- __module__ = 'test.cpp.interop.messages_pb2'
- # @@protoc_insertion_point(class_scope:grpc.testing.StreamingOutputCallResponse)
- ))
-_sym_db.RegisterMessage(StreamingOutputCallResponse)
-
-
-import abc
-from grpc.early_adopter import implementations
-from grpc.framework.alpha import utilities
-# @@protoc_insertion_point(module_scope)
diff --git a/src/python/grpcio_test/grpc_interop/methods.py b/src/python/grpcio_test/grpc_interop/methods.py
index 8ab5bac302..3ef8545355 100644
--- a/src/python/grpcio_test/grpc_interop/methods.py
+++ b/src/python/grpcio_test/grpc_interop/methods.py
@@ -37,123 +37,53 @@ import time
from oauth2client import client as oauth2client_client
-from grpc.framework.alpha import utilities
-from grpc.framework.alpha import exceptions
+from grpc.framework.common import cardinality
+from grpc.framework.interfaces.face import face
from grpc_interop import empty_pb2
from grpc_interop import messages_pb2
+from grpc_interop import test_pb2
_TIMEOUT = 7
-def _empty_call(request, unused_context):
- return empty_pb2.Empty()
+class TestService(test_pb2.BetaTestServiceServicer):
-_CLIENT_EMPTY_CALL = utilities.unary_unary_invocation_description(
- empty_pb2.Empty.SerializeToString, empty_pb2.Empty.FromString)
-_SERVER_EMPTY_CALL = utilities.unary_unary_service_description(
- _empty_call, empty_pb2.Empty.FromString,
- empty_pb2.Empty.SerializeToString)
+ def EmptyCall(self, request, context):
+ return empty_pb2.Empty()
-
-def _unary_call(request, unused_context):
- return messages_pb2.SimpleResponse(
- payload=messages_pb2.Payload(
- type=messages_pb2.COMPRESSABLE,
- body=b'\x00' * request.response_size))
-
-_CLIENT_UNARY_CALL = utilities.unary_unary_invocation_description(
- messages_pb2.SimpleRequest.SerializeToString,
- messages_pb2.SimpleResponse.FromString)
-_SERVER_UNARY_CALL = utilities.unary_unary_service_description(
- _unary_call, messages_pb2.SimpleRequest.FromString,
- messages_pb2.SimpleResponse.SerializeToString)
-
-
-def _streaming_output_call(request, unused_context):
- for response_parameters in request.response_parameters:
- yield messages_pb2.StreamingOutputCallResponse(
- payload=messages_pb2.Payload(
- type=request.response_type,
- body=b'\x00' * response_parameters.size))
-
-_CLIENT_STREAMING_OUTPUT_CALL = utilities.unary_stream_invocation_description(
- messages_pb2.StreamingOutputCallRequest.SerializeToString,
- messages_pb2.StreamingOutputCallResponse.FromString)
-_SERVER_STREAMING_OUTPUT_CALL = utilities.unary_stream_service_description(
- _streaming_output_call,
- messages_pb2.StreamingOutputCallRequest.FromString,
- messages_pb2.StreamingOutputCallResponse.SerializeToString)
-
-
-def _streaming_input_call(request_iterator, unused_context):
- aggregate_size = 0
- for request in request_iterator:
- if request.payload and request.payload.body:
- aggregate_size += len(request.payload.body)
- return messages_pb2.StreamingInputCallResponse(
- aggregated_payload_size=aggregate_size)
-
-_CLIENT_STREAMING_INPUT_CALL = utilities.stream_unary_invocation_description(
- messages_pb2.StreamingInputCallRequest.SerializeToString,
- messages_pb2.StreamingInputCallResponse.FromString)
-_SERVER_STREAMING_INPUT_CALL = utilities.stream_unary_service_description(
- _streaming_input_call,
- messages_pb2.StreamingInputCallRequest.FromString,
- messages_pb2.StreamingInputCallResponse.SerializeToString)
-
-
-def _full_duplex_call(request_iterator, unused_context):
- for request in request_iterator:
- yield messages_pb2.StreamingOutputCallResponse(
+ def UnaryCall(self, request, context):
+ return messages_pb2.SimpleResponse(
payload=messages_pb2.Payload(
- type=request.payload.type,
- body=b'\x00' * request.response_parameters[0].size))
-
-_CLIENT_FULL_DUPLEX_CALL = utilities.stream_stream_invocation_description(
- messages_pb2.StreamingOutputCallRequest.SerializeToString,
- messages_pb2.StreamingOutputCallResponse.FromString)
-_SERVER_FULL_DUPLEX_CALL = utilities.stream_stream_service_description(
- _full_duplex_call,
- messages_pb2.StreamingOutputCallRequest.FromString,
- messages_pb2.StreamingOutputCallResponse.SerializeToString)
-
-# NOTE(nathaniel): Apparently this is the same as the full-duplex call?
-_CLIENT_HALF_DUPLEX_CALL = utilities.stream_stream_invocation_description(
- messages_pb2.StreamingOutputCallRequest.SerializeToString,
- messages_pb2.StreamingOutputCallResponse.FromString)
-_SERVER_HALF_DUPLEX_CALL = utilities.stream_stream_service_description(
- _full_duplex_call,
- messages_pb2.StreamingOutputCallRequest.FromString,
- messages_pb2.StreamingOutputCallResponse.SerializeToString)
-
-
-SERVICE_NAME = 'grpc.testing.TestService'
-
-_EMPTY_CALL_METHOD_NAME = 'EmptyCall'
-_UNARY_CALL_METHOD_NAME = 'UnaryCall'
-_STREAMING_OUTPUT_CALL_METHOD_NAME = 'StreamingOutputCall'
-_STREAMING_INPUT_CALL_METHOD_NAME = 'StreamingInputCall'
-_FULL_DUPLEX_CALL_METHOD_NAME = 'FullDuplexCall'
-_HALF_DUPLEX_CALL_METHOD_NAME = 'HalfDuplexCall'
-
-CLIENT_METHODS = {
- _EMPTY_CALL_METHOD_NAME: _CLIENT_EMPTY_CALL,
- _UNARY_CALL_METHOD_NAME: _CLIENT_UNARY_CALL,
- _STREAMING_OUTPUT_CALL_METHOD_NAME: _CLIENT_STREAMING_OUTPUT_CALL,
- _STREAMING_INPUT_CALL_METHOD_NAME: _CLIENT_STREAMING_INPUT_CALL,
- _FULL_DUPLEX_CALL_METHOD_NAME: _CLIENT_FULL_DUPLEX_CALL,
- _HALF_DUPLEX_CALL_METHOD_NAME: _CLIENT_HALF_DUPLEX_CALL,
-}
-
-SERVER_METHODS = {
- _EMPTY_CALL_METHOD_NAME: _SERVER_EMPTY_CALL,
- _UNARY_CALL_METHOD_NAME: _SERVER_UNARY_CALL,
- _STREAMING_OUTPUT_CALL_METHOD_NAME: _SERVER_STREAMING_OUTPUT_CALL,
- _STREAMING_INPUT_CALL_METHOD_NAME: _SERVER_STREAMING_INPUT_CALL,
- _FULL_DUPLEX_CALL_METHOD_NAME: _SERVER_FULL_DUPLEX_CALL,
- _HALF_DUPLEX_CALL_METHOD_NAME: _SERVER_HALF_DUPLEX_CALL,
-}
+ type=messages_pb2.COMPRESSABLE,
+ body=b'\x00' * request.response_size))
+
+ def StreamingOutputCall(self, request, context):
+ for response_parameters in request.response_parameters:
+ yield messages_pb2.StreamingOutputCallResponse(
+ payload=messages_pb2.Payload(
+ type=request.response_type,
+ body=b'\x00' * response_parameters.size))
+
+ def StreamingInputCall(self, request_iterator, context):
+ aggregate_size = 0
+ for request in request_iterator:
+ if request.payload and request.payload.body:
+ aggregate_size += len(request.payload.body)
+ return messages_pb2.StreamingInputCallResponse(
+ aggregated_payload_size=aggregate_size)
+
+ def FullDuplexCall(self, request_iterator, context):
+ for request in request_iterator:
+ yield messages_pb2.StreamingOutputCallResponse(
+ payload=messages_pb2.Payload(
+ type=request.payload.type,
+ body=b'\x00' * request.response_parameters[0].size))
+
+ # NOTE(nathaniel): Apparently this is the same as the full-duplex call?
+ # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)...
+ def HalfDuplexCall(self, request_iterator, context):
+ return self.FullDuplexCall(request_iterator, context)
def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope):
@@ -162,7 +92,7 @@ def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope):
response_type=messages_pb2.COMPRESSABLE, response_size=314159,
payload=messages_pb2.Payload(body=b'\x00' * 271828),
fill_username=fill_username, fill_oauth_scope=fill_oauth_scope)
- response_future = stub.UnaryCall.async(request, _TIMEOUT)
+ response_future = stub.UnaryCall.future(request, _TIMEOUT)
response = response_future.result()
if response.payload.type is not messages_pb2.COMPRESSABLE:
raise ValueError(
@@ -227,7 +157,7 @@ def _cancel_after_begin(stub):
payloads = [messages_pb2.Payload(body=b'\x00' * size) for size in sizes]
requests = [messages_pb2.StreamingInputCallRequest(payload=payload)
for payload in payloads]
- responses = stub.StreamingInputCall.async(requests, _TIMEOUT)
+ responses = stub.StreamingInputCall.future(requests, _TIMEOUT)
responses.cancel()
if not responses.cancelled():
raise ValueError('expected call to be cancelled')
@@ -332,7 +262,7 @@ def _timeout_on_sleeping_server(stub):
time.sleep(0.1)
try:
next(response_iterator)
- except exceptions.ExpirationError:
+ except face.ExpirationError:
pass
else:
raise ValueError('expected call to exceed deadline')
diff --git a/src/python/grpcio_test/grpc_interop/server.py b/src/python/grpcio_test/grpc_interop/server.py
index d4c1b4dbf6..b541087663 100644
--- a/src/python/grpcio_test/grpc_interop/server.py
+++ b/src/python/grpcio_test/grpc_interop/server.py
@@ -33,10 +33,11 @@ import argparse
import logging
import time
-from grpc.early_adopter import implementations
+from grpc.beta import implementations
from grpc_interop import methods
from grpc_interop import resources
+from grpc_interop import test_pb2
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
@@ -50,15 +51,15 @@ def serve():
default=False, type=resources.parse_bool)
args = parser.parse_args()
+ server = test_pb2.beta_create_TestService_server(methods.TestService())
if args.use_tls:
private_key = resources.private_key()
certificate_chain = resources.certificate_chain()
- server = implementations.server(
- methods.SERVICE_NAME, methods.SERVER_METHODS, args.port,
- private_key=private_key, certificate_chain=certificate_chain)
+ credentials = implementations.ssl_server_credentials(
+ [(private_key, certificate_chain)])
+ server.add_secure_port('[::]:{}'.format(args.port), credentials)
else:
- server = implementations.server(
- methods.SERVICE_NAME, methods.SERVER_METHODS, args.port)
+ server.add_insecure_port('[::]:{}'.format(args.port))
server.start()
logging.info('Server serving.')
diff --git a/src/python/grpcio_test/grpc_interop/test.proto b/src/python/grpcio_test/grpc_interop/test.proto
new file mode 100644
index 0000000000..b499813e56
--- /dev/null
+++ b/src/python/grpcio_test/grpc_interop/test.proto
@@ -0,0 +1,86 @@
+
+// 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.
+
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+
+syntax = "proto3";
+
+import "grpc_interop/empty.proto";
+import "grpc_interop/messages.proto";
+
+package grpc.testing;
+
+// A simple service to test the various types of RPCs and experiment with
+// performance with various types of payload.
+service TestService {
+ // One empty request followed by one empty response.
+ rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty);
+
+ // One request followed by one response.
+ rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
+
+ // One request followed by a sequence of responses (streamed download).
+ // The server returns the payload with client desired type and sizes.
+ rpc StreamingOutputCall(StreamingOutputCallRequest)
+ returns (stream StreamingOutputCallResponse);
+
+ // A sequence of requests followed by one response (streamed upload).
+ // The server returns the aggregated size of client payload as the result.
+ rpc StreamingInputCall(stream StreamingInputCallRequest)
+ returns (StreamingInputCallResponse);
+
+ // A sequence of requests with each request served by the server immediately.
+ // As one request could lead to multiple responses, this interface
+ // demonstrates the idea of full duplexing.
+ rpc FullDuplexCall(stream StreamingOutputCallRequest)
+ returns (stream StreamingOutputCallResponse);
+
+ // A sequence of requests followed by a sequence of responses.
+ // The server buffers all the client requests and then serves them in order. A
+ // stream of responses are returned to the client when the server starts with
+ // first request.
+ rpc HalfDuplexCall(stream StreamingOutputCallRequest)
+ returns (stream StreamingOutputCallResponse);
+}
+
+
+// A simple service NOT implemented at servers so clients can test for
+// that case.
+service UnimplementedService {
+ // A call that no server should implement
+ rpc UnimplementedCall(grpc.testing.Empty) returns(grpc.testing.Empty);
+}
+
+// A service used to control reconnect server.
+service ReconnectService {
+ rpc Start(grpc.testing.Empty) returns (grpc.testing.Empty);
+ rpc Stop(grpc.testing.Empty) returns (grpc.testing.ReconnectInfo);
+}
diff --git a/src/python/grpcio_test/grpc_interop/test_pb2.py b/src/python/grpcio_test/grpc_interop/test_pb2.py
deleted file mode 100644
index 71325d5a9f..0000000000
--- a/src/python/grpcio_test/grpc_interop/test_pb2.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: test/cpp/interop/test.proto
-
-import sys
-_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
-from google.protobuf import descriptor as _descriptor
-from google.protobuf import message as _message
-from google.protobuf import reflection as _reflection
-from google.protobuf import symbol_database as _symbol_database
-from google.protobuf import descriptor_pb2
-# @@protoc_insertion_point(imports)
-
-_sym_db = _symbol_database.Default()
-
-
-from test.cpp.interop import empty_pb2 as test_dot_cpp_dot_interop_dot_empty__pb2
-from test.cpp.interop import messages_pb2 as test_dot_cpp_dot_interop_dot_messages__pb2
-
-
-DESCRIPTOR = _descriptor.FileDescriptor(
- name='test/cpp/interop/test.proto',
- package='grpc.testing',
- serialized_pb=_b('\n\x1btest/cpp/interop/test.proto\x12\x0cgrpc.testing\x1a\x1ctest/cpp/interop/empty.proto\x1a\x1ftest/cpp/interop/messages.proto2\xbb\x04\n\x0bTestService\x12\x35\n\tEmptyCall\x12\x13.grpc.testing.Empty\x1a\x13.grpc.testing.Empty\x12\x46\n\tUnaryCall\x12\x1b.grpc.testing.SimpleRequest\x1a\x1c.grpc.testing.SimpleResponse\x12l\n\x13StreamingOutputCall\x12(.grpc.testing.StreamingOutputCallRequest\x1a).grpc.testing.StreamingOutputCallResponse0\x01\x12i\n\x12StreamingInputCall\x12\'.grpc.testing.StreamingInputCallRequest\x1a(.grpc.testing.StreamingInputCallResponse(\x01\x12i\n\x0e\x46ullDuplexCall\x12(.grpc.testing.StreamingOutputCallRequest\x1a).grpc.testing.StreamingOutputCallResponse(\x01\x30\x01\x12i\n\x0eHalfDuplexCall\x12(.grpc.testing.StreamingOutputCallRequest\x1a).grpc.testing.StreamingOutputCallResponse(\x01\x30\x01')
- ,
- dependencies=[test_dot_cpp_dot_interop_dot_empty__pb2.DESCRIPTOR,test_dot_cpp_dot_interop_dot_messages__pb2.DESCRIPTOR,])
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
-
-
-
-
-
-import abc
-from grpc.early_adopter import implementations
-from grpc.framework.alpha import utilities
-class EarlyAdopterTestServiceServicer(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
- def EmptyCall(self, request, context):
- raise NotImplementedError()
- @abc.abstractmethod
- def UnaryCall(self, request, context):
- raise NotImplementedError()
- @abc.abstractmethod
- def StreamingOutputCall(self, request, context):
- raise NotImplementedError()
- @abc.abstractmethod
- def StreamingInputCall(self, request_iterator, context):
- raise NotImplementedError()
- @abc.abstractmethod
- def FullDuplexCall(self, request_iterator, context):
- raise NotImplementedError()
- @abc.abstractmethod
- def HalfDuplexCall(self, request_iterator, context):
- raise NotImplementedError()
-class EarlyAdopterTestServiceServer(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
- def start(self):
- raise NotImplementedError()
- @abc.abstractmethod
- def stop(self):
- raise NotImplementedError()
-class EarlyAdopterTestServiceStub(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
- def EmptyCall(self, request):
- raise NotImplementedError()
- EmptyCall.async = None
- @abc.abstractmethod
- def UnaryCall(self, request):
- raise NotImplementedError()
- UnaryCall.async = None
- @abc.abstractmethod
- def StreamingOutputCall(self, request):
- raise NotImplementedError()
- StreamingOutputCall.async = None
- @abc.abstractmethod
- def StreamingInputCall(self, request_iterator):
- raise NotImplementedError()
- StreamingInputCall.async = None
- @abc.abstractmethod
- def FullDuplexCall(self, request_iterator):
- raise NotImplementedError()
- FullDuplexCall.async = None
- @abc.abstractmethod
- def HalfDuplexCall(self, request_iterator):
- raise NotImplementedError()
- HalfDuplexCall.async = None
-def early_adopter_create_TestService_server(servicer, port, private_key=None, certificate_chain=None):
- import test.cpp.interop.empty_pb2
- import test.cpp.interop.empty_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- method_service_descriptions = {
- "EmptyCall": utilities.unary_unary_service_description(
- servicer.EmptyCall,
- test.cpp.interop.empty_pb2.Empty.FromString,
- test.cpp.interop.empty_pb2.Empty.SerializeToString,
- ),
- "FullDuplexCall": utilities.stream_stream_service_description(
- servicer.FullDuplexCall,
- test.cpp.interop.messages_pb2.StreamingOutputCallRequest.FromString,
- test.cpp.interop.messages_pb2.StreamingOutputCallResponse.SerializeToString,
- ),
- "HalfDuplexCall": utilities.stream_stream_service_description(
- servicer.HalfDuplexCall,
- test.cpp.interop.messages_pb2.StreamingOutputCallRequest.FromString,
- test.cpp.interop.messages_pb2.StreamingOutputCallResponse.SerializeToString,
- ),
- "StreamingInputCall": utilities.stream_unary_service_description(
- servicer.StreamingInputCall,
- test.cpp.interop.messages_pb2.StreamingInputCallRequest.FromString,
- test.cpp.interop.messages_pb2.StreamingInputCallResponse.SerializeToString,
- ),
- "StreamingOutputCall": utilities.unary_stream_service_description(
- servicer.StreamingOutputCall,
- test.cpp.interop.messages_pb2.StreamingOutputCallRequest.FromString,
- test.cpp.interop.messages_pb2.StreamingOutputCallResponse.SerializeToString,
- ),
- "UnaryCall": utilities.unary_unary_service_description(
- servicer.UnaryCall,
- test.cpp.interop.messages_pb2.SimpleRequest.FromString,
- test.cpp.interop.messages_pb2.SimpleResponse.SerializeToString,
- ),
- }
- return implementations.server("grpc.testing.TestService", method_service_descriptions, port, private_key=private_key, certificate_chain=certificate_chain)
-def early_adopter_create_TestService_stub(host, port, metadata_transformer=None, secure=False, root_certificates=None, private_key=None, certificate_chain=None, server_host_override=None):
- import test.cpp.interop.empty_pb2
- import test.cpp.interop.empty_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- import test.cpp.interop.messages_pb2
- method_invocation_descriptions = {
- "EmptyCall": utilities.unary_unary_invocation_description(
- test.cpp.interop.empty_pb2.Empty.SerializeToString,
- test.cpp.interop.empty_pb2.Empty.FromString,
- ),
- "FullDuplexCall": utilities.stream_stream_invocation_description(
- test.cpp.interop.messages_pb2.StreamingOutputCallRequest.SerializeToString,
- test.cpp.interop.messages_pb2.StreamingOutputCallResponse.FromString,
- ),
- "HalfDuplexCall": utilities.stream_stream_invocation_description(
- test.cpp.interop.messages_pb2.StreamingOutputCallRequest.SerializeToString,
- test.cpp.interop.messages_pb2.StreamingOutputCallResponse.FromString,
- ),
- "StreamingInputCall": utilities.stream_unary_invocation_description(
- test.cpp.interop.messages_pb2.StreamingInputCallRequest.SerializeToString,
- test.cpp.interop.messages_pb2.StreamingInputCallResponse.FromString,
- ),
- "StreamingOutputCall": utilities.unary_stream_invocation_description(
- test.cpp.interop.messages_pb2.StreamingOutputCallRequest.SerializeToString,
- test.cpp.interop.messages_pb2.StreamingOutputCallResponse.FromString,
- ),
- "UnaryCall": utilities.unary_unary_invocation_description(
- test.cpp.interop.messages_pb2.SimpleRequest.SerializeToString,
- test.cpp.interop.messages_pb2.SimpleResponse.FromString,
- ),
- }
- return implementations.stub("grpc.testing.TestService", method_invocation_descriptions, host, port, metadata_transformer=metadata_transformer, secure=secure, root_certificates=root_certificates, private_key=private_key, certificate_chain=certificate_chain, server_host_override=server_host_override)
-# @@protoc_insertion_point(module_scope)
diff --git a/src/python/grpcio_test/grpc_protoc_plugin/alpha_python_plugin_test.py b/src/python/grpcio_test/grpc_protoc_plugin/alpha_python_plugin_test.py
deleted file mode 100644
index b200d129a9..0000000000
--- a/src/python/grpcio_test/grpc_protoc_plugin/alpha_python_plugin_test.py
+++ /dev/null
@@ -1,541 +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.
-
-import argparse
-import contextlib
-import distutils.spawn
-import errno
-import itertools
-import os
-import pkg_resources
-import shutil
-import subprocess
-import sys
-import tempfile
-import threading
-import time
-import unittest
-
-from grpc.framework.alpha import exceptions
-from grpc.framework.foundation import future
-
-# Identifiers of entities we expect to find in the generated module.
-SERVICER_IDENTIFIER = 'EarlyAdopterTestServiceServicer'
-SERVER_IDENTIFIER = 'EarlyAdopterTestServiceServer'
-STUB_IDENTIFIER = 'EarlyAdopterTestServiceStub'
-SERVER_FACTORY_IDENTIFIER = 'early_adopter_create_TestService_server'
-STUB_FACTORY_IDENTIFIER = 'early_adopter_create_TestService_stub'
-
-# The timeout used in tests of RPCs that are supposed to expire.
-SHORT_TIMEOUT = 2
-# The timeout used in tests of RPCs that are not supposed to expire. The
-# absurdly large value doesn't matter since no passing execution of this test
-# module will ever wait the duration.
-LONG_TIMEOUT = 600
-NO_DELAY = 0
-
-
-class _ServicerMethods(object):
-
- def __init__(self, test_pb2, delay):
- self._condition = threading.Condition()
- self._delay = delay
- self._paused = False
- self._fail = False
- self._test_pb2 = test_pb2
-
- @contextlib.contextmanager
- def pause(self): # pylint: disable=invalid-name
- with self._condition:
- self._paused = True
- yield
- with self._condition:
- self._paused = False
- self._condition.notify_all()
-
- @contextlib.contextmanager
- def fail(self): # pylint: disable=invalid-name
- with self._condition:
- self._fail = True
- yield
- with self._condition:
- self._fail = False
-
- def _control(self): # pylint: disable=invalid-name
- with self._condition:
- if self._fail:
- raise ValueError()
- while self._paused:
- self._condition.wait()
- time.sleep(self._delay)
-
- def UnaryCall(self, request, unused_rpc_context):
- response = self._test_pb2.SimpleResponse()
- response.payload.payload_type = self._test_pb2.COMPRESSABLE
- response.payload.payload_compressable = 'a' * request.response_size
- self._control()
- return response
-
- def StreamingOutputCall(self, request, unused_rpc_context):
- for parameter in request.response_parameters:
- response = self._test_pb2.StreamingOutputCallResponse()
- response.payload.payload_type = self._test_pb2.COMPRESSABLE
- response.payload.payload_compressable = 'a' * parameter.size
- self._control()
- yield response
-
- def StreamingInputCall(self, request_iter, unused_rpc_context):
- response = self._test_pb2.StreamingInputCallResponse()
- aggregated_payload_size = 0
- for request in request_iter:
- aggregated_payload_size += len(request.payload.payload_compressable)
- response.aggregated_payload_size = aggregated_payload_size
- self._control()
- return response
-
- def FullDuplexCall(self, request_iter, unused_rpc_context):
- for request in request_iter:
- for parameter in request.response_parameters:
- response = self._test_pb2.StreamingOutputCallResponse()
- response.payload.payload_type = self._test_pb2.COMPRESSABLE
- response.payload.payload_compressable = 'a' * parameter.size
- self._control()
- yield response
-
- def HalfDuplexCall(self, request_iter, unused_rpc_context):
- responses = []
- for request in request_iter:
- for parameter in request.response_parameters:
- response = self._test_pb2.StreamingOutputCallResponse()
- response.payload.payload_type = self._test_pb2.COMPRESSABLE
- response.payload.payload_compressable = 'a' * parameter.size
- self._control()
- responses.append(response)
- for response in responses:
- yield response
-
-
-@contextlib.contextmanager
-def _CreateService(test_pb2, delay):
- """Provides a servicer backend and a stub.
-
- The servicer is just the implementation
- of the actual servicer passed to the face player of the python RPC
- implementation; the two are detached.
-
- Non-zero delay puts a delay on each call to the servicer, representative of
- communication latency. Timeout is the default timeout for the stub while
- waiting for the service.
-
- Args:
- test_pb2: The test_pb2 module generated by this test.
- delay: Delay in seconds per response from the servicer.
-
- Yields:
- A (servicer_methods, servicer, stub) three-tuple where servicer_methods is
- the back-end of the service bound to the stub and the server and stub
- are both activated and ready for use.
- """
- servicer_methods = _ServicerMethods(test_pb2, delay)
-
- class Servicer(getattr(test_pb2, SERVICER_IDENTIFIER)):
-
- def UnaryCall(self, request, context):
- return servicer_methods.UnaryCall(request, context)
-
- def StreamingOutputCall(self, request, context):
- return servicer_methods.StreamingOutputCall(request, context)
-
- def StreamingInputCall(self, request_iter, context):
- return servicer_methods.StreamingInputCall(request_iter, context)
-
- def FullDuplexCall(self, request_iter, context):
- return servicer_methods.FullDuplexCall(request_iter, context)
-
- def HalfDuplexCall(self, request_iter, context):
- return servicer_methods.HalfDuplexCall(request_iter, context)
-
- servicer = Servicer()
- server = getattr(
- test_pb2, SERVER_FACTORY_IDENTIFIER)(servicer, 0)
- with server:
- port = server.port()
- stub = getattr(test_pb2, STUB_FACTORY_IDENTIFIER)('localhost', port)
- with stub:
- yield servicer_methods, stub, server
-
-
-def _streaming_input_request_iterator(test_pb2):
- for _ in range(3):
- request = test_pb2.StreamingInputCallRequest()
- request.payload.payload_type = test_pb2.COMPRESSABLE
- request.payload.payload_compressable = 'a'
- yield request
-
-
-def _streaming_output_request(test_pb2):
- request = test_pb2.StreamingOutputCallRequest()
- sizes = [1, 2, 3]
- request.response_parameters.add(size=sizes[0], interval_us=0)
- request.response_parameters.add(size=sizes[1], interval_us=0)
- request.response_parameters.add(size=sizes[2], interval_us=0)
- return request
-
-
-def _full_duplex_request_iterator(test_pb2):
- request = test_pb2.StreamingOutputCallRequest()
- request.response_parameters.add(size=1, interval_us=0)
- yield request
- request = test_pb2.StreamingOutputCallRequest()
- request.response_parameters.add(size=2, interval_us=0)
- request.response_parameters.add(size=3, interval_us=0)
- yield request
-
-
-class PythonPluginTest(unittest.TestCase):
- """Test case for the gRPC Python protoc-plugin.
-
- While reading these tests, remember that the futures API
- (`stub.method.async()`) only gives futures for the *non-streaming* responses,
- else it behaves like its blocking cousin.
- """
-
- def setUp(self):
- # Assume that the appropriate protoc and grpc_python_plugins are on the
- # path.
- protoc_command = 'protoc'
- protoc_plugin_filename = distutils.spawn.find_executable(
- 'grpc_python_plugin')
- test_proto_filename = pkg_resources.resource_filename(
- 'grpc_protoc_plugin', 'test.proto')
- if not os.path.isfile(protoc_command):
- # Assume that if we haven't built protoc that it's on the system.
- protoc_command = 'protoc'
-
- # Ensure that the output directory exists.
- self.outdir = tempfile.mkdtemp()
-
- # Invoke protoc with the plugin.
- cmd = [
- protoc_command,
- '--plugin=protoc-gen-python-grpc=%s' % protoc_plugin_filename,
- '-I .',
- '--python_out=%s' % self.outdir,
- '--python-grpc_out=%s' % self.outdir,
- os.path.basename(test_proto_filename),
- ]
- subprocess.check_call(' '.join(cmd), shell=True, env=os.environ,
- cwd=os.path.dirname(test_proto_filename))
- sys.path.append(self.outdir)
-
- def tearDown(self):
- try:
- shutil.rmtree(self.outdir)
- except OSError as exc:
- if exc.errno != errno.ENOENT:
- raise
-
- # TODO(atash): Figure out which of these tests is hanging flakily with small
- # probability.
-
- def testImportAttributes(self):
- # check that we can access the generated module and its members.
- import test_pb2 # pylint: disable=g-import-not-at-top
- self.assertIsNotNone(getattr(test_pb2, SERVICER_IDENTIFIER, None))
- self.assertIsNotNone(getattr(test_pb2, SERVER_IDENTIFIER, None))
- self.assertIsNotNone(getattr(test_pb2, STUB_IDENTIFIER, None))
- self.assertIsNotNone(getattr(test_pb2, SERVER_FACTORY_IDENTIFIER, None))
- self.assertIsNotNone(getattr(test_pb2, STUB_FACTORY_IDENTIFIER, None))
-
- def testUpDown(self):
- import test_pb2
- with _CreateService(
- test_pb2, NO_DELAY) as (servicer, stub, unused_server):
- request = test_pb2.SimpleRequest(response_size=13)
-
- def testUnaryCall(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- timeout = 6 # TODO(issue 2039): LONG_TIMEOUT like the other methods.
- request = test_pb2.SimpleRequest(response_size=13)
- response = stub.UnaryCall(request, timeout)
- expected_response = methods.UnaryCall(request, 'not a real RpcContext!')
- self.assertEqual(expected_response, response)
-
- def testUnaryCallAsync(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = test_pb2.SimpleRequest(response_size=13)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- # Check that the call does not block waiting for the server to respond.
- with methods.pause():
- response_future = stub.UnaryCall.async(request, LONG_TIMEOUT)
- response = response_future.result()
- expected_response = methods.UnaryCall(request, 'not a real RpcContext!')
- self.assertEqual(expected_response, response)
-
- def testUnaryCallAsyncExpired(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- request = test_pb2.SimpleRequest(response_size=13)
- with methods.pause():
- response_future = stub.UnaryCall.async(request, SHORT_TIMEOUT)
- with self.assertRaises(exceptions.ExpirationError):
- response_future.result()
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testUnaryCallAsyncCancelled(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = test_pb2.SimpleRequest(response_size=13)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- response_future = stub.UnaryCall.async(request, 1)
- response_future.cancel()
- self.assertTrue(response_future.cancelled())
-
- def testUnaryCallAsyncFailed(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = test_pb2.SimpleRequest(response_size=13)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.fail():
- response_future = stub.UnaryCall.async(request, LONG_TIMEOUT)
- self.assertIsNotNone(response_future.exception())
-
- def testStreamingOutputCall(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = _streaming_output_request(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- responses = stub.StreamingOutputCall(request, LONG_TIMEOUT)
- expected_responses = methods.StreamingOutputCall(
- request, 'not a real RpcContext!')
- for expected_response, response in itertools.izip_longest(
- expected_responses, responses):
- self.assertEqual(expected_response, response)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testStreamingOutputCallExpired(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = _streaming_output_request(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT)
- with self.assertRaises(exceptions.ExpirationError):
- list(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testStreamingOutputCallCancelled(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = _streaming_output_request(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (
- unused_methods, stub, unused_server):
- responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT)
- next(responses)
- responses.cancel()
- with self.assertRaises(future.CancelledError):
- next(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this times out '
- 'instead of raising the proper error.')
- def testStreamingOutputCallFailed(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = _streaming_output_request(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.fail():
- responses = stub.StreamingOutputCall(request, 1)
- self.assertIsNotNone(responses)
- with self.assertRaises(exceptions.ServicerError):
- next(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testStreamingInputCall(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- response = stub.StreamingInputCall(
- _streaming_input_request_iterator(test_pb2), LONG_TIMEOUT)
- expected_response = methods.StreamingInputCall(
- _streaming_input_request_iterator(test_pb2), 'not a real RpcContext!')
- self.assertEqual(expected_response, response)
-
- def testStreamingInputCallAsync(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- response_future = stub.StreamingInputCall.async(
- _streaming_input_request_iterator(test_pb2), LONG_TIMEOUT)
- response = response_future.result()
- expected_response = methods.StreamingInputCall(
- _streaming_input_request_iterator(test_pb2), 'not a real RpcContext!')
- self.assertEqual(expected_response, response)
-
- def testStreamingInputCallAsyncExpired(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- response_future = stub.StreamingInputCall.async(
- _streaming_input_request_iterator(test_pb2), SHORT_TIMEOUT)
- with self.assertRaises(exceptions.ExpirationError):
- response_future.result()
- self.assertIsInstance(
- response_future.exception(), exceptions.ExpirationError)
-
- def testStreamingInputCallAsyncCancelled(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- timeout = 6 # TODO(issue 2039): LONG_TIMEOUT like the other methods.
- response_future = stub.StreamingInputCall.async(
- _streaming_input_request_iterator(test_pb2), timeout)
- response_future.cancel()
- self.assertTrue(response_future.cancelled())
- with self.assertRaises(future.CancelledError):
- response_future.result()
-
- def testStreamingInputCallAsyncFailed(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.fail():
- response_future = stub.StreamingInputCall.async(
- _streaming_input_request_iterator(test_pb2), SHORT_TIMEOUT)
- self.assertIsNotNone(response_future.exception())
-
- def testFullDuplexCall(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- responses = stub.FullDuplexCall(
- _full_duplex_request_iterator(test_pb2), LONG_TIMEOUT)
- expected_responses = methods.FullDuplexCall(
- _full_duplex_request_iterator(test_pb2), 'not a real RpcContext!')
- for expected_response, response in itertools.izip_longest(
- expected_responses, responses):
- self.assertEqual(expected_response, response)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testFullDuplexCallExpired(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request_iterator = _full_duplex_request_iterator(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- responses = stub.FullDuplexCall(request_iterator, SHORT_TIMEOUT)
- with self.assertRaises(exceptions.ExpirationError):
- list(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testFullDuplexCallCancelled(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- request_iterator = _full_duplex_request_iterator(test_pb2)
- responses = stub.FullDuplexCall(request_iterator, LONG_TIMEOUT)
- next(responses)
- responses.cancel()
- with self.assertRaises(future.CancelledError):
- next(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this hangs forever '
- 'and fix.')
- def testFullDuplexCallFailed(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request_iterator = _full_duplex_request_iterator(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.fail():
- responses = stub.FullDuplexCall(request_iterator, LONG_TIMEOUT)
- self.assertIsNotNone(responses)
- with self.assertRaises(exceptions.ServicerError):
- next(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testHalfDuplexCall(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- def half_duplex_request_iterator():
- request = test_pb2.StreamingOutputCallRequest()
- request.response_parameters.add(size=1, interval_us=0)
- yield request
- request = test_pb2.StreamingOutputCallRequest()
- request.response_parameters.add(size=2, interval_us=0)
- request.response_parameters.add(size=3, interval_us=0)
- yield request
- responses = stub.HalfDuplexCall(
- half_duplex_request_iterator(), LONG_TIMEOUT)
- expected_responses = methods.HalfDuplexCall(
- half_duplex_request_iterator(), 'not a real RpcContext!')
- for check in itertools.izip_longest(expected_responses, responses):
- expected_response, response = check
- self.assertEqual(expected_response, response)
-
- def testHalfDuplexCallWedged(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- condition = threading.Condition()
- wait_cell = [False]
- @contextlib.contextmanager
- def wait(): # pylint: disable=invalid-name
- # Where's Python 3's 'nonlocal' statement when you need it?
- with condition:
- wait_cell[0] = True
- yield
- with condition:
- wait_cell[0] = False
- condition.notify_all()
- def half_duplex_request_iterator():
- request = test_pb2.StreamingOutputCallRequest()
- request.response_parameters.add(size=1, interval_us=0)
- yield request
- with condition:
- while wait_cell[0]:
- condition.wait()
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- with wait():
- responses = stub.HalfDuplexCall(
- half_duplex_request_iterator(), SHORT_TIMEOUT)
- # half-duplex waits for the client to send all info
- with self.assertRaises(exceptions.ExpirationError):
- next(responses)
-
-
-if __name__ == '__main__':
- os.chdir(os.path.dirname(sys.argv[0]))
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_protoc_plugin/python_plugin_test.py b/src/python/grpcio_test/grpc_protoc_plugin/python_plugin_test.py
deleted file mode 100644
index b200d129a9..0000000000
--- a/src/python/grpcio_test/grpc_protoc_plugin/python_plugin_test.py
+++ /dev/null
@@ -1,541 +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.
-
-import argparse
-import contextlib
-import distutils.spawn
-import errno
-import itertools
-import os
-import pkg_resources
-import shutil
-import subprocess
-import sys
-import tempfile
-import threading
-import time
-import unittest
-
-from grpc.framework.alpha import exceptions
-from grpc.framework.foundation import future
-
-# Identifiers of entities we expect to find in the generated module.
-SERVICER_IDENTIFIER = 'EarlyAdopterTestServiceServicer'
-SERVER_IDENTIFIER = 'EarlyAdopterTestServiceServer'
-STUB_IDENTIFIER = 'EarlyAdopterTestServiceStub'
-SERVER_FACTORY_IDENTIFIER = 'early_adopter_create_TestService_server'
-STUB_FACTORY_IDENTIFIER = 'early_adopter_create_TestService_stub'
-
-# The timeout used in tests of RPCs that are supposed to expire.
-SHORT_TIMEOUT = 2
-# The timeout used in tests of RPCs that are not supposed to expire. The
-# absurdly large value doesn't matter since no passing execution of this test
-# module will ever wait the duration.
-LONG_TIMEOUT = 600
-NO_DELAY = 0
-
-
-class _ServicerMethods(object):
-
- def __init__(self, test_pb2, delay):
- self._condition = threading.Condition()
- self._delay = delay
- self._paused = False
- self._fail = False
- self._test_pb2 = test_pb2
-
- @contextlib.contextmanager
- def pause(self): # pylint: disable=invalid-name
- with self._condition:
- self._paused = True
- yield
- with self._condition:
- self._paused = False
- self._condition.notify_all()
-
- @contextlib.contextmanager
- def fail(self): # pylint: disable=invalid-name
- with self._condition:
- self._fail = True
- yield
- with self._condition:
- self._fail = False
-
- def _control(self): # pylint: disable=invalid-name
- with self._condition:
- if self._fail:
- raise ValueError()
- while self._paused:
- self._condition.wait()
- time.sleep(self._delay)
-
- def UnaryCall(self, request, unused_rpc_context):
- response = self._test_pb2.SimpleResponse()
- response.payload.payload_type = self._test_pb2.COMPRESSABLE
- response.payload.payload_compressable = 'a' * request.response_size
- self._control()
- return response
-
- def StreamingOutputCall(self, request, unused_rpc_context):
- for parameter in request.response_parameters:
- response = self._test_pb2.StreamingOutputCallResponse()
- response.payload.payload_type = self._test_pb2.COMPRESSABLE
- response.payload.payload_compressable = 'a' * parameter.size
- self._control()
- yield response
-
- def StreamingInputCall(self, request_iter, unused_rpc_context):
- response = self._test_pb2.StreamingInputCallResponse()
- aggregated_payload_size = 0
- for request in request_iter:
- aggregated_payload_size += len(request.payload.payload_compressable)
- response.aggregated_payload_size = aggregated_payload_size
- self._control()
- return response
-
- def FullDuplexCall(self, request_iter, unused_rpc_context):
- for request in request_iter:
- for parameter in request.response_parameters:
- response = self._test_pb2.StreamingOutputCallResponse()
- response.payload.payload_type = self._test_pb2.COMPRESSABLE
- response.payload.payload_compressable = 'a' * parameter.size
- self._control()
- yield response
-
- def HalfDuplexCall(self, request_iter, unused_rpc_context):
- responses = []
- for request in request_iter:
- for parameter in request.response_parameters:
- response = self._test_pb2.StreamingOutputCallResponse()
- response.payload.payload_type = self._test_pb2.COMPRESSABLE
- response.payload.payload_compressable = 'a' * parameter.size
- self._control()
- responses.append(response)
- for response in responses:
- yield response
-
-
-@contextlib.contextmanager
-def _CreateService(test_pb2, delay):
- """Provides a servicer backend and a stub.
-
- The servicer is just the implementation
- of the actual servicer passed to the face player of the python RPC
- implementation; the two are detached.
-
- Non-zero delay puts a delay on each call to the servicer, representative of
- communication latency. Timeout is the default timeout for the stub while
- waiting for the service.
-
- Args:
- test_pb2: The test_pb2 module generated by this test.
- delay: Delay in seconds per response from the servicer.
-
- Yields:
- A (servicer_methods, servicer, stub) three-tuple where servicer_methods is
- the back-end of the service bound to the stub and the server and stub
- are both activated and ready for use.
- """
- servicer_methods = _ServicerMethods(test_pb2, delay)
-
- class Servicer(getattr(test_pb2, SERVICER_IDENTIFIER)):
-
- def UnaryCall(self, request, context):
- return servicer_methods.UnaryCall(request, context)
-
- def StreamingOutputCall(self, request, context):
- return servicer_methods.StreamingOutputCall(request, context)
-
- def StreamingInputCall(self, request_iter, context):
- return servicer_methods.StreamingInputCall(request_iter, context)
-
- def FullDuplexCall(self, request_iter, context):
- return servicer_methods.FullDuplexCall(request_iter, context)
-
- def HalfDuplexCall(self, request_iter, context):
- return servicer_methods.HalfDuplexCall(request_iter, context)
-
- servicer = Servicer()
- server = getattr(
- test_pb2, SERVER_FACTORY_IDENTIFIER)(servicer, 0)
- with server:
- port = server.port()
- stub = getattr(test_pb2, STUB_FACTORY_IDENTIFIER)('localhost', port)
- with stub:
- yield servicer_methods, stub, server
-
-
-def _streaming_input_request_iterator(test_pb2):
- for _ in range(3):
- request = test_pb2.StreamingInputCallRequest()
- request.payload.payload_type = test_pb2.COMPRESSABLE
- request.payload.payload_compressable = 'a'
- yield request
-
-
-def _streaming_output_request(test_pb2):
- request = test_pb2.StreamingOutputCallRequest()
- sizes = [1, 2, 3]
- request.response_parameters.add(size=sizes[0], interval_us=0)
- request.response_parameters.add(size=sizes[1], interval_us=0)
- request.response_parameters.add(size=sizes[2], interval_us=0)
- return request
-
-
-def _full_duplex_request_iterator(test_pb2):
- request = test_pb2.StreamingOutputCallRequest()
- request.response_parameters.add(size=1, interval_us=0)
- yield request
- request = test_pb2.StreamingOutputCallRequest()
- request.response_parameters.add(size=2, interval_us=0)
- request.response_parameters.add(size=3, interval_us=0)
- yield request
-
-
-class PythonPluginTest(unittest.TestCase):
- """Test case for the gRPC Python protoc-plugin.
-
- While reading these tests, remember that the futures API
- (`stub.method.async()`) only gives futures for the *non-streaming* responses,
- else it behaves like its blocking cousin.
- """
-
- def setUp(self):
- # Assume that the appropriate protoc and grpc_python_plugins are on the
- # path.
- protoc_command = 'protoc'
- protoc_plugin_filename = distutils.spawn.find_executable(
- 'grpc_python_plugin')
- test_proto_filename = pkg_resources.resource_filename(
- 'grpc_protoc_plugin', 'test.proto')
- if not os.path.isfile(protoc_command):
- # Assume that if we haven't built protoc that it's on the system.
- protoc_command = 'protoc'
-
- # Ensure that the output directory exists.
- self.outdir = tempfile.mkdtemp()
-
- # Invoke protoc with the plugin.
- cmd = [
- protoc_command,
- '--plugin=protoc-gen-python-grpc=%s' % protoc_plugin_filename,
- '-I .',
- '--python_out=%s' % self.outdir,
- '--python-grpc_out=%s' % self.outdir,
- os.path.basename(test_proto_filename),
- ]
- subprocess.check_call(' '.join(cmd), shell=True, env=os.environ,
- cwd=os.path.dirname(test_proto_filename))
- sys.path.append(self.outdir)
-
- def tearDown(self):
- try:
- shutil.rmtree(self.outdir)
- except OSError as exc:
- if exc.errno != errno.ENOENT:
- raise
-
- # TODO(atash): Figure out which of these tests is hanging flakily with small
- # probability.
-
- def testImportAttributes(self):
- # check that we can access the generated module and its members.
- import test_pb2 # pylint: disable=g-import-not-at-top
- self.assertIsNotNone(getattr(test_pb2, SERVICER_IDENTIFIER, None))
- self.assertIsNotNone(getattr(test_pb2, SERVER_IDENTIFIER, None))
- self.assertIsNotNone(getattr(test_pb2, STUB_IDENTIFIER, None))
- self.assertIsNotNone(getattr(test_pb2, SERVER_FACTORY_IDENTIFIER, None))
- self.assertIsNotNone(getattr(test_pb2, STUB_FACTORY_IDENTIFIER, None))
-
- def testUpDown(self):
- import test_pb2
- with _CreateService(
- test_pb2, NO_DELAY) as (servicer, stub, unused_server):
- request = test_pb2.SimpleRequest(response_size=13)
-
- def testUnaryCall(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- timeout = 6 # TODO(issue 2039): LONG_TIMEOUT like the other methods.
- request = test_pb2.SimpleRequest(response_size=13)
- response = stub.UnaryCall(request, timeout)
- expected_response = methods.UnaryCall(request, 'not a real RpcContext!')
- self.assertEqual(expected_response, response)
-
- def testUnaryCallAsync(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = test_pb2.SimpleRequest(response_size=13)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- # Check that the call does not block waiting for the server to respond.
- with methods.pause():
- response_future = stub.UnaryCall.async(request, LONG_TIMEOUT)
- response = response_future.result()
- expected_response = methods.UnaryCall(request, 'not a real RpcContext!')
- self.assertEqual(expected_response, response)
-
- def testUnaryCallAsyncExpired(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- request = test_pb2.SimpleRequest(response_size=13)
- with methods.pause():
- response_future = stub.UnaryCall.async(request, SHORT_TIMEOUT)
- with self.assertRaises(exceptions.ExpirationError):
- response_future.result()
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testUnaryCallAsyncCancelled(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = test_pb2.SimpleRequest(response_size=13)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- response_future = stub.UnaryCall.async(request, 1)
- response_future.cancel()
- self.assertTrue(response_future.cancelled())
-
- def testUnaryCallAsyncFailed(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = test_pb2.SimpleRequest(response_size=13)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.fail():
- response_future = stub.UnaryCall.async(request, LONG_TIMEOUT)
- self.assertIsNotNone(response_future.exception())
-
- def testStreamingOutputCall(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = _streaming_output_request(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- responses = stub.StreamingOutputCall(request, LONG_TIMEOUT)
- expected_responses = methods.StreamingOutputCall(
- request, 'not a real RpcContext!')
- for expected_response, response in itertools.izip_longest(
- expected_responses, responses):
- self.assertEqual(expected_response, response)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testStreamingOutputCallExpired(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = _streaming_output_request(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT)
- with self.assertRaises(exceptions.ExpirationError):
- list(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testStreamingOutputCallCancelled(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = _streaming_output_request(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (
- unused_methods, stub, unused_server):
- responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT)
- next(responses)
- responses.cancel()
- with self.assertRaises(future.CancelledError):
- next(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this times out '
- 'instead of raising the proper error.')
- def testStreamingOutputCallFailed(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request = _streaming_output_request(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.fail():
- responses = stub.StreamingOutputCall(request, 1)
- self.assertIsNotNone(responses)
- with self.assertRaises(exceptions.ServicerError):
- next(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testStreamingInputCall(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- response = stub.StreamingInputCall(
- _streaming_input_request_iterator(test_pb2), LONG_TIMEOUT)
- expected_response = methods.StreamingInputCall(
- _streaming_input_request_iterator(test_pb2), 'not a real RpcContext!')
- self.assertEqual(expected_response, response)
-
- def testStreamingInputCallAsync(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- response_future = stub.StreamingInputCall.async(
- _streaming_input_request_iterator(test_pb2), LONG_TIMEOUT)
- response = response_future.result()
- expected_response = methods.StreamingInputCall(
- _streaming_input_request_iterator(test_pb2), 'not a real RpcContext!')
- self.assertEqual(expected_response, response)
-
- def testStreamingInputCallAsyncExpired(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- response_future = stub.StreamingInputCall.async(
- _streaming_input_request_iterator(test_pb2), SHORT_TIMEOUT)
- with self.assertRaises(exceptions.ExpirationError):
- response_future.result()
- self.assertIsInstance(
- response_future.exception(), exceptions.ExpirationError)
-
- def testStreamingInputCallAsyncCancelled(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- timeout = 6 # TODO(issue 2039): LONG_TIMEOUT like the other methods.
- response_future = stub.StreamingInputCall.async(
- _streaming_input_request_iterator(test_pb2), timeout)
- response_future.cancel()
- self.assertTrue(response_future.cancelled())
- with self.assertRaises(future.CancelledError):
- response_future.result()
-
- def testStreamingInputCallAsyncFailed(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.fail():
- response_future = stub.StreamingInputCall.async(
- _streaming_input_request_iterator(test_pb2), SHORT_TIMEOUT)
- self.assertIsNotNone(response_future.exception())
-
- def testFullDuplexCall(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- responses = stub.FullDuplexCall(
- _full_duplex_request_iterator(test_pb2), LONG_TIMEOUT)
- expected_responses = methods.FullDuplexCall(
- _full_duplex_request_iterator(test_pb2), 'not a real RpcContext!')
- for expected_response, response in itertools.izip_longest(
- expected_responses, responses):
- self.assertEqual(expected_response, response)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testFullDuplexCallExpired(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request_iterator = _full_duplex_request_iterator(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.pause():
- responses = stub.FullDuplexCall(request_iterator, SHORT_TIMEOUT)
- with self.assertRaises(exceptions.ExpirationError):
- list(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testFullDuplexCallCancelled(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- request_iterator = _full_duplex_request_iterator(test_pb2)
- responses = stub.FullDuplexCall(request_iterator, LONG_TIMEOUT)
- next(responses)
- responses.cancel()
- with self.assertRaises(future.CancelledError):
- next(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this hangs forever '
- 'and fix.')
- def testFullDuplexCallFailed(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- request_iterator = _full_duplex_request_iterator(test_pb2)
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- with methods.fail():
- responses = stub.FullDuplexCall(request_iterator, LONG_TIMEOUT)
- self.assertIsNotNone(responses)
- with self.assertRaises(exceptions.ServicerError):
- next(responses)
-
- @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
- 'forever and fix.')
- def testHalfDuplexCall(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- with _CreateService(test_pb2, NO_DELAY) as (
- methods, stub, unused_server):
- def half_duplex_request_iterator():
- request = test_pb2.StreamingOutputCallRequest()
- request.response_parameters.add(size=1, interval_us=0)
- yield request
- request = test_pb2.StreamingOutputCallRequest()
- request.response_parameters.add(size=2, interval_us=0)
- request.response_parameters.add(size=3, interval_us=0)
- yield request
- responses = stub.HalfDuplexCall(
- half_duplex_request_iterator(), LONG_TIMEOUT)
- expected_responses = methods.HalfDuplexCall(
- half_duplex_request_iterator(), 'not a real RpcContext!')
- for check in itertools.izip_longest(expected_responses, responses):
- expected_response, response = check
- self.assertEqual(expected_response, response)
-
- def testHalfDuplexCallWedged(self):
- import test_pb2 # pylint: disable=g-import-not-at-top
- condition = threading.Condition()
- wait_cell = [False]
- @contextlib.contextmanager
- def wait(): # pylint: disable=invalid-name
- # Where's Python 3's 'nonlocal' statement when you need it?
- with condition:
- wait_cell[0] = True
- yield
- with condition:
- wait_cell[0] = False
- condition.notify_all()
- def half_duplex_request_iterator():
- request = test_pb2.StreamingOutputCallRequest()
- request.response_parameters.add(size=1, interval_us=0)
- yield request
- with condition:
- while wait_cell[0]:
- condition.wait()
- with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
- with wait():
- responses = stub.HalfDuplexCall(
- half_duplex_request_iterator(), SHORT_TIMEOUT)
- # half-duplex waits for the client to send all info
- with self.assertRaises(exceptions.ExpirationError):
- next(responses)
-
-
-if __name__ == '__main__':
- os.chdir(os.path.dirname(sys.argv[0]))
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_protoc_plugin/test.proto b/src/python/grpcio_test/grpc_protoc_plugin/test.proto
index ed7c6a7b79..6762a8e7f3 100644
--- a/src/python/grpcio_test/grpc_protoc_plugin/test.proto
+++ b/src/python/grpcio_test/grpc_protoc_plugin/test.proto
@@ -32,7 +32,7 @@
// This file is duplicated around the code base. See GitHub issue #526.
syntax = "proto2";
-package grpc.testing;
+package grpc_protoc_plugin;
enum PayloadType {
// Compressable text format.
diff --git a/src/python/grpcio_test/grpc_test/_adapter/_blocking_invocation_inline_service_test.py b/src/python/grpcio_test/grpc_test/_adapter/_blocking_invocation_inline_service_test.py
deleted file mode 100644
index a1f776211c..0000000000
--- a/src/python/grpcio_test/grpc_test/_adapter/_blocking_invocation_inline_service_test.py
+++ /dev/null
@@ -1,46 +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.
-
-"""One of the tests of the Face layer of RPC Framework."""
-
-import unittest
-
-from grpc_test._adapter import _face_test_case
-from grpc_test.framework.face.testing import blocking_invocation_inline_service_test_case as test_case
-
-
-class BlockingInvocationInlineServiceTest(
- _face_test_case.FaceTestCase,
- test_case.BlockingInvocationInlineServiceTestCase,
- unittest.TestCase):
- pass
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/_adapter/_event_invocation_synchronous_event_service_test.py b/src/python/grpcio_test/grpc_test/_adapter/_event_invocation_synchronous_event_service_test.py
deleted file mode 100644
index 0d01ebc8dc..0000000000
--- a/src/python/grpcio_test/grpc_test/_adapter/_event_invocation_synchronous_event_service_test.py
+++ /dev/null
@@ -1,46 +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.
-
-"""One of the tests of the Face layer of RPC Framework."""
-
-import unittest
-
-from grpc_test._adapter import _face_test_case
-from grpc_test.framework.face.testing import event_invocation_synchronous_event_service_test_case as test_case
-
-
-class EventInvocationSynchronousEventServiceTest(
- _face_test_case.FaceTestCase,
- test_case.EventInvocationSynchronousEventServiceTestCase,
- unittest.TestCase):
- pass
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/_adapter/_face_test_case.py b/src/python/grpcio_test/grpc_test/_adapter/_face_test_case.py
deleted file mode 100644
index dfbd0b60af..0000000000
--- a/src/python/grpcio_test/grpc_test/_adapter/_face_test_case.py
+++ /dev/null
@@ -1,106 +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.
-
-"""Common construction and destruction for GRPC-backed Face-layer tests."""
-
-import unittest
-
-from grpc._adapter import fore
-from grpc._adapter import rear
-from grpc.framework.base import util
-from grpc.framework.base import implementations as base_implementations
-from grpc.framework.face import implementations as face_implementations
-from grpc.framework.foundation import logging_pool
-from grpc_test.framework.face.testing import coverage
-from grpc_test.framework.face.testing import serial
-from grpc_test.framework.face.testing import test_case
-
-_TIMEOUT = 3
-_MAXIMUM_TIMEOUT = 90
-_MAXIMUM_POOL_SIZE = 4
-
-
-class FaceTestCase(test_case.FaceTestCase, coverage.BlockingCoverage):
- """Provides abstract Face-layer tests a GRPC-backed implementation."""
-
- def set_up_implementation(
- self, name, methods, method_implementations,
- multi_method_implementation):
- pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
-
- servicer = face_implementations.servicer(
- pool, method_implementations, multi_method_implementation)
-
- serialization = serial.serialization(methods)
-
- fore_link = fore.ForeLink(
- pool, serialization.request_deserializers,
- serialization.response_serializers, None, ())
- fore_link.start()
- port = fore_link.port()
- rear_link = rear.RearLink(
- 'localhost', port, pool,
- serialization.request_serializers,
- serialization.response_deserializers, False, None, None, None)
- rear_link.start()
- front = base_implementations.front_link(pool, pool, pool)
- back = base_implementations.back_link(
- servicer, pool, pool, pool, _TIMEOUT, _MAXIMUM_TIMEOUT)
- fore_link.join_rear_link(back)
- back.join_fore_link(fore_link)
- rear_link.join_fore_link(front)
- front.join_rear_link(rear_link)
-
- stub = face_implementations.generic_stub(front, pool)
- return stub, (rear_link, fore_link, front, back)
-
- def tear_down_implementation(self, memo):
- rear_link, fore_link, front, back = memo
- # TODO(nathaniel): Waiting for the front and back to idle possibly should
- # not be necessary - investigate as part of graceful shutdown work.
- util.wait_for_idle(front)
- util.wait_for_idle(back)
- rear_link.stop()
- fore_link.stop()
-
- @unittest.skip('Service-side failure not transmitted by GRPC.')
- def testFailedUnaryRequestUnaryResponse(self):
- raise NotImplementedError()
-
- @unittest.skip('Service-side failure not transmitted by GRPC.')
- def testFailedUnaryRequestStreamResponse(self):
- raise NotImplementedError()
-
- @unittest.skip('Service-side failure not transmitted by GRPC.')
- def testFailedStreamRequestUnaryResponse(self):
- raise NotImplementedError()
-
- @unittest.skip('Service-side failure not transmitted by GRPC.')
- def testFailedStreamRequestStreamResponse(self):
- raise NotImplementedError()
diff --git a/src/python/grpcio_test/grpc_test/_adapter/_future_invocation_asynchronous_event_service_test.py b/src/python/grpcio_test/grpc_test/_adapter/_future_invocation_asynchronous_event_service_test.py
deleted file mode 100644
index ea4a6a0bae..0000000000
--- a/src/python/grpcio_test/grpc_test/_adapter/_future_invocation_asynchronous_event_service_test.py
+++ /dev/null
@@ -1,46 +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.
-
-"""One of the tests of the Face layer of RPC Framework."""
-
-import unittest
-
-from grpc_test._adapter import _face_test_case
-from grpc_test.framework.face.testing import future_invocation_asynchronous_event_service_test_case as test_case
-
-
-class FutureInvocationAsynchronousEventServiceTest(
- _face_test_case.FaceTestCase,
- test_case.FutureInvocationAsynchronousEventServiceTestCase,
- unittest.TestCase):
- pass
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/_adapter/_links_test.py b/src/python/grpcio_test/grpc_test/_adapter/_links_test.py
deleted file mode 100644
index 4077b8e350..0000000000
--- a/src/python/grpcio_test/grpc_test/_adapter/_links_test.py
+++ /dev/null
@@ -1,277 +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.
-
-"""Test of the GRPC-backed ForeLink and RearLink."""
-
-import threading
-import unittest
-
-from grpc._adapter import fore
-from grpc._adapter import rear
-from grpc.framework.base import interfaces
-from grpc.framework.foundation import logging_pool
-from grpc_test._adapter import _proto_scenarios
-from grpc_test._adapter import _test_links
-
-_IDENTITY = lambda x: x
-_TIMEOUT = 32
-
-
-# TODO(nathaniel): End-to-end metadata testing.
-def _transform_metadata(unused_metadata):
- return (
- ('one_unused_key', 'one unused value'),
- ('another_unused_key', 'another unused value'),
-)
-
-
-class RoundTripTest(unittest.TestCase):
-
- def setUp(self):
- self.fore_link_pool = logging_pool.pool(8)
- self.rear_link_pool = logging_pool.pool(8)
-
- def tearDown(self):
- self.rear_link_pool.shutdown(wait=True)
- self.fore_link_pool.shutdown(wait=True)
-
- def testZeroMessageRoundTrip(self):
- test_operation_id = object()
- test_method = 'test method'
- test_fore_link = _test_links.ForeLink(None, None)
- def rear_action(front_to_back_ticket, fore_link):
- if front_to_back_ticket.kind in (
- interfaces.FrontToBackTicket.Kind.COMPLETION,
- interfaces.FrontToBackTicket.Kind.ENTIRE):
- back_to_front_ticket = interfaces.BackToFrontTicket(
- front_to_back_ticket.operation_id, 0,
- interfaces.BackToFrontTicket.Kind.COMPLETION, None)
- fore_link.accept_back_to_front_ticket(back_to_front_ticket)
- test_rear_link = _test_links.RearLink(rear_action, None)
-
- fore_link = fore.ForeLink(
- self.fore_link_pool, {test_method: None}, {test_method: None}, None, ())
- fore_link.join_rear_link(test_rear_link)
- test_rear_link.join_fore_link(fore_link)
- fore_link.start()
- port = fore_link.port()
-
- rear_link = rear.RearLink(
- 'localhost', port, self.rear_link_pool, {test_method: None},
- {test_method: None}, False, None, None, None,
- metadata_transformer=_transform_metadata)
- rear_link.join_fore_link(test_fore_link)
- test_fore_link.join_rear_link(rear_link)
- rear_link.start()
-
- front_to_back_ticket = interfaces.FrontToBackTicket(
- test_operation_id, 0, interfaces.FrontToBackTicket.Kind.ENTIRE,
- test_method, interfaces.ServicedSubscription.Kind.FULL, None, None,
- _TIMEOUT)
- rear_link.accept_front_to_back_ticket(front_to_back_ticket)
-
- with test_fore_link.condition:
- while (not test_fore_link.tickets or
- test_fore_link.tickets[-1].kind is
- interfaces.BackToFrontTicket.Kind.CONTINUATION):
- test_fore_link.condition.wait()
-
- rear_link.stop()
- fore_link.stop()
-
- with test_fore_link.condition:
- self.assertIs(
- test_fore_link.tickets[-1].kind,
- interfaces.BackToFrontTicket.Kind.COMPLETION)
-
- def testEntireRoundTrip(self):
- test_operation_id = object()
- test_method = 'test method'
- test_front_to_back_datum = b'\x07'
- test_back_to_front_datum = b'\x08'
- test_fore_link = _test_links.ForeLink(None, None)
- rear_sequence_number = [0]
- def rear_action(front_to_back_ticket, fore_link):
- if front_to_back_ticket.payload is None:
- payload = None
- else:
- payload = test_back_to_front_datum
- terminal = front_to_back_ticket.kind in (
- interfaces.FrontToBackTicket.Kind.COMPLETION,
- interfaces.FrontToBackTicket.Kind.ENTIRE)
- if payload is not None or terminal:
- if terminal:
- kind = interfaces.BackToFrontTicket.Kind.COMPLETION
- else:
- kind = interfaces.BackToFrontTicket.Kind.CONTINUATION
- back_to_front_ticket = interfaces.BackToFrontTicket(
- front_to_back_ticket.operation_id, rear_sequence_number[0], kind,
- payload)
- rear_sequence_number[0] += 1
- fore_link.accept_back_to_front_ticket(back_to_front_ticket)
- test_rear_link = _test_links.RearLink(rear_action, None)
-
- fore_link = fore.ForeLink(
- self.fore_link_pool, {test_method: _IDENTITY},
- {test_method: _IDENTITY}, None, ())
- fore_link.join_rear_link(test_rear_link)
- test_rear_link.join_fore_link(fore_link)
- fore_link.start()
- port = fore_link.port()
-
- rear_link = rear.RearLink(
- 'localhost', port, self.rear_link_pool, {test_method: _IDENTITY},
- {test_method: _IDENTITY}, False, None, None, None)
- rear_link.join_fore_link(test_fore_link)
- test_fore_link.join_rear_link(rear_link)
- rear_link.start()
-
- front_to_back_ticket = interfaces.FrontToBackTicket(
- test_operation_id, 0, interfaces.FrontToBackTicket.Kind.ENTIRE,
- test_method, interfaces.ServicedSubscription.Kind.FULL, None,
- test_front_to_back_datum, _TIMEOUT)
- rear_link.accept_front_to_back_ticket(front_to_back_ticket)
-
- with test_fore_link.condition:
- while (not test_fore_link.tickets or
- test_fore_link.tickets[-1].kind is not
- interfaces.BackToFrontTicket.Kind.COMPLETION):
- test_fore_link.condition.wait()
-
- rear_link.stop()
- fore_link.stop()
-
- with test_rear_link.condition:
- front_to_back_payloads = tuple(
- ticket.payload for ticket in test_rear_link.tickets
- if ticket.payload is not None)
- with test_fore_link.condition:
- back_to_front_payloads = tuple(
- ticket.payload for ticket in test_fore_link.tickets
- if ticket.payload is not None)
- self.assertTupleEqual((test_front_to_back_datum,), front_to_back_payloads)
- self.assertTupleEqual((test_back_to_front_datum,), back_to_front_payloads)
-
- def _perform_scenario_test(self, scenario):
- test_operation_id = object()
- test_method = scenario.method()
- test_fore_link = _test_links.ForeLink(None, None)
- rear_lock = threading.Lock()
- rear_sequence_number = [0]
- def rear_action(front_to_back_ticket, fore_link):
- with rear_lock:
- if front_to_back_ticket.payload is not None:
- response = scenario.response_for_request(front_to_back_ticket.payload)
- else:
- response = None
- terminal = front_to_back_ticket.kind in (
- interfaces.FrontToBackTicket.Kind.COMPLETION,
- interfaces.FrontToBackTicket.Kind.ENTIRE)
- if response is not None or terminal:
- if terminal:
- kind = interfaces.BackToFrontTicket.Kind.COMPLETION
- else:
- kind = interfaces.BackToFrontTicket.Kind.CONTINUATION
- back_to_front_ticket = interfaces.BackToFrontTicket(
- front_to_back_ticket.operation_id, rear_sequence_number[0], kind,
- response)
- rear_sequence_number[0] += 1
- fore_link.accept_back_to_front_ticket(back_to_front_ticket)
- test_rear_link = _test_links.RearLink(rear_action, None)
-
- fore_link = fore.ForeLink(
- self.fore_link_pool, {test_method: scenario.deserialize_request},
- {test_method: scenario.serialize_response}, None, ())
- fore_link.join_rear_link(test_rear_link)
- test_rear_link.join_fore_link(fore_link)
- fore_link.start()
- port = fore_link.port()
-
- rear_link = rear.RearLink(
- 'localhost', port, self.rear_link_pool,
- {test_method: scenario.serialize_request},
- {test_method: scenario.deserialize_response}, False, None, None, None)
- rear_link.join_fore_link(test_fore_link)
- test_fore_link.join_rear_link(rear_link)
- rear_link.start()
-
- commencement_ticket = interfaces.FrontToBackTicket(
- test_operation_id, 0,
- interfaces.FrontToBackTicket.Kind.COMMENCEMENT, test_method,
- interfaces.ServicedSubscription.Kind.FULL, None, None,
- _TIMEOUT)
- fore_sequence_number = 1
- rear_link.accept_front_to_back_ticket(commencement_ticket)
- for request in scenario.requests():
- continuation_ticket = interfaces.FrontToBackTicket(
- test_operation_id, fore_sequence_number,
- interfaces.FrontToBackTicket.Kind.CONTINUATION, None, None, None,
- request, None)
- fore_sequence_number += 1
- rear_link.accept_front_to_back_ticket(continuation_ticket)
- completion_ticket = interfaces.FrontToBackTicket(
- test_operation_id, fore_sequence_number,
- interfaces.FrontToBackTicket.Kind.COMPLETION, None, None, None, None,
- None)
- fore_sequence_number += 1
- rear_link.accept_front_to_back_ticket(completion_ticket)
-
- with test_fore_link.condition:
- while (not test_fore_link.tickets or
- test_fore_link.tickets[-1].kind is not
- interfaces.BackToFrontTicket.Kind.COMPLETION):
- test_fore_link.condition.wait()
-
- rear_link.stop()
- fore_link.stop()
-
- with test_rear_link.condition:
- requests = tuple(
- ticket.payload for ticket in test_rear_link.tickets
- if ticket.payload is not None)
- with test_fore_link.condition:
- responses = tuple(
- ticket.payload for ticket in test_fore_link.tickets
- if ticket.payload is not None)
- self.assertTrue(scenario.verify_requests(requests))
- self.assertTrue(scenario.verify_responses(responses))
-
- def testEmptyScenario(self):
- self._perform_scenario_test(_proto_scenarios.EmptyScenario())
-
- def testBidirectionallyUnaryScenario(self):
- self._perform_scenario_test(_proto_scenarios.BidirectionallyUnaryScenario())
-
- def testBidirectionallyStreamingScenario(self):
- self._perform_scenario_test(
- _proto_scenarios.BidirectionallyStreamingScenario())
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/_adapter/_lonely_rear_link_test.py b/src/python/grpcio_test/grpc_test/_adapter/_lonely_rear_link_test.py
deleted file mode 100644
index 9b5758f60f..0000000000
--- a/src/python/grpcio_test/grpc_test/_adapter/_lonely_rear_link_test.py
+++ /dev/null
@@ -1,100 +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.
-
-"""A test of invocation-side code unconnected to an RPC server."""
-
-import unittest
-
-from grpc._adapter import rear
-from grpc.framework.base import interfaces
-from grpc.framework.foundation import logging_pool
-from grpc_test._adapter import _test_links
-
-_IDENTITY = lambda x: x
-_TIMEOUT = 2
-
-
-class LonelyRearLinkTest(unittest.TestCase):
-
- def setUp(self):
- self.pool = logging_pool.pool(8)
-
- def tearDown(self):
- self.pool.shutdown(wait=True)
-
- def testUpAndDown(self):
- rear_link = rear.RearLink(
- 'nonexistent', 54321, self.pool, {}, {}, False, None, None, None)
-
- rear_link.start()
- rear_link.stop()
-
- def _perform_lonely_client_test_with_ticket_kind(
- self, front_to_back_ticket_kind):
- test_operation_id = object()
- test_method = 'test method'
- fore_link = _test_links.ForeLink(None, None)
-
- rear_link = rear.RearLink(
- 'nonexistent', 54321, self.pool, {test_method: None},
- {test_method: None}, False, None, None, None)
- rear_link.join_fore_link(fore_link)
- rear_link.start()
-
- front_to_back_ticket = interfaces.FrontToBackTicket(
- test_operation_id, 0, front_to_back_ticket_kind, test_method,
- interfaces.ServicedSubscription.Kind.FULL, None, None, _TIMEOUT)
- rear_link.accept_front_to_back_ticket(front_to_back_ticket)
-
- with fore_link.condition:
- while True:
- if (fore_link.tickets and
- fore_link.tickets[-1].kind is not
- interfaces.BackToFrontTicket.Kind.CONTINUATION):
- break
- fore_link.condition.wait()
-
- rear_link.stop()
-
- with fore_link.condition:
- self.assertIsNot(
- fore_link.tickets[-1].kind,
- interfaces.BackToFrontTicket.Kind.COMPLETION)
-
- def testLonelyClientCommencementTicket(self):
- self._perform_lonely_client_test_with_ticket_kind(
- interfaces.FrontToBackTicket.Kind.COMMENCEMENT)
-
- def testLonelyClientEntireTicket(self):
- self._perform_lonely_client_test_with_ticket_kind(
- interfaces.FrontToBackTicket.Kind.ENTIRE)
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/_adapter/_test_links.py b/src/python/grpcio_test/grpc_test/_adapter/_test_links.py
deleted file mode 100644
index 86c7e61b17..0000000000
--- a/src/python/grpcio_test/grpc_test/_adapter/_test_links.py
+++ /dev/null
@@ -1,80 +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.
-
-"""Links suitable for use in tests."""
-
-import threading
-
-from grpc.framework.base import interfaces
-
-
-class ForeLink(interfaces.ForeLink):
- """A ForeLink suitable for use in tests of RearLinks."""
-
- def __init__(self, action, rear_link):
- self.condition = threading.Condition()
- self.tickets = []
- self.action = action
- self.rear_link = rear_link
-
- def accept_back_to_front_ticket(self, ticket):
- with self.condition:
- self.tickets.append(ticket)
- self.condition.notify_all()
- action, rear_link = self.action, self.rear_link
-
- if action is not None:
- action(ticket, rear_link)
-
- def join_rear_link(self, rear_link):
- with self.condition:
- self.rear_link = rear_link
-
-
-class RearLink(interfaces.RearLink):
- """A RearLink suitable for use in tests of ForeLinks."""
-
- def __init__(self, action, fore_link):
- self.condition = threading.Condition()
- self.tickets = []
- self.action = action
- self.fore_link = fore_link
-
- def accept_front_to_back_ticket(self, ticket):
- with self.condition:
- self.tickets.append(ticket)
- self.condition.notify_all()
- action, fore_link = self.action, self.fore_link
-
- if action is not None:
- action(ticket, fore_link)
-
- def join_fore_link(self, fore_link):
- with self.condition:
- self.fore_link = fore_link
diff --git a/src/python/grpcio_test/grpc_test/early_adopter/implementations_test.py b/src/python/grpcio_test/grpc_test/early_adopter/implementations_test.py
deleted file mode 100644
index 611637e8b8..0000000000
--- a/src/python/grpcio_test/grpc_test/early_adopter/implementations_test.py
+++ /dev/null
@@ -1,180 +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.
-
-# TODO(nathaniel): Expand this test coverage.
-
-"""Test of the GRPC-backed ForeLink and RearLink."""
-
-import unittest
-
-from grpc.early_adopter import implementations
-from grpc.framework.alpha import utilities
-from grpc_test._junkdrawer import math_pb2
-
-SERVICE_NAME = 'math.Math'
-
-DIV = 'Div'
-DIV_MANY = 'DivMany'
-FIB = 'Fib'
-SUM = 'Sum'
-
-def _fibbonacci(limit):
- left, right = 0, 1
- for _ in xrange(limit):
- yield left
- left, right = right, left + right
-
-
-def _div(request, unused_context):
- return math_pb2.DivReply(
- quotient=request.dividend / request.divisor,
- remainder=request.dividend % request.divisor)
-
-
-def _div_many(request_iterator, unused_context):
- for request in request_iterator:
- yield math_pb2.DivReply(
- quotient=request.dividend / request.divisor,
- remainder=request.dividend % request.divisor)
-
-
-def _fib(request, unused_context):
- for number in _fibbonacci(request.limit):
- yield math_pb2.Num(num=number)
-
-
-def _sum(request_iterator, unused_context):
- accumulation = 0
- for request in request_iterator:
- accumulation += request.num
- return math_pb2.Num(num=accumulation)
-
-
-_INVOCATION_DESCRIPTIONS = {
- DIV: utilities.unary_unary_invocation_description(
- math_pb2.DivArgs.SerializeToString, math_pb2.DivReply.FromString),
- DIV_MANY: utilities.stream_stream_invocation_description(
- math_pb2.DivArgs.SerializeToString, math_pb2.DivReply.FromString),
- FIB: utilities.unary_stream_invocation_description(
- math_pb2.FibArgs.SerializeToString, math_pb2.Num.FromString),
- SUM: utilities.stream_unary_invocation_description(
- math_pb2.Num.SerializeToString, math_pb2.Num.FromString),
-}
-
-_SERVICE_DESCRIPTIONS = {
- DIV: utilities.unary_unary_service_description(
- _div, math_pb2.DivArgs.FromString,
- math_pb2.DivReply.SerializeToString),
- DIV_MANY: utilities.stream_stream_service_description(
- _div_many, math_pb2.DivArgs.FromString,
- math_pb2.DivReply.SerializeToString),
- FIB: utilities.unary_stream_service_description(
- _fib, math_pb2.FibArgs.FromString, math_pb2.Num.SerializeToString),
- SUM: utilities.stream_unary_service_description(
- _sum, math_pb2.Num.FromString, math_pb2.Num.SerializeToString),
-}
-
-_TIMEOUT = 3
-
-
-class EarlyAdopterImplementationsTest(unittest.TestCase):
-
- def setUp(self):
- self.server = implementations.server(
- SERVICE_NAME, _SERVICE_DESCRIPTIONS, 0)
- self.server.start()
- port = self.server.port()
- self.stub = implementations.stub(
- SERVICE_NAME, _INVOCATION_DESCRIPTIONS, 'localhost', port)
-
- def tearDown(self):
- self.server.stop()
-
- def testUpAndDown(self):
- with self.stub:
- pass
-
- def testUnaryUnary(self):
- divisor = 59
- dividend = 973
- expected_quotient = dividend / divisor
- expected_remainder = dividend % divisor
-
- with self.stub:
- response = self.stub.Div(
- math_pb2.DivArgs(divisor=divisor, dividend=dividend), _TIMEOUT)
- self.assertEqual(expected_quotient, response.quotient)
- self.assertEqual(expected_remainder, response.remainder)
-
- def testUnaryStream(self):
- stream_length = 43
-
- with self.stub:
- response_iterator = self.stub.Fib(
- math_pb2.FibArgs(limit=stream_length), _TIMEOUT)
- numbers = tuple(response.num for response in response_iterator)
- for early, middle, later in zip(numbers, numbers[:1], numbers[:2]):
- self.assertEqual(early + middle, later)
- self.assertEqual(stream_length, len(numbers))
-
- def testStreamUnary(self):
- stream_length = 127
-
- with self.stub:
- response_future = self.stub.Sum.async(
- (math_pb2.Num(num=index) for index in range(stream_length)),
- _TIMEOUT)
- self.assertEqual(
- (stream_length * (stream_length - 1)) / 2,
- response_future.result().num)
-
- def testStreamStream(self):
- stream_length = 179
- divisor_offset = 71
- dividend_offset = 1763
-
- with self.stub:
- response_iterator = self.stub.DivMany(
- (math_pb2.DivArgs(
- divisor=divisor_offset + index,
- dividend=dividend_offset + index)
- for index in range(stream_length)),
- _TIMEOUT)
- for index, response in enumerate(response_iterator):
- self.assertEqual(
- (dividend_offset + index) / (divisor_offset + index),
- response.quotient)
- self.assertEqual(
- (dividend_offset + index) % (divisor_offset + index),
- response.remainder)
- self.assertEqual(stream_length, index + 1)
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/framework/base/implementations_test.py b/src/python/grpcio_test/grpc_test/framework/base/implementations_test.py
deleted file mode 100644
index 5a7d1398fd..0000000000
--- a/src/python/grpcio_test/grpc_test/framework/base/implementations_test.py
+++ /dev/null
@@ -1,80 +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.
-
-"""Tests for grpc.framework.base.implementations."""
-
-import unittest
-
-from grpc.framework.base import implementations
-from grpc.framework.base import util
-from grpc.framework.foundation import logging_pool
-from grpc_test.framework.base import interfaces_test_case
-
-POOL_MAX_WORKERS = 10
-DEFAULT_TIMEOUT = 30
-MAXIMUM_TIMEOUT = 60
-
-
-class ImplementationsTest(
- interfaces_test_case.FrontAndBackTest, unittest.TestCase):
-
- def setUp(self):
- self.memory_transmission_pool = logging_pool.pool(POOL_MAX_WORKERS)
- self.front_work_pool = logging_pool.pool(POOL_MAX_WORKERS)
- self.front_transmission_pool = logging_pool.pool(POOL_MAX_WORKERS)
- self.front_utility_pool = logging_pool.pool(POOL_MAX_WORKERS)
- self.back_work_pool = logging_pool.pool(POOL_MAX_WORKERS)
- self.back_transmission_pool = logging_pool.pool(POOL_MAX_WORKERS)
- self.back_utility_pool = logging_pool.pool(POOL_MAX_WORKERS)
- self.test_pool = logging_pool.pool(POOL_MAX_WORKERS)
- self.test_servicer = interfaces_test_case.TestServicer(self.test_pool)
- self.front = implementations.front_link(
- self.front_work_pool, self.front_transmission_pool,
- self.front_utility_pool)
- self.back = implementations.back_link(
- self.test_servicer, self.back_work_pool, self.back_transmission_pool,
- self.back_utility_pool, DEFAULT_TIMEOUT, MAXIMUM_TIMEOUT)
- self.front.join_rear_link(self.back)
- self.back.join_fore_link(self.front)
-
- def tearDown(self):
- util.wait_for_idle(self.back)
- util.wait_for_idle(self.front)
- self.memory_transmission_pool.shutdown(wait=True)
- self.front_work_pool.shutdown(wait=True)
- self.front_transmission_pool.shutdown(wait=True)
- self.front_utility_pool.shutdown(wait=True)
- self.back_work_pool.shutdown(wait=True)
- self.back_transmission_pool.shutdown(wait=True)
- self.back_utility_pool.shutdown(wait=True)
- self.test_pool.shutdown(wait=True)
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/framework/base/interfaces_test_case.py b/src/python/grpcio_test/grpc_test/framework/base/interfaces_test_case.py
deleted file mode 100644
index be775ad4e0..0000000000
--- a/src/python/grpcio_test/grpc_test/framework/base/interfaces_test_case.py
+++ /dev/null
@@ -1,307 +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.
-
-"""Abstract tests against the interfaces of the base layer of RPC Framework."""
-
-import threading
-import time
-
-from grpc.framework.base import interfaces
-from grpc.framework.base import util
-from grpc.framework.foundation import stream
-from grpc.framework.foundation import stream_util
-from grpc_test.framework.foundation import stream_testing
-
-TICK = 0.1
-SMALL_TIMEOUT = TICK * 50
-STREAM_LENGTH = 100
-
-SYNCHRONOUS_ECHO = 'synchronous echo'
-ASYNCHRONOUS_ECHO = 'asynchronous echo'
-IMMEDIATE_FAILURE = 'immediate failure'
-TRIGGERED_FAILURE = 'triggered failure'
-WAIT_ON_CONDITION = 'wait on condition'
-
-EMPTY_OUTCOME_DICT = {
- interfaces.Outcome.COMPLETED: 0,
- interfaces.Outcome.CANCELLED: 0,
- interfaces.Outcome.EXPIRED: 0,
- interfaces.Outcome.RECEPTION_FAILURE: 0,
- interfaces.Outcome.TRANSMISSION_FAILURE: 0,
- interfaces.Outcome.SERVICER_FAILURE: 0,
- interfaces.Outcome.SERVICED_FAILURE: 0,
- }
-
-
-def _synchronous_echo(output_consumer):
- return stream_util.TransformingConsumer(lambda x: x, output_consumer)
-
-
-class AsynchronousEcho(stream.Consumer):
- """A stream.Consumer that echoes its input to another stream.Consumer."""
-
- def __init__(self, output_consumer, pool):
- self._lock = threading.Lock()
- self._output_consumer = output_consumer
- self._pool = pool
-
- self._queue = []
- self._spinning = False
-
- def _spin(self, value, complete):
- while True:
- if value:
- if complete:
- self._output_consumer.consume_and_terminate(value)
- else:
- self._output_consumer.consume(value)
- elif complete:
- self._output_consumer.terminate()
- with self._lock:
- if self._queue:
- value, complete = self._queue.pop(0)
- else:
- self._spinning = False
- return
-
- def consume(self, value):
- with self._lock:
- if self._spinning:
- self._queue.append((value, False))
- else:
- self._spinning = True
- self._pool.submit(self._spin, value, False)
-
- def terminate(self):
- with self._lock:
- if self._spinning:
- self._queue.append((None, True))
- else:
- self._spinning = True
- self._pool.submit(self._spin, None, True)
-
- def consume_and_terminate(self, value):
- with self._lock:
- if self._spinning:
- self._queue.append((value, True))
- else:
- self._spinning = True
- self._pool.submit(self._spin, value, True)
-
-
-class TestServicer(interfaces.Servicer):
- """An interfaces.Servicer with instrumented for testing."""
-
- def __init__(self, pool):
- self._pool = pool
- self.condition = threading.Condition()
- self._released = False
-
- def service(self, name, context, output_consumer):
- if name == SYNCHRONOUS_ECHO:
- return _synchronous_echo(output_consumer)
- elif name == ASYNCHRONOUS_ECHO:
- return AsynchronousEcho(output_consumer, self._pool)
- elif name == IMMEDIATE_FAILURE:
- raise ValueError()
- elif name == TRIGGERED_FAILURE:
- raise NotImplementedError
- elif name == WAIT_ON_CONDITION:
- with self.condition:
- while not self._released:
- self.condition.wait()
- return _synchronous_echo(output_consumer)
- else:
- raise NotImplementedError()
-
- def release(self):
- with self.condition:
- self._released = True
- self.condition.notify_all()
-
-
-class EasyServicedIngestor(interfaces.ServicedIngestor):
- """A trivial implementation of interfaces.ServicedIngestor."""
-
- def __init__(self, consumer):
- self._consumer = consumer
-
- def consumer(self, operation_context):
- """See interfaces.ServicedIngestor.consumer for specification."""
- return self._consumer
-
-
-class FrontAndBackTest(object):
- """A test suite usable against any joined Front and Back."""
-
- # Pylint doesn't know that this is a unittest.TestCase mix-in.
- # pylint: disable=invalid-name
-
- def testSimplestCall(self):
- """Tests the absolute simplest call - a one-ticket fire-and-forget."""
- self.front.operate(
- SYNCHRONOUS_ECHO, None, True, SMALL_TIMEOUT,
- util.none_serviced_subscription(), 'test trace ID')
- util.wait_for_idle(self.front)
- self.assertEqual(
- 1, self.front.operation_stats()[interfaces.Outcome.COMPLETED])
-
- # Assuming nothing really pathological (such as pauses on the order of
- # SMALL_TIMEOUT interfering with this test) there are a two different ways
- # the back could have experienced execution up to this point:
- # (1) The ticket is still either in the front waiting to be transmitted
- # or is somewhere on the link between the front and the back. The back has
- # no idea that this test is even happening. Calling wait_for_idle on it
- # would do no good because in this case the back is idle and the call would
- # return with the ticket bound for it still in the front or on the link.
- back_operation_stats = self.back.operation_stats()
- first_back_possibility = EMPTY_OUTCOME_DICT
- # (2) The ticket arrived at the back and the back completed the operation.
- second_back_possibility = dict(EMPTY_OUTCOME_DICT)
- second_back_possibility[interfaces.Outcome.COMPLETED] = 1
- self.assertIn(
- back_operation_stats, (first_back_possibility, second_back_possibility))
- # It's true that if the ticket had arrived at the back and the back had
- # begun processing that wait_for_idle could hold test execution until the
- # back completed the operation, but that doesn't really collapse the
- # possibility space down to one solution.
-
- def testEntireEcho(self):
- """Tests a very simple one-ticket-each-way round-trip."""
- test_payload = 'test payload'
- test_consumer = stream_testing.TestConsumer()
- subscription = util.full_serviced_subscription(
- EasyServicedIngestor(test_consumer))
-
- self.front.operate(
- ASYNCHRONOUS_ECHO, test_payload, True, SMALL_TIMEOUT, subscription,
- 'test trace ID')
-
- util.wait_for_idle(self.front)
- util.wait_for_idle(self.back)
- self.assertEqual(
- 1, self.front.operation_stats()[interfaces.Outcome.COMPLETED])
- self.assertEqual(
- 1, self.back.operation_stats()[interfaces.Outcome.COMPLETED])
- self.assertListEqual([(test_payload, True)], test_consumer.calls)
-
- def testBidirectionalStreamingEcho(self):
- """Tests sending multiple tickets each way."""
- test_payload_template = 'test_payload: %03d'
- test_payloads = [test_payload_template % i for i in range(STREAM_LENGTH)]
- test_consumer = stream_testing.TestConsumer()
- subscription = util.full_serviced_subscription(
- EasyServicedIngestor(test_consumer))
-
- operation = self.front.operate(
- SYNCHRONOUS_ECHO, None, False, SMALL_TIMEOUT, subscription,
- 'test trace ID')
-
- for test_payload in test_payloads:
- operation.consumer.consume(test_payload)
- operation.consumer.terminate()
-
- util.wait_for_idle(self.front)
- util.wait_for_idle(self.back)
- self.assertEqual(
- 1, self.front.operation_stats()[interfaces.Outcome.COMPLETED])
- self.assertEqual(
- 1, self.back.operation_stats()[interfaces.Outcome.COMPLETED])
- self.assertListEqual(test_payloads, test_consumer.values())
-
- def testCancellation(self):
- """Tests cancelling a long-lived operation."""
- test_consumer = stream_testing.TestConsumer()
- subscription = util.full_serviced_subscription(
- EasyServicedIngestor(test_consumer))
-
- operation = self.front.operate(
- ASYNCHRONOUS_ECHO, None, False, SMALL_TIMEOUT, subscription,
- 'test trace ID')
- operation.cancel()
-
- util.wait_for_idle(self.front)
- self.assertEqual(
- 1, self.front.operation_stats()[interfaces.Outcome.CANCELLED])
- util.wait_for_idle(self.back)
- self.assertListEqual([], test_consumer.calls)
-
- # Assuming nothing really pathological (such as pauses on the order of
- # SMALL_TIMEOUT interfering with this test) there are a two different ways
- # the back could have experienced execution up to this point:
- # (1) Both tickets are still either in the front waiting to be transmitted
- # or are somewhere on the link between the front and the back. The back has
- # no idea that this test is even happening. Calling wait_for_idle on it
- # would do no good because in this case the back is idle and the call would
- # return with the tickets bound for it still in the front or on the link.
- back_operation_stats = self.back.operation_stats()
- first_back_possibility = EMPTY_OUTCOME_DICT
- # (2) Both tickets arrived within SMALL_TIMEOUT of one another at the back.
- # The back started processing based on the first ticket and then stopped
- # upon receiving the cancellation ticket.
- second_back_possibility = dict(EMPTY_OUTCOME_DICT)
- second_back_possibility[interfaces.Outcome.CANCELLED] = 1
- self.assertIn(
- back_operation_stats, (first_back_possibility, second_back_possibility))
-
- def testExpiration(self):
- """Tests that operations time out."""
- timeout = TICK * 2
- allowance = TICK # How much extra time to
- condition = threading.Condition()
- test_payload = 'test payload'
- subscription = util.termination_only_serviced_subscription()
- start_time = time.time()
-
- outcome_cell = [None]
- termination_time_cell = [None]
- def termination_action(outcome):
- with condition:
- outcome_cell[0] = outcome
- termination_time_cell[0] = time.time()
- condition.notify()
-
- with condition:
- operation = self.front.operate(
- SYNCHRONOUS_ECHO, test_payload, False, timeout, subscription,
- 'test trace ID')
- operation.context.add_termination_callback(termination_action)
- while outcome_cell[0] is None:
- condition.wait()
-
- duration = termination_time_cell[0] - start_time
- self.assertLessEqual(timeout, duration)
- self.assertLess(duration, timeout + allowance)
- self.assertEqual(interfaces.Outcome.EXPIRED, outcome_cell[0])
- util.wait_for_idle(self.front)
- self.assertEqual(
- 1, self.front.operation_stats()[interfaces.Outcome.EXPIRED])
- util.wait_for_idle(self.back)
- self.assertLessEqual(
- 1, self.back.operation_stats()[interfaces.Outcome.EXPIRED])
diff --git a/src/python/grpcio_test/grpc_test/framework/face/_test_case.py b/src/python/grpcio_test/grpc_test/framework/face/_test_case.py
deleted file mode 100644
index 486b6e630e..0000000000
--- a/src/python/grpcio_test/grpc_test/framework/face/_test_case.py
+++ /dev/null
@@ -1,61 +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.
-
-"""Common lifecycle code for in-memory-ticket-exchange Face-layer tests."""
-
-from grpc.framework.face import implementations
-from grpc.framework.foundation import logging_pool
-from grpc_test.framework.face.testing import base_util
-from grpc_test.framework.face.testing import test_case
-
-_TIMEOUT = 3
-_MAXIMUM_POOL_SIZE = 10
-
-
-class FaceTestCase(test_case.FaceTestCase):
- """Provides abstract Face-layer tests an in-memory implementation."""
-
- def set_up_implementation(
- self, name, methods, method_implementations,
- multi_method_implementation):
- servicer_pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
- stub_pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
-
- servicer = implementations.servicer(
- servicer_pool, method_implementations, multi_method_implementation)
-
- linked_pair = base_util.linked_pair(servicer, _TIMEOUT)
- stub = implementations.generic_stub(linked_pair.front, stub_pool)
- return stub, (servicer_pool, stub_pool, linked_pair)
-
- def tear_down_implementation(self, memo):
- servicer_pool, stub_pool, linked_pair = memo
- linked_pair.shut_down()
- stub_pool.shutdown(wait=True)
- servicer_pool.shutdown(wait=True)
diff --git a/src/python/grpcio_test/grpc_test/framework/face/blocking_invocation_inline_service_test.py b/src/python/grpcio_test/grpc_test/framework/face/blocking_invocation_inline_service_test.py
deleted file mode 100644
index 8674666418..0000000000
--- a/src/python/grpcio_test/grpc_test/framework/face/blocking_invocation_inline_service_test.py
+++ /dev/null
@@ -1,46 +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.
-
-"""One of the tests of the Face layer of RPC Framework."""
-
-import unittest
-
-from grpc_test.framework.face import _test_case
-from grpc_test.framework.face.testing import blocking_invocation_inline_service_test_case as test_case
-
-
-class BlockingInvocationInlineServiceTest(
- _test_case.FaceTestCase,
- test_case.BlockingInvocationInlineServiceTestCase,
- unittest.TestCase):
- pass
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/framework/face/event_invocation_synchronous_event_service_test.py b/src/python/grpcio_test/grpc_test/framework/face/event_invocation_synchronous_event_service_test.py
deleted file mode 100644
index dca373ef7c..0000000000
--- a/src/python/grpcio_test/grpc_test/framework/face/event_invocation_synchronous_event_service_test.py
+++ /dev/null
@@ -1,46 +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.
-
-"""One of the tests of the Face layer of RPC Framework."""
-
-import unittest
-
-from grpc_test.framework.face import _test_case
-from grpc_test.framework.face.testing import event_invocation_synchronous_event_service_test_case as test_case
-
-
-class EventInvocationSynchronousEventServiceTest(
- _test_case.FaceTestCase,
- test_case.EventInvocationSynchronousEventServiceTestCase,
- unittest.TestCase):
- pass
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/framework/face/future_invocation_asynchronous_event_service_test.py b/src/python/grpcio_test/grpc_test/framework/face/future_invocation_asynchronous_event_service_test.py
deleted file mode 100644
index 99fdf18123..0000000000
--- a/src/python/grpcio_test/grpc_test/framework/face/future_invocation_asynchronous_event_service_test.py
+++ /dev/null
@@ -1,46 +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.
-
-"""One of the tests of the Face layer of RPC Framework."""
-
-import unittest
-
-from grpc_test.framework.face import _test_case
-from grpc_test.framework.face.testing import future_invocation_asynchronous_event_service_test_case as test_case
-
-
-class FutureInvocationAsynchronousEventServiceTest(
- _test_case.FaceTestCase,
- test_case.FutureInvocationAsynchronousEventServiceTestCase,
- unittest.TestCase):
- pass
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/framework/face/testing/serial.py b/src/python/grpcio_test/grpc_test/framework/face/testing/serial.py
deleted file mode 100644
index 47fc5822de..0000000000
--- a/src/python/grpcio_test/grpc_test/framework/face/testing/serial.py
+++ /dev/null
@@ -1,70 +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.
-
-"""Utility for serialization in the context of test RPC services."""
-
-import collections
-
-
-class Serialization(
- collections.namedtuple(
- '_Serialization',
- ['request_serializers',
- 'request_deserializers',
- 'response_serializers',
- 'response_deserializers'])):
- """An aggregation of serialization behaviors for an RPC service.
-
- Attributes:
- request_serializers: A dict from method name to request object serializer
- behavior.
- request_deserializers: A dict from method name to request object
- deserializer behavior.
- response_serializers: A dict from method name to response object serializer
- behavior.
- response_deserializers: A dict from method name to response object
- deserializer behavior.
- """
-
-
-def serialization(methods):
- """Creates a Serialization from a sequences of interfaces.Method objects."""
- request_serializers = {}
- request_deserializers = {}
- response_serializers = {}
- response_deserializers = {}
- for method in methods:
- name = method.name()
- request_serializers[name] = method.serialize_request
- request_deserializers[name] = method.deserialize_request
- response_serializers[name] = method.serialize_response
- response_deserializers[name] = method.deserialize_response
- return Serialization(
- request_serializers, request_deserializers, response_serializers,
- response_deserializers)
diff --git a/src/python/grpcio_test/setup.py b/src/python/grpcio_test/setup.py
index 0f43b4a638..e9ee45a92a 100644
--- a/src/python/grpcio_test/setup.py
+++ b/src/python/grpcio_test/setup.py
@@ -77,7 +77,9 @@ _INSTALL_REQUIRES = (
)
_COMMAND_CLASS = {
- 'test': commands.RunTests
+ 'test': commands.RunTests,
+ 'build_proto_modules': commands.BuildProtoModules,
+ 'build_py': commands.BuildPy,
}
setuptools.setup(
diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb
index e6d5223272..1388685734 100755
--- a/src/ruby/pb/test/client.rb
+++ b/src/ruby/pb/test/client.rb
@@ -255,6 +255,12 @@ class NamedTests
def per_rpc_creds
auth_creds = Google::Auth.get_application_default(@args.oauth_scope)
kw = auth_creds.updater_proc.call({})
+
+ # TODO(jtattermusch): downcase the metadata keys here to make sure
+ # they are not rejected by C core. This is a hotfix that should
+ # be addressed by introducing auto-downcasing logic.
+ kw = Hash[ kw.each_pair.map { |k, v| [k.downcase, v] }]
+
resp = perform_large_unary(fill_username: true,
fill_oauth_scope: true,
**kw)