aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar vjpai <vpai@google.com>2015-12-22 10:40:16 -0800
committerGravatar vjpai <vpai@google.com>2015-12-22 10:40:16 -0800
commitbe75ffd028ae4d7224883d0fa96bbd188d180305 (patch)
treed200cc25eb4264aaf531d80e69a281540a246d64 /test
parent594f0c43e0cceea10ca897759aa2912b7fa9e37f (diff)
parentd491897c4050bce09025d8ad0011d38c14ab0dad (diff)
Merge branch 'master' into bbuf
Diffstat (limited to 'test')
-rw-r--r--test/core/bad_client/bad_client.c17
-rw-r--r--test/core/bad_client/bad_client.h8
-rwxr-xr-xtest/core/bad_client/gen_build_yaml.py6
-rw-r--r--test/core/bad_client/tests/bad_timeout.headers2
-rw-r--r--test/core/bad_client/tests/badreq.c140
-rw-r--r--test/core/bad_client/tests/badreq_2path.headers13
-rw-r--r--test/core/bad_client/tests/badreq_algorithm.headers11
-rw-r--r--test/core/bad_client/tests/badreq_content_type.headers11
-rw-r--r--test/core/bad_client/tests/badreq_encoding.headers12
-rw-r--r--test/core/bad_client/tests/badreq_te.headers11
-rw-r--r--test/core/bad_client/tests/connection_prefix.c3
-rw-r--r--test/core/bad_client/tests/headers.c306
-rw-r--r--test/core/bad_client/tests/initial_settings_frame.c28
-rw-r--r--test/core/bad_client/tests/server_registered_method.c155
-rw-r--r--test/core/bad_client/tests/server_registered_method.headers12
-rw-r--r--test/core/bad_client/tests/simple_request.c159
-rw-r--r--test/core/bad_client/tests/simple_request.headers12
-rw-r--r--test/core/bad_client/tests/simple_request_unusual.headers13
-rw-r--r--test/core/bad_client/tests/unknown_frame.c59
-rw-r--r--test/core/bad_client/tests/window_overflow.c106
-rw-r--r--test/core/bad_ssl/bad_ssl_test.c171
-rwxr-xr-xtest/core/bad_ssl/gen_build_yaml.py104
-rw-r--r--test/core/bad_ssl/server.c113
-rw-r--r--test/core/bad_ssl/server.h42
-rw-r--r--test/core/bad_ssl/servers/alpn.c86
-rw-r--r--test/core/bad_ssl/servers/cert.c79
-rw-r--r--test/core/channel/channel_stack_test.c32
-rw-r--r--test/core/client_config/lb_policies_test.c216
-rw-r--r--test/core/client_config/resolvers/dns_resolver_test.c106
-rw-r--r--test/core/client_config/resolvers/sockaddr_resolver_test.c116
-rw-r--r--test/core/client_config/set_initial_connect_string_test.c8
-rw-r--r--test/core/compression/algorithm_test.c104
-rw-r--r--test/core/compression/compression_test.c78
-rw-r--r--test/core/compression/message_compress_test.c129
-rw-r--r--test/core/end2end/fixtures/h2_census.c132
-rw-r--r--test/core/end2end/fixtures/h2_full+pipe.c120
-rw-r--r--test/core/end2end/fixtures/h2_full+poll+pipe.c120
-rw-r--r--test/core/end2end/fixtures/h2_sockpair+trace.c27
-rw-r--r--test/core/end2end/fixtures/h2_sockpair.c27
-rw-r--r--test/core/end2end/fixtures/h2_sockpair_1byte.c27
-rw-r--r--test/core/end2end/fixtures/h2_uchannel.c85
-rwxr-xr-xtest/core/end2end/gen_build_yaml.py118
-rw-r--r--test/core/end2end/invalid_call_argument_test.c557
-rw-r--r--test/core/end2end/tests/binary_metadata.c2
-rw-r--r--test/core/end2end/tests/cancel_after_accept.c2
-rw-r--r--test/core/end2end/tests/cancel_after_client_done.c2
-rw-r--r--test/core/end2end/tests/cancel_after_invoke.c2
-rw-r--r--test/core/end2end/tests/cancel_before_invoke.c2
-rw-r--r--test/core/end2end/tests/cancel_in_a_vacuum.c2
-rw-r--r--test/core/end2end/tests/cancel_with_status.c2
-rw-r--r--test/core/end2end/tests/census_simple_request.c232
-rw-r--r--test/core/end2end/tests/channel_connectivity.c2
-rw-r--r--test/core/end2end/tests/channel_ping.c97
-rw-r--r--test/core/end2end/tests/compressed_payload.c2
-rw-r--r--test/core/end2end/tests/empty_batch.c2
-rw-r--r--test/core/end2end/tests/graceful_server_shutdown.c2
-rw-r--r--test/core/end2end/tests/high_initial_seqno.c12
-rw-r--r--test/core/end2end/tests/hpack_size.c8
-rw-r--r--test/core/end2end/tests/invoke_large_request.c2
-rw-r--r--test/core/end2end/tests/large_metadata.c2
-rw-r--r--test/core/end2end/tests/max_concurrent_streams.c2
-rw-r--r--test/core/end2end/tests/max_message_length.c2
-rw-r--r--test/core/end2end/tests/metadata.c2
-rw-r--r--test/core/end2end/tests/negative_deadline.c2
-rw-r--r--test/core/end2end/tests/no_op.c2
-rw-r--r--test/core/end2end/tests/payload.c2
-rw-r--r--test/core/end2end/tests/ping_pong_streaming.c2
-rw-r--r--test/core/end2end/tests/registered_call.c2
-rw-r--r--test/core/end2end/tests/request_with_flags.c2
-rw-r--r--test/core/end2end/tests/request_with_payload.c2
-rw-r--r--test/core/end2end/tests/server_finishes_request.c2
-rw-r--r--test/core/end2end/tests/shutdown_finishes_calls.c2
-rw-r--r--test/core/end2end/tests/shutdown_finishes_tags.c2
-rw-r--r--test/core/end2end/tests/simple_request.c2
-rw-r--r--test/core/end2end/tests/trailing_metadata.c2
-rw-r--r--test/core/fling/server.c2
-rw-r--r--test/core/httpcli/httpcli_test.c37
-rw-r--r--test/core/httpcli/httpscli_test.c195
-rw-r--r--test/core/httpcli/parser_test.c16
-rwxr-xr-xtest/core/httpcli/test_server.py14
-rw-r--r--test/core/iomgr/fd_posix_test.c8
-rw-r--r--test/core/iomgr/sockaddr_utils_test.c24
-rw-r--r--test/core/iomgr/socket_utils_test.c62
-rw-r--r--test/core/iomgr/tcp_client_posix_test.c5
-rw-r--r--test/core/iomgr/tcp_posix_test.c72
-rw-r--r--test/core/iomgr/udp_server_test.c8
-rw-r--r--test/core/iomgr/workqueue_test.c36
-rw-r--r--test/core/json/json_stream_error_test.c74
-rw-r--r--test/core/json/json_test.c22
-rw-r--r--test/core/security/credentials_test.c211
-rw-r--r--test/core/security/oauth2_utils.c5
-rw-r--r--test/core/security/print_google_default_creds_token.c5
-rw-r--r--test/core/security/security_connector_test.c57
-rw-r--r--test/core/support/alloc_test.c68
-rw-r--r--test/core/support/cmdline_test.c187
-rw-r--r--test/core/support/slice_buffer_test.c58
-rw-r--r--test/core/support/slice_test.c17
-rw-r--r--test/core/support/string_test.c50
-rw-r--r--test/core/support/sync_test.c56
-rw-r--r--test/core/support/thd_test.c14
-rw-r--r--test/core/support/time_test.c4
-rw-r--r--test/core/surface/byte_buffer_reader_test.c37
-rw-r--r--test/core/surface/channel_create_test.c55
-rw-r--r--test/core/surface/completion_queue_test.c81
-rw-r--r--test/core/surface/init_test.c78
-rw-r--r--test/core/surface/invalid_channel_args_test.c186
-rw-r--r--test/core/surface/lame_client_test.c75
-rw-r--r--test/core/surface/secure_channel_create_test.c95
-rw-r--r--test/core/surface/server_chttp2_test.c (renamed from test/core/surface/multi_init_test.c)28
-rw-r--r--test/core/surface/server_test.c93
-rw-r--r--test/core/transport/chttp2/hpack_encoder_test.c11
-rw-r--r--test/core/transport/chttp2/hpack_parser_test.c15
-rw-r--r--test/core/transport/chttp2/hpack_table_test.c33
-rw-r--r--test/core/transport/chttp2/varint_test.c69
-rw-r--r--test/core/transport/connectivity_state_test.c154
-rw-r--r--test/core/transport/metadata_test.c125
-rw-r--r--test/core/tsi/transport_security_test.c63
-rw-r--r--test/core/util/test_config.c4
-rw-r--r--test/cpp/common/channel_arguments_test.cc (renamed from test/cpp/client/channel_arguments_test.cc)16
-rw-r--r--test/cpp/end2end/async_end2end_test.cc11
-rw-r--r--test/cpp/end2end/end2end_test.cc6
-rw-r--r--test/cpp/end2end/generic_end2end_test.cc4
-rw-r--r--test/cpp/interop/interop_client.cc42
-rw-r--r--test/cpp/interop/interop_client.h9
-rw-r--r--test/cpp/interop/metrics_client.cc2
125 files changed, 6018 insertions, 667 deletions
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
index ed46e7b009..5aceac6cac 100644
--- a/test/core/bad_client/bad_client.c
+++ b/test/core/bad_client/bad_client.c
@@ -49,13 +49,14 @@ typedef struct {
grpc_server *server;
grpc_completion_queue *cq;
grpc_bad_client_server_side_validator validator;
+ void *registered_method;
gpr_event done_thd;
gpr_event done_write;
} thd_args;
static void thd_func(void *arg) {
thd_args *a = arg;
- a->validator(a->server, a->cq);
+ a->validator(a->server, a->cq, a->registered_method);
gpr_event_set(&a->done_thd, (void *)1);
}
@@ -64,14 +65,13 @@ static void done_write(grpc_exec_ctx *exec_ctx, void *arg, int success) {
gpr_event_set(&a->done_write, (void *)1);
}
-static void server_setup_transport(void *ts, grpc_transport *transport,
- grpc_mdctx *mdctx) {
+static void server_setup_transport(void *ts, grpc_transport *transport) {
thd_args *a = ts;
static grpc_channel_filter const *extra_filters[] = {
&grpc_http_server_filter};
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_server_setup_transport(&exec_ctx, a->server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx,
+ GPR_ARRAY_SIZE(extra_filters),
grpc_server_get_channel_args(a->server));
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -84,7 +84,6 @@ void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator,
gpr_thd_id id;
char *hex;
grpc_transport *transport;
- grpc_mdctx *mdctx = grpc_mdctx_create();
gpr_slice slice =
gpr_slice_from_copied_buffer(client_payload, client_payload_length);
gpr_slice_buffer outgoing;
@@ -112,10 +111,12 @@ void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator,
gpr_event_init(&a.done_write);
a.validator = validator;
grpc_server_register_completion_queue(a.server, a.cq, NULL);
+ a.registered_method =
+ grpc_server_register_method(a.server, GRPC_BAD_CLIENT_REGISTERED_METHOD,
+ GRPC_BAD_CLIENT_REGISTERED_HOST);
grpc_server_start(a.server);
- transport =
- grpc_create_chttp2_transport(&exec_ctx, NULL, sfd.server, mdctx, 0);
- server_setup_transport(&a, transport, mdctx);
+ transport = grpc_create_chttp2_transport(&exec_ctx, NULL, sfd.server, 0);
+ server_setup_transport(&a, transport);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/bad_client/bad_client.h b/test/core/bad_client/bad_client.h
index 01beda60ee..2dd100a3db 100644
--- a/test/core/bad_client/bad_client.h
+++ b/test/core/bad_client/bad_client.h
@@ -37,8 +37,12 @@
#include <grpc/grpc.h>
#include "test/core/util/test_config.h"
-typedef void (*grpc_bad_client_server_side_validator)(
- grpc_server *server, grpc_completion_queue *cq);
+#define GRPC_BAD_CLIENT_REGISTERED_METHOD "/registered/bar"
+#define GRPC_BAD_CLIENT_REGISTERED_HOST "localhost"
+
+typedef void (*grpc_bad_client_server_side_validator)(grpc_server *server,
+ grpc_completion_queue *cq,
+ void *registered_method);
#define GRPC_BAD_CLIENT_DISCONNECT 1
diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py
index 3df889ecda..22b99e7cb4 100755
--- a/test/core/bad_client/gen_build_yaml.py
+++ b/test/core/bad_client/gen_build_yaml.py
@@ -40,8 +40,14 @@ default_test_options = TestOptions(False)
# maps test names to options
BAD_CLIENT_TESTS = {
+ 'badreq': default_test_options,
'connection_prefix': default_test_options,
+ 'headers': default_test_options,
'initial_settings_frame': default_test_options,
+ 'server_registered_method': default_test_options,
+ 'simple_request': default_test_options,
+ 'window_overflow': default_test_options,
+ 'unknown_frame': default_test_options,
}
def main():
diff --git a/test/core/bad_client/tests/bad_timeout.headers b/test/core/bad_client/tests/bad_timeout.headers
new file mode 100644
index 0000000000..60c37b9ff6
--- /dev/null
+++ b/test/core/bad_client/tests/bad_timeout.headers
@@ -0,0 +1,2 @@
+# a badly encoded timeout value
+grpc-timeout: 15 seconds \ No newline at end of file
diff --git a/test/core/bad_client/tests/badreq.c b/test/core/bad_client/tests/badreq.c
new file mode 100644
index 0000000000..6d59d25b92
--- /dev/null
+++ b/test/core/bad_client/tests/badreq.c
@@ -0,0 +1,140 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/bad_client/bad_client.h"
+
+#include <string.h>
+
+#include "test/core/end2end/cq_verifier.h"
+#include "src/core/surface/server.h"
+
+#define PFX_STR \
+ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */
+
+static void verifier(grpc_server *server, grpc_completion_queue *cq,
+ void *registered_method) {
+ while (grpc_server_has_open_connections(server)) {
+ GPR_ASSERT(grpc_completion_queue_next(cq,
+ GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20),
+ NULL).type == GRPC_QUEUE_TIMEOUT);
+ }
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+
+ /* invalid content type */
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier, PFX_STR
+ "\x00\x00\xc2\x01\x04\x00\x00\x00\x01"
+ "\x10\x05:path\x08/foo/bar"
+ "\x10\x07:scheme\x04http"
+ "\x10\x07:method\x04POST"
+ "\x10\x0a:authority\x09localhost"
+ "\x10\x0c"
+ "content-type\x09text/html"
+ "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"
+ "\x10\x02te\x08trailers"
+ "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ /* invalid te */
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier, PFX_STR
+ "\x00\x00\xcb\x01\x04\x00\x00\x00\x01"
+ "\x10\x05:path\x08/foo/bar"
+ "\x10\x07:scheme\x04http"
+ "\x10\x07:method\x04POST"
+ "\x10\x0a:authority\x09localhost"
+ "\x10\x0c"
+ "content-type\x10"
+ "application/grpc"
+ "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"
+ "\x10\x02te\x0a"
+ "frobnicate"
+ "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ /* two path headers */
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier, PFX_STR
+ "\x00\x00\xd9\x01\x04\x00\x00\x00\x01"
+ "\x10\x05:path\x08/foo/bar"
+ "\x10\x05:path\x08/foo/bah"
+ "\x10\x07:scheme\x04http"
+ "\x10\x07:method\x04POST"
+ "\x10\x0a:authority\x09localhost"
+ "\x10\x0c"
+ "content-type\x10"
+ "application/grpc"
+ "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"
+ "\x10\x02te\x08trailers"
+ "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ /* bad accept-encoding algorithm */
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier, PFX_STR
+ "\x00\x00\xd2\x01\x04\x00\x00\x00\x01"
+ "\x10\x05:path\x08/foo/bar"
+ "\x10\x07:scheme\x04http"
+ "\x10\x07:method\x04POST"
+ "\x10\x0a:authority\x09localhost"
+ "\x10\x0c"
+ "content-type\x10"
+ "application/grpc"
+ "\x10\x14grpc-accept-encoding\x1enobody-knows-the-trouble-i-see"
+ "\x10\x02te\x08trailers"
+ "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ /* bad grpc-encoding algorithm */
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier, PFX_STR
+ "\x00\x00\xf5\x01\x04\x00\x00\x00\x01"
+ "\x10\x05:path\x08/foo/bar"
+ "\x10\x07:scheme\x04http"
+ "\x10\x07:method\x04POST"
+ "\x10\x0a:authority\x09localhost"
+ "\x10\x0c"
+ "content-type\x10"
+ "application/grpc"
+ "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"
+ "\x10\x0dgrpc-encoding\x1cyou-dont-know-how-to-do-this"
+ "\x10\x02te\x08trailers"
+ "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ return 0;
+}
diff --git a/test/core/bad_client/tests/badreq_2path.headers b/test/core/bad_client/tests/badreq_2path.headers
new file mode 100644
index 0000000000..0441e50c8c
--- /dev/null
+++ b/test/core/bad_client/tests/badreq_2path.headers
@@ -0,0 +1,13 @@
+# headers used in badreq.c
+# use tools/codegen/core/gen_header_frame.py to generate the binary strings
+# contained in the source code
+:path: /foo/bar
+:path: /foo/bah
+:scheme: http
+:method: POST
+:authority: localhost
+content-type: application/grpc
+grpc-accept-encoding: identity,deflate,gzip
+te: trailers
+user-agent: bad-client grpc-c/0.12.0.0 (linux)
+
diff --git a/test/core/bad_client/tests/badreq_algorithm.headers b/test/core/bad_client/tests/badreq_algorithm.headers
new file mode 100644
index 0000000000..ff3e613f93
--- /dev/null
+++ b/test/core/bad_client/tests/badreq_algorithm.headers
@@ -0,0 +1,11 @@
+# headers used in badreq.c
+# use tools/codegen/core/gen_header_frame.py to generate the binary strings
+# contained in the source code
+:path: /foo/bar
+:scheme: http
+:method: POST
+:authority: localhost
+content-type: application/grpc
+grpc-accept-encoding: nobody-knows-the-trouble-i-see
+te: trailers
+user-agent: bad-client grpc-c/0.12.0.0 (linux)
diff --git a/test/core/bad_client/tests/badreq_content_type.headers b/test/core/bad_client/tests/badreq_content_type.headers
new file mode 100644
index 0000000000..ed8d798f19
--- /dev/null
+++ b/test/core/bad_client/tests/badreq_content_type.headers
@@ -0,0 +1,11 @@
+# headers used in badreq.c
+# use tools/codegen/core/gen_header_frame.py to generate the binary strings
+# contained in the source code
+:path: /foo/bar
+:scheme: http
+:method: POST
+:authority: localhost
+content-type: text/html
+grpc-accept-encoding: identity,deflate,gzip
+te: trailers
+user-agent: bad-client grpc-c/0.12.0.0 (linux)
diff --git a/test/core/bad_client/tests/badreq_encoding.headers b/test/core/bad_client/tests/badreq_encoding.headers
new file mode 100644
index 0000000000..5639c1fd71
--- /dev/null
+++ b/test/core/bad_client/tests/badreq_encoding.headers
@@ -0,0 +1,12 @@
+# headers used in badreq.c
+# use tools/codegen/core/gen_header_frame.py to generate the binary strings
+# contained in the source code
+:path: /foo/bar
+:scheme: http
+:method: POST
+:authority: localhost
+content-type: application/grpc
+grpc-accept-encoding: identity,deflate,gzip
+grpc-encoding: you-dont-know-how-to-do-this
+te: trailers
+user-agent: bad-client grpc-c/0.12.0.0 (linux)
diff --git a/test/core/bad_client/tests/badreq_te.headers b/test/core/bad_client/tests/badreq_te.headers
new file mode 100644
index 0000000000..012810e77d
--- /dev/null
+++ b/test/core/bad_client/tests/badreq_te.headers
@@ -0,0 +1,11 @@
+# headers used in badreq.c
+# use tools/codegen/core/gen_header_frame.py to generate the binary strings
+# contained in the source code
+:path: /foo/bar
+:scheme: http
+:method: POST
+:authority: localhost
+content-type: application/grpc
+grpc-accept-encoding: identity,deflate,gzip
+te: frobnicate
+user-agent: bad-client grpc-c/0.12.0.0 (linux)
diff --git a/test/core/bad_client/tests/connection_prefix.c b/test/core/bad_client/tests/connection_prefix.c
index 90d37a3735..66ff8c2936 100644
--- a/test/core/bad_client/tests/connection_prefix.c
+++ b/test/core/bad_client/tests/connection_prefix.c
@@ -34,7 +34,8 @@
#include "test/core/bad_client/bad_client.h"
#include "src/core/surface/server.h"
-static void verifier(grpc_server *server, grpc_completion_queue *cq) {
+static void verifier(grpc_server *server, grpc_completion_queue *cq,
+ void *registered_method) {
while (grpc_server_has_open_connections(server)) {
GPR_ASSERT(grpc_completion_queue_next(cq,
GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20),
diff --git a/test/core/bad_client/tests/headers.c b/test/core/bad_client/tests/headers.c
new file mode 100644
index 0000000000..2186a4ffcb
--- /dev/null
+++ b/test/core/bad_client/tests/headers.c
@@ -0,0 +1,306 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/bad_client/bad_client.h"
+#include "src/core/surface/server.h"
+
+#define PFX_STR \
+ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00"
+
+static void verifier(grpc_server *server, grpc_completion_queue *cq,
+ void *registered_method) {
+ while (grpc_server_has_open_connections(server)) {
+ GPR_ASSERT(grpc_completion_queue_next(cq,
+ GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20),
+ NULL).type == GRPC_QUEUE_TIMEOUT);
+ }
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+
+ /* partial http2 header prefixes */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR "\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR "\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR "\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR "\x00\x00\x00\x01",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR "\x00\x00\x00\x01\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR "\x00\x00\x00\x01\x04",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR "\x00\x00\x00\x01\x05",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR "\x00\x00\x00\x01\x04\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR "\x00\x00\x00\x01\x04\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR "\x00\x00\x00\x01\x04\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR "\x00\x00\x00\x01\x04\x00\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR "\x00\x00\x00\x01\x04\x00\x00\x00\x01",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ /* test adding prioritization data */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x01\x01\x24\x00\x00\x00\x01"
+ "\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x02\x01\x24\x00\x00\x00\x01"
+ "\x00\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x03\x01\x24\x00\x00\x00\x01"
+ "\x00\x00\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x04\x01\x24\x00\x00\x00\x01"
+ "\x00\x00\x00\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x24\x00\x00\x00\x01"
+ "",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x24\x00\x00\x00\x01"
+ "\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x24\x00\x00\x00\x01"
+ "\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x24\x00\x00\x00\x01"
+ "\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x24\x00\x00\x00\x01"
+ "\x00\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x24\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ /* test looking up an invalid index */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x01\x01\x04\x00\x00\x00\x01"
+ "\xfe",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x04\x01\x04\x00\x00\x00\x01"
+ "\x7f\x7f\x01"
+ "a",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x04\x01\x04\x00\x00\x00\x01"
+ "\x0f\x7f\x01"
+ "a",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x04\x01\x04\x00\x00\x00\x01"
+ "\x1f\x7f\x01"
+ "a",
+ 0);
+ /* test nvr, not indexed in static table */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x03\x01\x04\x00\x00\x00\x01"
+ "\x01\x01"
+ "a",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x03\x01\x04\x00\x00\x00\x01"
+ "\x11\x01"
+ "a",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ /* illegal op code */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x01\x01\x04\x00\x00\x00\x01"
+ "\x80",
+ 0);
+ /* parse some long indices */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x02\x01\x04\x00\x00\x00\x01"
+ "\xff\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x03\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x04\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x80\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x06\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x80\x80\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x07\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x80\x80\x80\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x08\x01\x04\x00\x00\x00\x01"
+ "\xff",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x08\x01\x04\x00\x00\x00\x01"
+ "\xff\x80",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x08\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x08\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x80",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x08\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x80\x80",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x08\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x80\x80\x80",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x08\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x80\x80\x80\x80",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x08\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x80\x80\x80\x80\x00",
+ 0);
+ /* overflow on byte 4 */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x06\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x80\x80\x7f",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x06\x01\x04\x00\x00\x00\x01"
+ "\xff\xff\xff\xff\xff\x0f",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ /* overflow after byte 4 */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x08\x01\x04\x00\x00\x00\x01"
+ "\xff\x80\x80\x80\x80\x80\x80\x02",
+ 0);
+ /* end of headers mid-opcode */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x01\x01\x04\x00\x00\x00\x01"
+ "\x01",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ /* dynamic table size update: set to default */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x03\x01\x04\x00\x00\x00\x01"
+ "\x3f\xe1\x1f",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ /* dynamic table size update: set too large */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x03\x01\x04\x00\x00\x00\x01"
+ "\x3f\xf1\x1f",
+ 0);
+ /* dynamic table size update: set twice */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x04\x01\x04\x00\x00\x00\x01"
+ "\x20\x3f\xe1\x1f",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ /* dynamic table size update: set thrice */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x03\x01\x04\x00\x00\x00\x01"
+ "\x20\x20\x20",
+ 0);
+
+ /* non-ending header followed by continuation frame */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x09\x04\x00\x00\x00\x01",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ /* non-ending header followed by non-continuation frame */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x04\x00\x00\x00\x01",
+ 0);
+ /* non-ending header followed by a continuation frame for a different stream
+ */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x00\x01\x04\x00\x00\x00\x01"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x03"
+ "\x00\x00\x00\x09\x04\x00\x00\x00\x01",
+ 0);
+ /* opening with a continuation frame */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR "\x00\x00\x00\x09\x04\x00\x00\x00\x01", 0);
+ /* three header frames */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x00\x01\x04\x00\x00\x00\x01"
+ "\x00\x00\x00\x01\x04\x00\x00\x00\x01"
+ "\x00\x00\x00\x01\x04\x00\x00\x00\x01",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ /* an invalid header found with fuzzing */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR "\x00\x00\x00\x01\x39\x67\xed\x1d\x64",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ /* a badly encoded timeout value */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x19\x01\x04\x00\x00\x00\x01"
+ "\x10\x0cgrpc-timeout\x0a"
+ "15 seconds",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ /* a badly encoded timeout value: twice (catches caching) */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x19\x01\x04\x00\x00\x00\x01"
+ "\x10\x0cgrpc-timeout\x0a"
+ "15 seconds"
+ "\x00\x00\x19\x01\x04\x00\x00\x00\x03"
+ "\x10\x0cgrpc-timeout\x0a"
+ "15 seconds",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ return 0;
+}
diff --git a/test/core/bad_client/tests/initial_settings_frame.c b/test/core/bad_client/tests/initial_settings_frame.c
index 827e93b67c..fb6149cc3b 100644
--- a/test/core/bad_client/tests/initial_settings_frame.c
+++ b/test/core/bad_client/tests/initial_settings_frame.c
@@ -35,8 +35,10 @@
#include "src/core/surface/server.h"
#define PFX_STR "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
+#define ONE_SETTING_HDR "\x00\x00\x06\x04\x00\x00\x00\x00\x00"
-static void verifier(grpc_server *server, grpc_completion_queue *cq) {
+static void verifier(grpc_server *server, grpc_completion_queue *cq,
+ void *registered_method) {
while (grpc_server_has_open_connections(server)) {
GPR_ASSERT(grpc_completion_queue_next(cq,
GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20),
@@ -90,6 +92,30 @@ int main(int argc, char **argv) {
PFX_STR "\x00\x00\x04\x04\x00\x00\x00\x00\x00", 0);
GRPC_RUN_BAD_CLIENT_TEST(verifier,
PFX_STR "\x00\x00\x05\x04\x00\x00\x00\x00\x00", 0);
+ /* some settings values are illegal */
+ /* max frame size = 0 */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR ONE_SETTING_HDR "\x00\x05\x00\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR ONE_SETTING_HDR "\x00\x06\xff\xff\xff\xff",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ /* update intiial window size */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR ONE_SETTING_HDR "\x00\x04\x00\x01\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ /* ack with data */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00"
+ "\x00\x00\x01\x04\x01\x00\x00\x00\x00",
+ 0);
+ /* settings frame with invalid flags */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR "\x00\x00\x00\x04\x10\x00\x00\x00\x00", 0);
+ /* unknown settings should be ignored */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR ONE_SETTING_HDR "\x00\x99\x00\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
return 0;
}
diff --git a/test/core/bad_client/tests/server_registered_method.c b/test/core/bad_client/tests/server_registered_method.c
new file mode 100644
index 0000000000..d2876ffa93
--- /dev/null
+++ b/test/core/bad_client/tests/server_registered_method.c
@@ -0,0 +1,155 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/bad_client/bad_client.h"
+
+#include <string.h>
+
+#include "test/core/end2end/cq_verifier.h"
+#include "src/core/surface/server.h"
+
+#define PFX_STR \
+ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */ \
+ "\x00\x00\xd0\x01\x04\x00\x00\x00\x01" \
+ "\x10\x05:path\x0f/registered/bar" \
+ "\x10\x07:scheme\x04http" \
+ "\x10\x07:method\x04POST" \
+ "\x10\x0a:authority\x09localhost" \
+ "\x10\x0c" \
+ "content-type\x10" \
+ "application/grpc" \
+ "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip" \
+ "\x10\x02te\x08trailers" \
+ "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
+
+static void *tag(gpr_intptr t) { return (void *)t; }
+
+static void verifier_succeeds(grpc_server *server, grpc_completion_queue *cq,
+ void *registered_method) {
+ grpc_call_error error;
+ grpc_call *s;
+ cq_verifier *cqv = cq_verifier_create(cq);
+ grpc_metadata_array request_metadata_recv;
+ gpr_timespec deadline;
+ grpc_byte_buffer *payload = NULL;
+
+ grpc_metadata_array_init(&request_metadata_recv);
+
+ error = grpc_server_request_registered_call(server, registered_method, &s,
+ &deadline, &request_metadata_recv,
+ &payload, cq, cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ cq_expect_completion(cqv, tag(101), 1);
+ cq_verify(cqv);
+
+ GPR_ASSERT(payload != NULL);
+
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_destroy(s);
+ grpc_byte_buffer_destroy(payload);
+ cq_verifier_destroy(cqv);
+}
+
+static void verifier_fails(grpc_server *server, grpc_completion_queue *cq,
+ void *registered_method) {
+ grpc_call_error error;
+ grpc_call *s;
+ cq_verifier *cqv = cq_verifier_create(cq);
+ grpc_metadata_array request_metadata_recv;
+ gpr_timespec deadline;
+ grpc_byte_buffer *payload = NULL;
+
+ grpc_metadata_array_init(&request_metadata_recv);
+
+ error = grpc_server_request_registered_call(server, registered_method, &s,
+ &deadline, &request_metadata_recv,
+ &payload, cq, cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ cq_expect_completion(cqv, tag(101), 1);
+ cq_verify(cqv);
+
+ GPR_ASSERT(payload == NULL);
+
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_destroy(s);
+ cq_verifier_destroy(cqv);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+
+ /* body generated with
+ * tools/codegen/core/gen_server_registered_method_bad_client_test_body.py */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier_fails,
+ PFX_STR "\x00\x00\x00\x00\x00\x00\x00\x00\x01",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier_fails,
+ PFX_STR "\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier_fails, PFX_STR
+ "\x00\x00\x02\x00\x00\x00\x00\x00\x01\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier_fails, PFX_STR
+ "\x00\x00\x03\x00\x00\x00\x00\x00\x01\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier_fails,
+ PFX_STR "\x00\x00\x04\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier_succeeds,
+ PFX_STR "\x00\x00\x05\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00", 0);
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier_fails,
+ PFX_STR "\x00\x00\x05\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier_succeeds,
+ PFX_STR "\x00\x00\x06\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00",
+ 0);
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier_fails,
+ PFX_STR "\x00\x00\x05\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x02",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier_fails,
+ PFX_STR "\x00\x00\x06\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x02\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(
+ verifier_succeeds, PFX_STR
+ "\x00\x00\x07\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x02\x00\x00",
+ 0);
+
+ return 0;
+}
diff --git a/test/core/bad_client/tests/server_registered_method.headers b/test/core/bad_client/tests/server_registered_method.headers
new file mode 100644
index 0000000000..06ee73c82e
--- /dev/null
+++ b/test/core/bad_client/tests/server_registered_method.headers
@@ -0,0 +1,12 @@
+# headers used in simple_request.c
+# use tools/codegen/core/gen_header_frame.py to generate the binary strings
+# contained in the source code
+:path: /registered/bar
+:scheme: http
+:method: POST
+:authority: localhost
+content-type: application/grpc
+grpc-accept-encoding: identity,deflate,gzip
+te: trailers
+user-agent: bad-client grpc-c/0.12.0.0 (linux)
+
diff --git a/test/core/bad_client/tests/simple_request.c b/test/core/bad_client/tests/simple_request.c
new file mode 100644
index 0000000000..4df586e0e4
--- /dev/null
+++ b/test/core/bad_client/tests/simple_request.c
@@ -0,0 +1,159 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/bad_client/bad_client.h"
+
+#include <string.h>
+
+#include "test/core/end2end/cq_verifier.h"
+#include "src/core/surface/server.h"
+
+#define PFX_STR \
+ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */ \
+ "\x00\x00\xc9\x01\x04\x00\x00\x00\x01" /* headers: generated from \
+ simple_request.headers in this \
+ directory */ \
+ "\x10\x05:path\x08/foo/bar" \
+ "\x10\x07:scheme\x04http" \
+ "\x10\x07:method\x04POST" \
+ "\x10\x0a:authority\x09localhost" \
+ "\x10\x0c" \
+ "content-type\x10" \
+ "application/grpc" \
+ "\x10\x14grpc-accept-encoding\x15" \
+ "deflate,identity,gzip" \
+ "\x10\x02te\x08trailers" \
+ "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
+
+#define PFX_STR_UNUSUAL \
+ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */ \
+ "\x00\x00\xf4\x01\x04\x00\x00\x00\x01" /* headers: generated from \
+ simple_request_unusual.headers \
+ in this directory */ \
+ "\x10\x05:path\x08/foo/bar" \
+ "\x10\x07:scheme\x04http" \
+ "\x10\x07:method\x04POST" \
+ "\x10\x04host\x09localhost" \
+ "\x10\x0c" \
+ "content-type\x1e" \
+ "application/grpc+this-is-valid" \
+ "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip" \
+ "\x10\x02te\x08trailers" \
+ "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" \
+ "\x10\x0cgrpc-timeout\x03" \
+ "10S" \
+ "\x10\x0cgrpc-timeout\x02" \
+ "5S"
+
+static void *tag(gpr_intptr t) { return (void *)t; }
+
+static void verifier(grpc_server *server, grpc_completion_queue *cq,
+ void *registered_method) {
+ grpc_call_error error;
+ grpc_call *s;
+ grpc_call_details call_details;
+ cq_verifier *cqv = cq_verifier_create(cq);
+ grpc_metadata_array request_metadata_recv;
+
+ grpc_call_details_init(&call_details);
+ grpc_metadata_array_init(&request_metadata_recv);
+
+ error = grpc_server_request_call(server, &s, &call_details,
+ &request_metadata_recv, cq, cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ cq_expect_completion(cqv, tag(101), 1);
+ cq_verify(cqv);
+
+ GPR_ASSERT(0 == strcmp(call_details.host, "localhost"));
+ GPR_ASSERT(0 == strcmp(call_details.method, "/foo/bar"));
+
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_call_destroy(s);
+ cq_verifier_destroy(cqv);
+}
+
+static void failure_verifier(grpc_server *server, grpc_completion_queue *cq,
+ void *registered_method) {
+ while (grpc_server_has_open_connections(server)) {
+ GPR_ASSERT(grpc_completion_queue_next(cq,
+ GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20),
+ NULL).type == GRPC_QUEUE_TIMEOUT);
+ }
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+
+ /* basic request: check that things are working */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR, 0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR_UNUSUAL, 0);
+
+ /* push an illegal data frame */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x00\x00\x00\x00\x00\x01"
+ "\x34\x00\x00\x00\x00",
+ 0);
+
+ /* push a data frame with bad flags */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR "\x00\x00\x00\x00\x02\x00\x00\x00\x01", 0);
+ /* push a window update with a bad length */
+ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier,
+ PFX_STR "\x00\x00\x01\x08\x00\x00\x00\x00\x01", 0);
+ /* push a window update with bad flags */
+ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier,
+ PFX_STR "\x00\x00\x00\x08\x10\x00\x00\x00\x01", 0);
+ /* push a window update with bad data */
+ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, PFX_STR
+ "\x00\x00\x04\x08\x00\x00\x00\x00\x01"
+ "\xff\xff\xff\xff",
+ 0);
+ /* push a short goaway */
+ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier,
+ PFX_STR "\x00\x00\x04\x07\x00\x00\x00\x00\x00", 0);
+ /* disconnect before sending goaway */
+ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier,
+ PFX_STR "\x00\x01\x12\x07\x00\x00\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ /* push a rst_stream with a bad length */
+ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier,
+ PFX_STR "\x00\x00\x01\x03\x00\x00\x00\x00\x01", 0);
+ /* push a rst_stream with bad flags */
+ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier,
+ PFX_STR "\x00\x00\x00\x03\x10\x00\x00\x00\x01", 0);
+
+ return 0;
+}
diff --git a/test/core/bad_client/tests/simple_request.headers b/test/core/bad_client/tests/simple_request.headers
new file mode 100644
index 0000000000..691fac161a
--- /dev/null
+++ b/test/core/bad_client/tests/simple_request.headers
@@ -0,0 +1,12 @@
+# headers used in simple_request.c
+# use tools/codegen/core/gen_header_frame.py to generate the binary strings
+# contained in the source code
+:path: /foo/bar
+:scheme: http
+:method: POST
+:authority: localhost
+content-type: application/grpc
+grpc-accept-encoding: identity,deflate,gzip
+te: trailers
+user-agent: bad-client grpc-c/0.12.0.0 (linux)
+
diff --git a/test/core/bad_client/tests/simple_request_unusual.headers b/test/core/bad_client/tests/simple_request_unusual.headers
new file mode 100644
index 0000000000..f36e1dfc9f
--- /dev/null
+++ b/test/core/bad_client/tests/simple_request_unusual.headers
@@ -0,0 +1,13 @@
+# headers used in simple_request.c
+# use tools/codegen/core/gen_header_frame.py to generate the binary strings
+# contained in the source code
+:path: /foo/bar
+:scheme: http
+:method: POST
+host: localhost
+content-type: application/grpc+this-is-valid
+grpc-accept-encoding: deflate,identity,gzip
+te: trailers
+user-agent: bad-client grpc-c/0.12.0.0 (linux)
+grpc-timeout: 10S
+grpc-timeout: 5S
diff --git a/test/core/bad_client/tests/unknown_frame.c b/test/core/bad_client/tests/unknown_frame.c
new file mode 100644
index 0000000000..2ef340eeb5
--- /dev/null
+++ b/test/core/bad_client/tests/unknown_frame.c
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/bad_client/bad_client.h"
+#include "src/core/surface/server.h"
+
+#define PFX_STR \
+ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00"
+
+static void verifier(grpc_server *server, grpc_completion_queue *cq,
+ void *registered_method) {
+ while (grpc_server_has_open_connections(server)) {
+ GPR_ASSERT(grpc_completion_queue_next(cq,
+ GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20),
+ NULL).type == GRPC_QUEUE_TIMEOUT);
+ }
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+
+ /* test adding prioritization data */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR "\x00\x00\x00\x88\x00\x00\x00\x00\x01",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
+ return 0;
+}
diff --git a/test/core/bad_client/tests/window_overflow.c b/test/core/bad_client/tests/window_overflow.c
new file mode 100644
index 0000000000..1c898f352d
--- /dev/null
+++ b/test/core/bad_client/tests/window_overflow.c
@@ -0,0 +1,106 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/bad_client/bad_client.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+
+#include "src/core/surface/server.h"
+
+#define PFX_STR \
+ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */ \
+ "\x00\x00\xc9\x01\x04\x00\x00\x00\x01" /* headers: generated from \
+ simple_request.headers in this \
+ directory */ \
+ "\x10\x05:path\x08/foo/bar" \
+ "\x10\x07:scheme\x04http" \
+ "\x10\x07:method\x04POST" \
+ "\x10\x0a:authority\x09localhost" \
+ "\x10\x0c" \
+ "content-type\x10" \
+ "application/grpc" \
+ "\x10\x14grpc-accept-encoding\x15" \
+ "deflate,identity,gzip" \
+ "\x10\x02te\x08trailers" \
+ "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
+
+static void verifier(grpc_server *server, grpc_completion_queue *cq,
+ void *registered_method) {
+ while (grpc_server_has_open_connections(server)) {
+ GPR_ASSERT(grpc_completion_queue_next(cq,
+ GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20),
+ NULL).type == GRPC_QUEUE_TIMEOUT);
+ }
+}
+
+char *g_buffer;
+size_t g_cap = 0;
+size_t g_count = 0;
+
+static void addbuf(const void *data, size_t len) {
+ if (g_count + len > g_cap) {
+ g_cap = GPR_MAX(g_count + len, g_cap * 2);
+ g_buffer = gpr_realloc(g_buffer, g_cap);
+ }
+ memcpy(g_buffer + g_count, data, len);
+ g_count += len;
+}
+
+int main(int argc, char **argv) {
+ int i, j;
+#define MAX_FRAME_SIZE 16384
+#define MESSAGES_PER_FRAME (MAX_FRAME_SIZE / 5)
+#define FRAME_SIZE (MESSAGES_PER_FRAME * 5)
+#define SEND_SIZE (100 * 1024)
+#define NUM_FRAMES (SEND_SIZE / FRAME_SIZE + 1)
+ grpc_test_init(argc, argv);
+
+ addbuf(PFX_STR, sizeof(PFX_STR) - 1);
+ for (i = 0; i < NUM_FRAMES; i++) {
+ gpr_uint8 hdr[9] = {(gpr_uint8)(FRAME_SIZE >> 16),
+ (gpr_uint8)(FRAME_SIZE >> 8), (gpr_uint8)FRAME_SIZE, 0,
+ 0, 0, 0, 0, 1};
+ addbuf(hdr, sizeof(hdr));
+ for (j = 0; j < MESSAGES_PER_FRAME; j++) {
+ gpr_uint8 message[5] = {0, 0, 0, 0, 0};
+ addbuf(message, sizeof(message));
+ }
+ }
+ grpc_run_bad_client_test(verifier, g_buffer, g_count, 0);
+ gpr_free(g_buffer);
+
+ return 0;
+}
diff --git a/test/core/bad_ssl/bad_ssl_test.c b/test/core/bad_ssl/bad_ssl_test.c
new file mode 100644
index 0000000000..08ab482c58
--- /dev/null
+++ b/test/core/bad_ssl/bad_ssl_test.c
@@ -0,0 +1,171 @@
+/*
+ *
+ * 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 <string.h>
+#include <stdio.h>
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/subprocess.h>
+#include "src/core/support/string.h"
+#include "test/core/util/port.h"
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/util/test_config.h"
+
+static void *tag(gpr_intptr t) { return (void *)t; }
+
+static void run_test(const char *target, size_t nops) {
+ grpc_channel_credentials *ssl_creds =
+ grpc_ssl_credentials_create(NULL, NULL, NULL);
+ grpc_channel *channel;
+ grpc_call *c;
+
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ char *details = NULL;
+ size_t details_capacity = 0;
+ grpc_status_code status;
+ grpc_call_error error;
+ gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
+ grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+ cq_verifier *cqv = cq_verifier_create(cq);
+
+ grpc_op ops[6];
+ grpc_op *op;
+
+ grpc_arg ssl_name_override = {GRPC_ARG_STRING,
+ GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
+ {"foo.test.google.fr"}};
+ grpc_channel_args args;
+
+ args.num_args = 1;
+ args.args = &ssl_name_override;
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+
+ channel = grpc_secure_channel_create(ssl_creds, target, &args, NULL);
+ c = grpc_channel_create_call(channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
+ "/foo", "foo.test.google.fr:1234", deadline,
+ NULL);
+
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op->data.recv_status_on_client.status_details_capacity = &details_capacity;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata = &initial_metadata_recv;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ error = grpc_call_start_batch(c, ops, nops, tag(1), NULL);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ cq_expect_completion(cqv, tag(1), 1);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status != GRPC_STATUS_OK);
+
+ grpc_call_destroy(c);
+ gpr_free(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+
+ grpc_channel_destroy(channel);
+ grpc_completion_queue_destroy(cq);
+ cq_verifier_destroy(cqv);
+ grpc_channel_credentials_release(ssl_creds);
+}
+
+int main(int argc, char **argv) {
+ char *me = argv[0];
+ char *lslash = strrchr(me, '/');
+ char *lunder = strrchr(me, '_');
+ char *tmp;
+ char root[1024];
+ char test[64];
+ int port = grpc_pick_unused_port_or_die();
+ char *args[10];
+ int status;
+ size_t i;
+ gpr_subprocess *svr;
+ /* figure out where we are */
+ if (lslash) {
+ memcpy(root, me, (size_t)(lslash - me));
+ root[lslash - me] = 0;
+ } else {
+ strcpy(root, ".");
+ }
+ /* figure out our test name */
+ tmp = lunder - 1;
+ while (*tmp != '_') tmp--;
+ tmp++;
+ memcpy(test, tmp, (size_t)(lunder - tmp));
+ /* start the server */
+ gpr_asprintf(&args[0], "%s/bad_ssl_%s_server%s", root, test,
+ gpr_subprocess_binary_extension());
+ args[1] = "--bind";
+ gpr_join_host_port(&args[2], "::", port);
+ svr = gpr_subprocess_create(4, (const char **)args);
+ gpr_free(args[0]);
+
+ for (i = 3; i <= 4; i++) {
+ grpc_init();
+ run_test(args[2], i);
+ grpc_shutdown();
+ }
+ gpr_free(args[2]);
+
+ gpr_subprocess_interrupt(svr);
+ status = gpr_subprocess_join(svr);
+ gpr_subprocess_destroy(svr);
+ return status;
+}
diff --git a/test/core/bad_ssl/gen_build_yaml.py b/test/core/bad_ssl/gen_build_yaml.py
new file mode 100755
index 0000000000..d12722439e
--- /dev/null
+++ b/test/core/bad_ssl/gen_build_yaml.py
@@ -0,0 +1,104 @@
+#!/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.
+
+
+"""Generates the appropriate build.json data for all the end2end tests."""
+
+
+import collections
+import yaml
+
+TestOptions = collections.namedtuple('TestOptions', 'flaky')
+default_test_options = TestOptions(False)
+
+# maps test names to options
+BAD_CLIENT_TESTS = {
+ 'cert': default_test_options,
+ 'alpn': default_test_options,
+}
+
+def main():
+ json = {
+ '#': 'generated with test/bad_ssl/gen_build_json.py',
+ 'libs': [
+ {
+ 'name': 'bad_ssl_test_server',
+ 'build': 'private',
+ 'language': 'c',
+ 'src': ['test/core/bad_ssl/server.c'],
+ 'headers': ['test/core/bad_ssl/server.h'],
+ 'vs_proj_dir': 'test',
+ 'platforms': ['linux', 'posix', 'mac'],
+ 'deps': [
+ 'grpc_test_util',
+ 'grpc',
+ 'gpr_test_util',
+ 'gpr'
+ ]
+ }
+ ],
+ 'targets': [
+ {
+ 'name': 'bad_ssl_%s_server' % t,
+ 'build': 'test',
+ 'language': 'c',
+ 'run': False,
+ 'src': ['test/core/bad_ssl/servers/%s.c' % t],
+ 'vs_proj_dir': 'test',
+ 'platforms': ['linux', 'posix', 'mac'],
+ 'deps': [
+ 'bad_ssl_test_server',
+ 'grpc_test_util',
+ 'grpc',
+ 'gpr_test_util',
+ 'gpr'
+ ]
+ }
+ for t in sorted(BAD_CLIENT_TESTS.keys())] + [
+ {
+ 'name': 'bad_ssl_%s_test' % t,
+ 'build': 'test',
+ 'language': 'c',
+ 'src': ['test/core/bad_ssl/bad_ssl_test.c'],
+ 'vs_proj_dir': 'test',
+ 'platforms': ['linux', 'posix', 'mac'],
+ 'deps': [
+ 'grpc_test_util',
+ 'grpc',
+ 'gpr_test_util',
+ 'gpr'
+ ]
+ }
+ for t in sorted(BAD_CLIENT_TESTS.keys())]}
+ print yaml.dump(json)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/core/bad_ssl/server.c b/test/core/bad_ssl/server.c
new file mode 100644
index 0000000000..6113d364c9
--- /dev/null
+++ b/test/core/bad_ssl/server.c
@@ -0,0 +1,113 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/cmdline.h>
+#include <grpc/support/log.h>
+#include <signal.h>
+
+#include "test/core/bad_ssl/server.h"
+#include "test/core/util/test_config.h"
+
+/* Common server implementation details for all servers in servers/.
+ * There's nothing *wrong* with these servers per-se, but they are
+ * configured to cause some failure case in the SSL connection path.
+ */
+
+static int got_sigint = 0;
+
+static void sigint_handler(int x) { got_sigint = 1; }
+
+const char *bad_ssl_addr(int argc, char **argv) {
+ gpr_cmdline *cl;
+ char *addr = NULL;
+ cl = gpr_cmdline_create("test server");
+ gpr_cmdline_add_string(cl, "bind", "Bind host:port", &addr);
+ gpr_cmdline_parse(cl, argc, argv);
+ gpr_cmdline_destroy(cl);
+ GPR_ASSERT(addr);
+ return addr;
+}
+
+void bad_ssl_run(grpc_server *server) {
+ int shutdown_started = 0;
+ int shutdown_finished = 0;
+ grpc_event ev;
+ grpc_call_error error;
+ grpc_call *s = NULL;
+ grpc_call_details call_details;
+ grpc_metadata_array request_metadata_recv;
+ grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+
+ grpc_call_details_init(&call_details);
+ grpc_metadata_array_init(&request_metadata_recv);
+
+ grpc_server_register_completion_queue(server, cq, NULL);
+ grpc_server_start(server);
+
+ error = grpc_server_request_call(server, &s, &call_details,
+ &request_metadata_recv, cq, cq, (void *)1);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ signal(SIGINT, sigint_handler);
+ while (!shutdown_finished) {
+ if (got_sigint && !shutdown_started) {
+ gpr_log(GPR_INFO, "Shutting down due to SIGINT");
+ grpc_server_shutdown_and_notify(server, cq, NULL);
+ GPR_ASSERT(grpc_completion_queue_pluck(
+ cq, NULL, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL)
+ .type == GRPC_OP_COMPLETE);
+ grpc_completion_queue_shutdown(cq);
+ shutdown_started = 1;
+ }
+ ev = grpc_completion_queue_next(
+ cq, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_micros(1000000, GPR_TIMESPAN)),
+ NULL);
+ switch (ev.type) {
+ case GRPC_OP_COMPLETE:
+ GPR_ASSERT(ev.tag == (void *)1);
+ GPR_ASSERT(ev.success == 0);
+ break;
+ case GRPC_QUEUE_SHUTDOWN:
+ GPR_ASSERT(shutdown_started);
+ shutdown_finished = 1;
+ break;
+ case GRPC_QUEUE_TIMEOUT:
+ break;
+ }
+ }
+
+ GPR_ASSERT(s == NULL);
+ grpc_call_details_destroy(&call_details);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+}
diff --git a/test/core/bad_ssl/server.h b/test/core/bad_ssl/server.h
new file mode 100644
index 0000000000..8ec7755503
--- /dev/null
+++ b/test/core/bad_ssl/server.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CORE_BAD_SSL_SERVER_H
+#define GRPC_TEST_CORE_BAD_SSL_SERVER_H
+
+#include <grpc/grpc.h>
+
+const char *bad_ssl_addr(int argc, char **argv);
+void bad_ssl_run(grpc_server *server);
+
+#endif /* GRPC_TEST_CORE_BAD_SSL_SERVER_H */
diff --git a/test/core/bad_ssl/servers/alpn.c b/test/core/bad_ssl/servers/alpn.c
new file mode 100644
index 0000000000..7d70690e52
--- /dev/null
+++ b/test/core/bad_ssl/servers/alpn.c
@@ -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.
+ *
+ */
+
+#include <string.h>
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/transport/chttp2/alpn.h"
+#include "test/core/bad_ssl/server.h"
+#include "test/core/end2end/data/ssl_test_data.h"
+
+/* This test starts a server that is configured to advertise (via alpn and npn)
+ * a protocol that the connecting client does not support. It does this by
+ * overriding the functions declared in alpn.c from the core library. */
+
+static const char *const fake_versions[] = {"not-h2"};
+
+int grpc_chttp2_is_alpn_version_supported(const char *version, size_t size) {
+ size_t i;
+ for (i = 0; i < GPR_ARRAY_SIZE(fake_versions); i++) {
+ if (!strncmp(version, fake_versions[i], size)) return 1;
+ }
+ return 0;
+}
+
+size_t grpc_chttp2_num_alpn_versions(void) {
+ return GPR_ARRAY_SIZE(fake_versions);
+}
+
+const char *grpc_chttp2_get_alpn_version_index(size_t i) {
+ GPR_ASSERT(i < GPR_ARRAY_SIZE(fake_versions));
+ return fake_versions[i];
+}
+
+int main(int argc, char **argv) {
+ const char *addr = bad_ssl_addr(argc, argv);
+ grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key,
+ test_server1_cert};
+ grpc_server_credentials *ssl_creds;
+ grpc_server *server;
+
+ grpc_init();
+ ssl_creds =
+ grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0, NULL);
+ server = grpc_server_create(NULL, NULL);
+ GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
+ grpc_server_credentials_release(ssl_creds);
+
+ bad_ssl_run(server);
+ grpc_shutdown();
+
+ return 0;
+}
diff --git a/test/core/bad_ssl/servers/cert.c b/test/core/bad_ssl/servers/cert.c
new file mode 100644
index 0000000000..d67a6ca1d4
--- /dev/null
+++ b/test/core/bad_ssl/servers/cert.c
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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 <string.h>
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/support/file.h"
+
+#include "test/core/bad_ssl/server.h"
+#include "test/core/end2end/data/ssl_test_data.h"
+
+/* This server will present an untrusted cert to the connecting client,
+ * causing the SSL handshake to fail */
+
+int main(int argc, char **argv) {
+ const char *addr = bad_ssl_addr(argc, argv);
+ grpc_ssl_pem_key_cert_pair pem_key_cert_pair;
+ grpc_server_credentials *ssl_creds;
+ grpc_server *server;
+ gpr_slice cert_slice, key_slice;
+ int ok;
+
+ grpc_init();
+
+ cert_slice = gpr_load_file("src/core/tsi/test_creds/badserver.pem", 1, &ok);
+ GPR_ASSERT(ok);
+ key_slice = gpr_load_file("src/core/tsi/test_creds/badserver.key", 1, &ok);
+ GPR_ASSERT(ok);
+ pem_key_cert_pair.private_key = (const char *)GPR_SLICE_START_PTR(key_slice);
+ pem_key_cert_pair.cert_chain = (const char *)GPR_SLICE_START_PTR(cert_slice);
+
+ ssl_creds =
+ grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0, NULL);
+ server = grpc_server_create(NULL, NULL);
+ GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
+ grpc_server_credentials_release(ssl_creds);
+
+ gpr_slice_unref(cert_slice);
+ gpr_slice_unref(key_slice);
+
+ bad_ssl_run(server);
+ grpc_shutdown();
+
+ return 0;
+}
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index 5e1ba11857..f1bb37c0bf 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -81,6 +81,16 @@ static char *get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
return gpr_strdup("peer");
}
+static void free_channel(grpc_exec_ctx *exec_ctx, void *arg, int success) {
+ grpc_channel_stack_destroy(exec_ctx, arg);
+ gpr_free(arg);
+}
+
+static void free_call(grpc_exec_ctx *exec_ctx, void *arg, int success) {
+ grpc_call_stack_destroy(exec_ctx, arg);
+ gpr_free(arg);
+}
+
static void test_create_channel_stack(void) {
const grpc_channel_filter filter = {
call_func, channel_func, sizeof(int), call_init_func,
@@ -93,13 +103,10 @@ static void test_create_channel_stack(void) {
grpc_call_element *call_elem;
grpc_arg arg;
grpc_channel_args chan_args;
- grpc_mdctx *metadata_context;
int *channel_data;
int *call_data;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- metadata_context = grpc_mdctx_create();
-
arg.type = GRPC_ARG_INTEGER;
arg.key = "test_key";
arg.value.integer = 42;
@@ -108,16 +115,16 @@ static void test_create_channel_stack(void) {
chan_args.args = &arg;
channel_stack = gpr_malloc(grpc_channel_stack_size(&filters, 1));
- grpc_channel_stack_init(&exec_ctx, &filters, 1, NULL, &chan_args,
- metadata_context, channel_stack);
+ grpc_channel_stack_init(&exec_ctx, 1, free_channel, channel_stack, &filters,
+ 1, &chan_args, "test", channel_stack);
GPR_ASSERT(channel_stack->count == 1);
channel_elem = grpc_channel_stack_element(channel_stack, 0);
channel_data = (int *)channel_elem->channel_data;
GPR_ASSERT(*channel_data == 0);
call_stack = gpr_malloc(channel_stack->call_stack_size);
- grpc_call_stack_init(&exec_ctx, channel_stack, 0, NULL, NULL, NULL, NULL,
- call_stack);
+ grpc_call_stack_init(&exec_ctx, channel_stack, 1, free_call, call_stack, NULL,
+ NULL, call_stack);
GPR_ASSERT(call_stack->count == 1);
call_elem = grpc_call_stack_element(call_stack, 0);
GPR_ASSERT(call_elem->filter == channel_elem->filter);
@@ -126,20 +133,19 @@ static void test_create_channel_stack(void) {
GPR_ASSERT(*call_data == 0);
GPR_ASSERT(*channel_data == 1);
- grpc_call_stack_destroy(&exec_ctx, call_stack);
- gpr_free(call_stack);
+ GRPC_CALL_STACK_UNREF(&exec_ctx, call_stack, "done");
+ grpc_exec_ctx_flush(&exec_ctx);
GPR_ASSERT(*channel_data == 2);
- grpc_channel_stack_destroy(&exec_ctx, channel_stack);
- gpr_free(channel_stack);
-
- grpc_mdctx_unref(metadata_context);
+ GRPC_CHANNEL_STACK_UNREF(&exec_ctx, channel_stack, "done");
grpc_exec_ctx_finish(&exec_ctx);
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
+ grpc_init();
test_create_channel_stack();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/client_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c
index 5aa8140e08..5f6166cbb5 100644
--- a/test/core/client_config/lb_policies_test.c
+++ b/test/core/client_config/lb_policies_test.c
@@ -38,17 +38,19 @@
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
-#include <grpc/support/time.h>
#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
#include "src/core/channel/channel_stack.h"
-#include "src/core/surface/channel.h"
#include "src/core/channel/client_channel.h"
+#include "src/core/client_config/lb_policies/round_robin.h"
+#include "src/core/client_config/lb_policy_registry.h"
#include "src/core/support/string.h"
+#include "src/core/surface/channel.h"
#include "src/core/surface/server.h"
-#include "test/core/util/test_config.h"
-#include "test/core/util/port.h"
#include "test/core/end2end/cq_verifier.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
typedef struct servers_fixture {
size_t num_servers;
@@ -135,9 +137,8 @@ static void kill_server(const servers_fixture *f, size_t i) {
gpr_log(GPR_INFO, "KILLING SERVER %d", i);
GPR_ASSERT(f->servers[i] != NULL);
grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000));
- GPR_ASSERT(
- grpc_completion_queue_pluck(f->cq, tag(10000), n_millis_time(5000), NULL)
- .type == GRPC_OP_COMPLETE);
+ GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(10000), n_millis_time(5000),
+ NULL).type == GRPC_OP_COMPLETE);
grpc_server_destroy(f->servers[i]);
f->servers[i] = NULL;
}
@@ -203,8 +204,8 @@ static void teardown_servers(servers_fixture *f) {
if (f->servers[i] == NULL) continue;
grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000));
GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(10000),
- n_millis_time(5000), NULL)
- .type == GRPC_OP_COMPLETE);
+ n_millis_time(5000),
+ NULL).type == GRPC_OP_COMPLETE);
grpc_server_destroy(f->servers[i]);
}
grpc_completion_queue_shutdown(f->cq);
@@ -225,8 +226,8 @@ static void teardown_servers(servers_fixture *f) {
}
/** Returns connection sequence (server indices), which must be freed */
-int *perform_request(servers_fixture *f, grpc_channel *client,
- request_data *rdata, const test_spec *spec) {
+static int *perform_request(servers_fixture *f, grpc_channel *client,
+ request_data *rdata, const test_spec *spec) {
grpc_call *c;
int s_idx;
int *s_valid;
@@ -242,8 +243,6 @@ int *perform_request(servers_fixture *f, grpc_channel *client,
s_valid = gpr_malloc(sizeof(int) * f->num_servers);
connection_sequence = gpr_malloc(sizeof(int) * spec->num_iters);
- /* Send a trivial request. */
-
for (iter_num = 0; iter_num < spec->num_iters; iter_num++) {
cq_verifier *cqv = cq_verifier_create(f->cq);
rdata->details = NULL;
@@ -304,8 +303,8 @@ int *perform_request(servers_fixture *f, grpc_channel *client,
s_idx = -1;
while ((ev = grpc_completion_queue_next(
- f->cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), NULL))
- .type != GRPC_QUEUE_TIMEOUT) {
+ f->cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), NULL)).type !=
+ GRPC_QUEUE_TIMEOUT) {
GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
read_tag = ((int)(gpr_intptr)ev.tag);
gpr_log(GPR_DEBUG, "EVENT: success:%d, type:%d, tag:%d iter:%d",
@@ -324,8 +323,6 @@ int *perform_request(servers_fixture *f, grpc_channel *client,
}
}
- gpr_log(GPR_DEBUG, "s_idx=%d", s_idx);
-
if (s_idx >= 0) {
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
@@ -371,7 +368,7 @@ int *perform_request(servers_fixture *f, grpc_channel *client,
&rdata->call_details[s_idx],
&f->request_metadata_recv[s_idx], f->cq,
f->cq, tag(1000 + (int)s_idx)));
- } else {
+ } else { /* no response from server */
grpc_call_cancel(c, NULL);
if (!completed_client) {
cq_expect_completion(cqv, tag(1), 1);
@@ -379,6 +376,10 @@ int *perform_request(servers_fixture *f, grpc_channel *client,
}
}
+ GPR_ASSERT(grpc_completion_queue_next(f->cq,
+ GRPC_TIMEOUT_MILLIS_TO_DEADLINE(200),
+ NULL).type == GRPC_QUEUE_TIMEOUT);
+
grpc_metadata_array_destroy(&rdata->initial_metadata_recv);
grpc_metadata_array_destroy(&rdata->trailing_metadata_recv);
@@ -397,6 +398,42 @@ int *perform_request(servers_fixture *f, grpc_channel *client,
return connection_sequence;
}
+static grpc_call **perform_multirequest(servers_fixture *f,
+ grpc_channel *client,
+ size_t concurrent_calls) {
+ grpc_call **calls;
+ grpc_op ops[6];
+ grpc_op *op;
+ size_t i;
+
+ calls = gpr_malloc(sizeof(grpc_call *) * concurrent_calls);
+ for (i = 0; i < f->num_servers; i++) {
+ kill_server(f, i);
+ }
+
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op->flags = 0;
+ op->reserved = NULL;
+
+ for (i = 0; i < concurrent_calls; i++) {
+ calls[i] = grpc_channel_create_call(
+ client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq, "/foo",
+ "foo.test.google.fr", gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ GPR_ASSERT(calls[i]);
+ GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(calls[i], ops,
+ (size_t)(op - ops), tag(1),
+ NULL));
+ }
+
+ return calls;
+}
+
static void assert_channel_connectivity(
grpc_channel *ch, size_t num_accepted_conn_states,
grpc_connectivity_state accepted_conn_state, ...) {
@@ -487,8 +524,110 @@ void run_spec(const test_spec *spec) {
gpr_free(actual_connection_sequence);
gpr_free(rdata.call_details);
+ grpc_channel_destroy(client); /* calls the LB's shutdown func */
+ teardown_servers(f);
+}
+
+static grpc_channel *create_client(const servers_fixture *f) {
+ grpc_channel *client;
+ char *client_hostport;
+ char *servers_hostports_str;
+ grpc_arg arg;
+ grpc_channel_args args;
+
+ servers_hostports_str = gpr_strjoin_sep((const char **)f->servers_hostports,
+ f->num_servers, ",", NULL);
+ gpr_asprintf(&client_hostport, "ipv4:%s?lb_policy=round_robin",
+ servers_hostports_str);
+
+ arg.type = GRPC_ARG_INTEGER;
+ arg.key = "grpc.testing.fixed_reconnect_backoff";
+ arg.value.integer = 100;
+ args.num_args = 1;
+ args.args = &arg;
+
+ client = grpc_insecure_channel_create(client_hostport, &args, NULL);
+ gpr_free(client_hostport);
+ gpr_free(servers_hostports_str);
+
+ return client;
+}
+
+static void test_ping() {
+ grpc_channel *client;
+ request_data rdata;
+ servers_fixture *f;
+ cq_verifier *cqv;
+ grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
+ const size_t num_servers = 1;
+ int i;
+
+ rdata.call_details = gpr_malloc(sizeof(grpc_call_details) * num_servers);
+ f = setup_servers("127.0.0.1", &rdata, num_servers);
+ cqv = cq_verifier_create(f->cq);
+
+ client = create_client(f);
+
+ grpc_channel_ping(client, f->cq, tag(0), NULL);
+ cq_expect_completion(cqv, tag(0), 0);
+
+ /* check that we're still in idle, and start connecting */
+ GPR_ASSERT(grpc_channel_check_connectivity_state(client, 1) ==
+ GRPC_CHANNEL_IDLE);
+ /* we'll go through some set of transitions (some might be missed), until
+ READY is reached */
+ while (state != GRPC_CHANNEL_READY) {
+ grpc_channel_watch_connectivity_state(
+ client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f->cq, tag(99));
+ cq_expect_completion(cqv, tag(99), 1);
+ cq_verify(cqv);
+ state = grpc_channel_check_connectivity_state(client, 0);
+ GPR_ASSERT(state == GRPC_CHANNEL_READY ||
+ state == GRPC_CHANNEL_CONNECTING ||
+ state == GRPC_CHANNEL_TRANSIENT_FAILURE);
+ }
+
+ for (i = 1; i <= 5; i++) {
+ grpc_channel_ping(client, f->cq, tag(i), NULL);
+ cq_expect_completion(cqv, tag(i), 1);
+ cq_verify(cqv);
+ }
+ gpr_free(rdata.call_details);
+
grpc_channel_destroy(client);
teardown_servers(f);
+
+ cq_verifier_destroy(cqv);
+}
+
+static void test_pending_calls(size_t concurrent_calls) {
+ size_t i;
+ grpc_call **calls;
+ grpc_channel *client;
+ request_data rdata;
+ servers_fixture *f;
+ test_spec *spec = test_spec_create(0, 4);
+ rdata.call_details =
+ gpr_malloc(sizeof(grpc_call_details) * spec->num_servers);
+ f = setup_servers("127.0.0.1", &rdata, spec->num_servers);
+
+ client = create_client(f);
+ calls = perform_multirequest(f, client, concurrent_calls);
+ grpc_call_cancel(
+ calls[0],
+ NULL); /* exercise the cancel pick path whilst there are pending picks */
+
+ gpr_free(rdata.call_details);
+
+ grpc_channel_destroy(client); /* calls the LB's shutdown func */
+ /* destroy the calls after the channel so that they are still around for the
+ * LB's shutdown func to process */
+ for (i = 0; i < concurrent_calls; i++) {
+ grpc_call_destroy(calls[i]);
+ }
+ gpr_free(calls);
+ teardown_servers(f);
+ test_spec_destroy(spec);
}
static void print_failed_expectations(const int *expected_connection_sequence,
@@ -635,6 +774,23 @@ static void verify_partial_carnage_round_robin(
gpr_free(expected_connection_sequence);
}
+static void dump_array(const char *desc, const int *data, const size_t count) {
+ gpr_strvec s;
+ char *tmp;
+ size_t i;
+ gpr_strvec_init(&s);
+ gpr_strvec_add(&s, gpr_strdup(desc));
+ gpr_strvec_add(&s, gpr_strdup(":"));
+ for (i = 0; i < count; i++) {
+ gpr_asprintf(&tmp, " %d", data[i]);
+ gpr_strvec_add(&s, tmp);
+ }
+ tmp = gpr_strvec_flatten(&s, NULL);
+ gpr_strvec_destroy(&s);
+ gpr_log(GPR_DEBUG, "%s", tmp);
+ gpr_free(tmp);
+}
+
static void verify_rebirth_round_robin(const servers_fixture *f,
grpc_channel *client,
const int *actual_connection_sequence,
@@ -642,7 +798,10 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
int *expected_connection_sequence;
size_t i, j, unique_seq_last_idx, unique_seq_first_idx;
const size_t expected_seq_length = f->num_servers;
- uint8_t *seen_elements;
+ int *seen_elements;
+
+ dump_array("actual_connection_sequence", actual_connection_sequence,
+ num_iters);
/* verify conn. seq. expectation */
/* get the first unique run of length "num_servers". */
@@ -651,12 +810,12 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
unique_seq_last_idx = ~(size_t)0;
- memset(seen_elements, 0, sizeof(uint8_t) * expected_seq_length);
+ memset(seen_elements, 0, sizeof(int) * expected_seq_length);
for (i = 0; i < num_iters; i++) {
if (actual_connection_sequence[i] < 0 ||
seen_elements[actual_connection_sequence[i]] != 0) {
/* if anything breaks the uniqueness of the run, back to square zero */
- memset(seen_elements, 0, sizeof(uint8_t) * expected_seq_length);
+ memset(seen_elements, 0, sizeof(int) * expected_seq_length);
continue;
}
seen_elements[actual_connection_sequence[i]] = 1;
@@ -669,6 +828,7 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
}
}
/* make sure we found a valid run */
+ dump_array("seen_elements", seen_elements, expected_seq_length);
for (j = 0; j < expected_seq_length; j++) {
GPR_ASSERT(seen_elements[j] != 0);
}
@@ -715,9 +875,14 @@ int main(int argc, char **argv) {
grpc_test_init(argc, argv);
grpc_init();
+ grpc_lb_round_robin_trace = 1;
+
+ GPR_ASSERT(grpc_lb_policy_create("this-lb-policy-does-not-exist", NULL) ==
+ NULL);
+ GPR_ASSERT(grpc_lb_policy_create(NULL, NULL) == NULL);
- /* everything is fine, all servers stay up the whole time and life's peachy */
spec = test_spec_create(NUM_ITERS, NUM_SERVERS);
+ /* everything is fine, all servers stay up the whole time and life's peachy */
spec->verifier = verify_vanilla_round_robin;
spec->description = "test_all_server_up";
run_spec(spec);
@@ -731,7 +896,8 @@ int main(int argc, char **argv) {
}
run_spec(spec);
- /* at the start of the 2nd iteration, kill all but the first and last servers.
+ /* at the start of the 2nd iteration, kill all but the first and last
+ * servers.
* This should knock down the server bound to be selected next */
test_spec_reset(spec);
spec->verifier = verify_vanishing_floor_round_robin;
@@ -760,9 +926,11 @@ int main(int argc, char **argv) {
spec->revive_at[3][i] = 1;
}
run_spec(spec);
-
test_spec_destroy(spec);
+ test_pending_calls(4);
+ test_ping();
+
grpc_shutdown();
return 0;
}
diff --git a/test/core/client_config/resolvers/dns_resolver_test.c b/test/core/client_config/resolvers/dns_resolver_test.c
new file mode 100644
index 0000000000..38e76d5342
--- /dev/null
+++ b/test/core/client_config/resolvers/dns_resolver_test.c
@@ -0,0 +1,106 @@
+/*
+ *
+ * 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/client_config/resolvers/dns_resolver.h"
+
+#include <string.h>
+
+#include <grpc/support/log.h>
+
+#include "src/core/client_config/resolver.h"
+#include "test/core/util/test_config.h"
+
+static void subchannel_factory_ref(grpc_subchannel_factory *scv) {}
+static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
+ grpc_subchannel_factory *scv) {}
+static grpc_subchannel *subchannel_factory_create_subchannel(
+ grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory,
+ grpc_subchannel_args *args) {
+ GPR_UNREACHABLE_CODE(return NULL);
+}
+
+static const grpc_subchannel_factory_vtable sc_vtable = {
+ subchannel_factory_ref, subchannel_factory_unref,
+ subchannel_factory_create_subchannel};
+
+static grpc_subchannel_factory sc_factory = {&sc_vtable};
+
+static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_uri *uri = grpc_uri_parse(string, 0);
+ grpc_resolver_args args;
+ grpc_resolver *resolver;
+ gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string,
+ factory->vtable->scheme);
+ GPR_ASSERT(uri);
+ memset(&args, 0, sizeof(args));
+ args.uri = uri;
+ args.subchannel_factory = &sc_factory;
+ resolver = grpc_resolver_factory_create_resolver(factory, &args);
+ GPR_ASSERT(resolver != NULL);
+ GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds");
+ grpc_uri_destroy(uri);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void test_fails(grpc_resolver_factory *factory, const char *string) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_uri *uri = grpc_uri_parse(string, 0);
+ grpc_resolver_args args;
+ grpc_resolver *resolver;
+ gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string,
+ factory->vtable->scheme);
+ GPR_ASSERT(uri);
+ memset(&args, 0, sizeof(args));
+ args.uri = uri;
+ resolver = grpc_resolver_factory_create_resolver(factory, &args);
+ GPR_ASSERT(resolver == NULL);
+ grpc_uri_destroy(uri);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+int main(int argc, char **argv) {
+ grpc_resolver_factory *dns;
+ grpc_test_init(argc, argv);
+
+ dns = grpc_dns_resolver_factory_create();
+
+ test_succeeds(dns, "dns:10.2.1.1");
+ test_succeeds(dns, "dns:10.2.1.1:1234");
+ test_succeeds(dns, "ipv4:www.google.com");
+ test_fails(dns, "ipv4://8.8.8.8/8.8.8.8:8888");
+
+ grpc_resolver_factory_unref(dns);
+
+ return 0;
+}
diff --git a/test/core/client_config/resolvers/sockaddr_resolver_test.c b/test/core/client_config/resolvers/sockaddr_resolver_test.c
new file mode 100644
index 0000000000..8856c85449
--- /dev/null
+++ b/test/core/client_config/resolvers/sockaddr_resolver_test.c
@@ -0,0 +1,116 @@
+/*
+ *
+ * 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/client_config/resolvers/sockaddr_resolver.h"
+
+#include <string.h>
+
+#include <grpc/support/log.h>
+
+#include "src/core/client_config/resolver.h"
+#include "test/core/util/test_config.h"
+
+static void subchannel_factory_ref(grpc_subchannel_factory *scv) {}
+static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
+ grpc_subchannel_factory *scv) {}
+static grpc_subchannel *subchannel_factory_create_subchannel(
+ grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory,
+ grpc_subchannel_args *args) {
+ GPR_UNREACHABLE_CODE(return NULL);
+}
+
+static const grpc_subchannel_factory_vtable sc_vtable = {
+ subchannel_factory_ref, subchannel_factory_unref,
+ subchannel_factory_create_subchannel};
+
+static grpc_subchannel_factory sc_factory = {&sc_vtable};
+
+static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_uri *uri = grpc_uri_parse(string, 0);
+ grpc_resolver_args args;
+ grpc_resolver *resolver;
+ gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string,
+ factory->vtable->scheme);
+ GPR_ASSERT(uri);
+ memset(&args, 0, sizeof(args));
+ args.uri = uri;
+ args.subchannel_factory = &sc_factory;
+ resolver = grpc_resolver_factory_create_resolver(factory, &args);
+ GPR_ASSERT(resolver != NULL);
+ GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds");
+ grpc_uri_destroy(uri);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void test_fails(grpc_resolver_factory *factory, const char *string) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_uri *uri = grpc_uri_parse(string, 0);
+ grpc_resolver_args args;
+ grpc_resolver *resolver;
+ gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string,
+ factory->vtable->scheme);
+ GPR_ASSERT(uri);
+ memset(&args, 0, sizeof(args));
+ args.uri = uri;
+ resolver = grpc_resolver_factory_create_resolver(factory, &args);
+ GPR_ASSERT(resolver == NULL);
+ grpc_uri_destroy(uri);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+int main(int argc, char **argv) {
+ grpc_resolver_factory *ipv4, *ipv6;
+ grpc_test_init(argc, argv);
+
+ ipv4 = grpc_ipv4_resolver_factory_create();
+ ipv6 = grpc_ipv6_resolver_factory_create();
+
+ test_fails(ipv4, "ipv4:10.2.1.1");
+ test_succeeds(ipv4, "ipv4:10.2.1.1:1234");
+ test_fails(ipv4, "ipv4:10.2.1.1:123456");
+ test_fails(ipv4, "ipv4:www.google.com");
+ test_fails(ipv4, "ipv4:[");
+ test_fails(ipv4, "ipv4://8.8.8.8/8.8.8.8:8888");
+
+ test_fails(ipv6, "ipv6:[");
+ test_fails(ipv6, "ipv6:[::]");
+ test_succeeds(ipv6, "ipv6:[::]:1234");
+ test_fails(ipv6, "ipv6:[::]:123456");
+ test_fails(ipv6, "ipv6:www.google.com");
+
+ grpc_resolver_factory_unref(ipv4);
+ grpc_resolver_factory_unref(ipv6);
+
+ return 0;
+}
diff --git a/test/core/client_config/set_initial_connect_string_test.c b/test/core/client_config/set_initial_connect_string_test.c
index 13517b7c1f..ceca56c833 100644
--- a/test/core/client_config/set_initial_connect_string_test.c
+++ b/test/core/client_config/set_initial_connect_string_test.c
@@ -66,15 +66,15 @@ static grpc_closure on_read;
static void handle_read(grpc_exec_ctx *exec_ctx, void *arg, int success) {
GPR_ASSERT(success);
- gpr_slice_buffer_move_into(
- &state.temp_incoming_buffer, &state.incoming_buffer);
+ gpr_slice_buffer_move_into(&state.temp_incoming_buffer,
+ &state.incoming_buffer);
if (state.incoming_buffer.length > strlen(magic_connect_string)) {
state.done = 1;
grpc_endpoint_shutdown(exec_ctx, state.tcp);
grpc_endpoint_destroy(exec_ctx, state.tcp);
} else {
- grpc_endpoint_read(
- exec_ctx, state.tcp, &state.temp_incoming_buffer, &on_read);
+ grpc_endpoint_read(exec_ctx, state.tcp, &state.temp_incoming_buffer,
+ &on_read);
}
}
diff --git a/test/core/compression/algorithm_test.c b/test/core/compression/algorithm_test.c
new file mode 100644
index 0000000000..7de7e11a94
--- /dev/null
+++ b/test/core/compression/algorithm_test.c
@@ -0,0 +1,104 @@
+/*
+ *
+ * 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/compression/algorithm_metadata.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/transport/static_metadata.h"
+#include "test/core/util/test_config.h"
+
+static void test_algorithm_mesh(void) {
+ int i;
+
+ gpr_log(GPR_DEBUG, "test_algorithm_mesh");
+
+ for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
+ char *name;
+ grpc_compression_algorithm parsed;
+ grpc_mdstr *mdstr;
+ grpc_mdelem *mdelem;
+ GPR_ASSERT(
+ grpc_compression_algorithm_name((grpc_compression_algorithm)i, &name));
+ GPR_ASSERT(grpc_compression_algorithm_parse(name, strlen(name), &parsed));
+ GPR_ASSERT((int)parsed == i);
+ mdstr = grpc_mdstr_from_string(name);
+ GPR_ASSERT(mdstr == grpc_compression_algorithm_mdstr(parsed));
+ GPR_ASSERT(parsed == grpc_compression_algorithm_from_mdstr(mdstr));
+ mdelem = grpc_compression_encoding_mdelem(parsed);
+ GPR_ASSERT(mdelem->value == mdstr);
+ GPR_ASSERT(mdelem->key == GRPC_MDSTR_GRPC_ENCODING);
+ GRPC_MDSTR_UNREF(mdstr);
+ GRPC_MDELEM_UNREF(mdelem);
+ }
+
+ /* test failure */
+ GPR_ASSERT(NULL ==
+ grpc_compression_encoding_mdelem(GRPC_COMPRESS_ALGORITHMS_COUNT));
+}
+
+static void test_algorithm_failure(void) {
+ grpc_mdstr *mdstr;
+
+ gpr_log(GPR_DEBUG, "test_algorithm_failure");
+
+ GPR_ASSERT(grpc_compression_algorithm_name(GRPC_COMPRESS_ALGORITHMS_COUNT,
+ NULL) == 0);
+ GPR_ASSERT(grpc_compression_algorithm_name(GRPC_COMPRESS_ALGORITHMS_COUNT + 1,
+ NULL) == 0);
+ mdstr = grpc_mdstr_from_string("this-is-an-invalid-algorithm");
+ GPR_ASSERT(grpc_compression_algorithm_from_mdstr(mdstr) ==
+ GRPC_COMPRESS_ALGORITHMS_COUNT);
+ GPR_ASSERT(grpc_compression_algorithm_mdstr(GRPC_COMPRESS_ALGORITHMS_COUNT) ==
+ NULL);
+ GPR_ASSERT(grpc_compression_algorithm_mdstr(GRPC_COMPRESS_ALGORITHMS_COUNT +
+ 1) == NULL);
+ GRPC_MDSTR_UNREF(mdstr);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+
+ test_algorithm_mesh();
+ test_algorithm_failure();
+
+ grpc_shutdown();
+
+ return 0;
+}
diff --git a/test/core/compression/compression_test.c b/test/core/compression/compression_test.c
index 633fbd97f4..26d7b2b6cc 100644
--- a/test/core/compression/compression_test.c
+++ b/test/core/compression/compression_test.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <grpc/compression.h>
+#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
@@ -52,9 +53,8 @@ static void test_compression_algorithm_parse(void) {
for (i = 0; i < GPR_ARRAY_SIZE(valid_names); i++) {
const char *valid_name = valid_names[i];
grpc_compression_algorithm algorithm;
- int success;
- success = grpc_compression_algorithm_parse(valid_name, strlen(valid_name),
- &algorithm);
+ const int success = grpc_compression_algorithm_parse(
+ valid_name, strlen(valid_name), &algorithm);
GPR_ASSERT(success != 0);
GPR_ASSERT(algorithm == valid_algorithms[i]);
}
@@ -70,8 +70,80 @@ static void test_compression_algorithm_parse(void) {
}
}
+static void test_compression_algorithm_name(void) {
+ int success;
+ char *name;
+ size_t i;
+ const char *valid_names[] = {"identity", "gzip", "deflate"};
+ const grpc_compression_algorithm valid_algorithms[] = {
+ GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_DEFLATE};
+
+ gpr_log(GPR_DEBUG, "test_compression_algorithm_name");
+
+ for (i = 0; i < GPR_ARRAY_SIZE(valid_algorithms); i++) {
+ success = grpc_compression_algorithm_name(valid_algorithms[i], &name);
+ GPR_ASSERT(success != 0);
+ GPR_ASSERT(strcmp(name, valid_names[i]) == 0);
+ }
+
+ success =
+ grpc_compression_algorithm_name(GRPC_COMPRESS_ALGORITHMS_COUNT, &name);
+ GPR_ASSERT(success == 0);
+ /* the value of "name" is undefined upon failure */
+}
+
+static void test_compression_algorithm_for_level(void) {
+ size_t i;
+ grpc_compression_level levels[] = {
+ GRPC_COMPRESS_LEVEL_NONE, GRPC_COMPRESS_LEVEL_LOW,
+ GRPC_COMPRESS_LEVEL_MED, GRPC_COMPRESS_LEVEL_HIGH};
+ grpc_compression_algorithm algorithms[] = {
+ GRPC_COMPRESS_NONE, GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_DEFLATE,
+ GRPC_COMPRESS_DEFLATE};
+ gpr_log(GPR_DEBUG, "test_compression_algorithm_for_level");
+
+ for (i = 0; i < GPR_ARRAY_SIZE(levels); i++) {
+ GPR_ASSERT(algorithms[i] ==
+ grpc_compression_algorithm_for_level(levels[i]));
+ }
+}
+
+static void test_compression_enable_disable_algorithm(void) {
+ grpc_compression_options options;
+ grpc_compression_algorithm algorithm;
+
+ gpr_log(GPR_DEBUG, "test_compression_enable_disable_algorithm");
+
+ grpc_compression_options_init(&options);
+ for (algorithm = GRPC_COMPRESS_NONE;
+ algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT; algorithm++) {
+ /* all algorithms are enabled by default */
+ GPR_ASSERT(grpc_compression_options_is_algorithm_enabled(&options,
+ algorithm) != 0);
+ }
+ /* disable one by one */
+ for (algorithm = GRPC_COMPRESS_NONE;
+ algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT; algorithm++) {
+ grpc_compression_options_disable_algorithm(&options, algorithm);
+ GPR_ASSERT(grpc_compression_options_is_algorithm_enabled(&options,
+ algorithm) == 0);
+ }
+ /* re-enable one by one */
+ for (algorithm = GRPC_COMPRESS_NONE;
+ algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT; algorithm++) {
+ grpc_compression_options_enable_algorithm(&options, algorithm);
+ GPR_ASSERT(grpc_compression_options_is_algorithm_enabled(&options,
+ algorithm) != 0);
+ }
+}
+
int main(int argc, char **argv) {
+ grpc_init();
test_compression_algorithm_parse();
+ test_compression_algorithm_name();
+ test_compression_algorithm_for_level();
+ test_compression_enable_disable_algorithm();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index 98da6a1eaa..e5a01ef69e 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -36,11 +36,13 @@
#include <stdlib.h>
#include <string.h>
-#include "test/core/util/test_config.h"
-#include "src/core/support/murmur_hash.h"
+#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
+
+#include "src/core/support/murmur_hash.h"
#include "test/core/util/slice_splitter.h"
+#include "test/core/util/test_config.h"
typedef enum { ONE_A = 0, ONE_KB_A, ONE_MB_A, TEST_VALUE_COUNT } test_value;
@@ -146,26 +148,130 @@ static gpr_slice create_test_value(test_value id) {
return gpr_slice_from_copied_string("bad value");
}
-static void test_bad_data(void) {
+static void test_tiny_data_compress(void) {
gpr_slice_buffer input;
gpr_slice_buffer output;
grpc_compression_algorithm i;
gpr_slice_buffer_init(&input);
gpr_slice_buffer_init(&output);
- gpr_slice_buffer_add(&input, gpr_slice_from_copied_string(
- "this is not valid compressed input"));
+ gpr_slice_buffer_add(&input, create_test_value(ONE_A));
for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
if (i == GRPC_COMPRESS_NONE) continue;
- GPR_ASSERT(0 == grpc_msg_decompress(i, &input, &output));
- GPR_ASSERT(0 == output.count);
+ GPR_ASSERT(0 == grpc_msg_compress(i, &input, &output));
+ GPR_ASSERT(1 == output.count);
}
gpr_slice_buffer_destroy(&input);
gpr_slice_buffer_destroy(&output);
}
+static void test_bad_decompression_data_crc(void) {
+ gpr_slice_buffer input;
+ gpr_slice_buffer corrupted;
+ gpr_slice_buffer output;
+ size_t idx;
+ const gpr_uint32 bad = 0xdeadbeef;
+
+ gpr_slice_buffer_init(&input);
+ gpr_slice_buffer_init(&corrupted);
+ gpr_slice_buffer_init(&output);
+ gpr_slice_buffer_add(&input, create_test_value(ONE_MB_A));
+
+ /* compress it */
+ grpc_msg_compress(GRPC_COMPRESS_GZIP, &input, &corrupted);
+ /* corrupt the output by smashing the CRC */
+ GPR_ASSERT(corrupted.count > 1);
+ GPR_ASSERT(GPR_SLICE_LENGTH(corrupted.slices[1]) > 8);
+ idx = GPR_SLICE_LENGTH(corrupted.slices[1]) - 8;
+ memcpy(GPR_SLICE_START_PTR(corrupted.slices[1]) + idx, &bad, 4);
+
+ /* try (and fail) to decompress the corrupted compresed buffer */
+ GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_GZIP, &corrupted, &output));
+
+ gpr_slice_buffer_destroy(&input);
+ gpr_slice_buffer_destroy(&corrupted);
+ gpr_slice_buffer_destroy(&output);
+}
+
+static void test_bad_decompression_data_trailing_garbage(void) {
+ gpr_slice_buffer input;
+ gpr_slice_buffer output;
+
+ gpr_slice_buffer_init(&input);
+ gpr_slice_buffer_init(&output);
+ /* append 0x99 to the end of an otherwise valid stream */
+ gpr_slice_buffer_add(
+ &input, gpr_slice_from_copied_buffer(
+ "\x78\xda\x63\x60\x60\x60\x00\x00\x00\x04\x00\x01\x99", 13));
+
+ /* try (and fail) to decompress the invalid compresed buffer */
+ GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
+
+ gpr_slice_buffer_destroy(&input);
+ gpr_slice_buffer_destroy(&output);
+}
+
+static void test_bad_decompression_data_stream(void) {
+ gpr_slice_buffer input;
+ gpr_slice_buffer output;
+
+ gpr_slice_buffer_init(&input);
+ gpr_slice_buffer_init(&output);
+ gpr_slice_buffer_add(&input,
+ gpr_slice_from_copied_buffer("\x78\xda\xff\xff", 4));
+
+ /* try (and fail) to decompress the invalid compresed buffer */
+ GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
+
+ gpr_slice_buffer_destroy(&input);
+ gpr_slice_buffer_destroy(&output);
+}
+
+static void test_bad_compression_algorithm(void) {
+ gpr_slice_buffer input;
+ gpr_slice_buffer output;
+ int was_compressed;
+
+ gpr_slice_buffer_init(&input);
+ gpr_slice_buffer_init(&output);
+ gpr_slice_buffer_add(&input,
+ gpr_slice_from_copied_string("Never gonna give you up"));
+ was_compressed =
+ grpc_msg_compress(GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
+ GPR_ASSERT(0 == was_compressed);
+
+ was_compressed =
+ grpc_msg_compress(GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
+ GPR_ASSERT(0 == was_compressed);
+
+ gpr_slice_buffer_destroy(&input);
+ gpr_slice_buffer_destroy(&output);
+}
+
+static void test_bad_decompression_algorithm(void) {
+ gpr_slice_buffer input;
+ gpr_slice_buffer output;
+ int was_decompressed;
+
+ gpr_slice_buffer_init(&input);
+ gpr_slice_buffer_init(&output);
+ gpr_slice_buffer_add(&input,
+ gpr_slice_from_copied_string(
+ "I'm not really compressed but it doesn't matter"));
+ was_decompressed =
+ grpc_msg_decompress(GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
+ GPR_ASSERT(0 == was_decompressed);
+
+ was_decompressed = grpc_msg_decompress(GRPC_COMPRESS_ALGORITHMS_COUNT + 123,
+ &input, &output);
+ GPR_ASSERT(0 == was_decompressed);
+
+ gpr_slice_buffer_destroy(&input);
+ gpr_slice_buffer_destroy(&output);
+}
+
int main(int argc, char **argv) {
unsigned i, j, k, m;
grpc_slice_split_mode uncompressed_split_modes[] = {
@@ -175,6 +281,7 @@ int main(int argc, char **argv) {
GRPC_SLICE_SPLIT_ONE_BYTE};
grpc_test_init(argc, argv);
+ grpc_init();
for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
for (j = 0; j < GPR_ARRAY_SIZE(uncompressed_split_modes); j++) {
@@ -188,7 +295,13 @@ int main(int argc, char **argv) {
}
}
- test_bad_data();
+ test_tiny_data_compress();
+ test_bad_decompression_data_crc();
+ test_bad_decompression_data_stream();
+ test_bad_decompression_data_trailing_garbage();
+ test_bad_compression_algorithm();
+ test_bad_decompression_algorithm();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c
new file mode 100644
index 0000000000..90f3713cc8
--- /dev/null
+++ b/test/core/end2end/fixtures/h2_census.c
@@ -0,0 +1,132 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <string.h>
+
+#include "src/core/channel/channel_args.h"
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+typedef struct fullstack_fixture_data {
+ char *localaddr;
+} fullstack_fixture_data;
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
+ grpc_channel_args *client_args, grpc_channel_args *server_args) {
+ grpc_end2end_test_fixture f;
+ int port = grpc_pick_unused_port_or_die();
+ fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data));
+ memset(&f, 0, sizeof(f));
+
+ gpr_join_host_port(&ffd->localaddr, "localhost", port);
+
+ f.fixture_data = ffd;
+ f.cq = grpc_completion_queue_create(NULL);
+
+ return f;
+}
+
+static grpc_arg make_census_enable_arg(void) {
+ grpc_arg arg;
+ arg.type = GRPC_ARG_INTEGER;
+ arg.key = GRPC_ARG_ENABLE_CENSUS;
+ arg.value.integer = 1;
+ return arg;
+}
+
+void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
+ grpc_channel_args *client_args) {
+ fullstack_fixture_data *ffd = f->fixture_data;
+ grpc_arg arg = make_census_enable_arg();
+ client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1);
+ f->client = grpc_insecure_channel_create(ffd->localaddr, client_args, NULL);
+ grpc_channel_args_destroy(client_args);
+ GPR_ASSERT(f->client);
+}
+
+void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
+ grpc_channel_args *server_args) {
+ fullstack_fixture_data *ffd = f->fixture_data;
+ grpc_arg arg = make_census_enable_arg();
+ if (f->server) {
+ grpc_server_destroy(f->server);
+ }
+ server_args = grpc_channel_args_copy_and_add(server_args, &arg, 1);
+ f->server = grpc_server_create(server_args, NULL);
+ grpc_channel_args_destroy(server_args);
+ grpc_server_register_completion_queue(f->server, f->cq, NULL);
+ GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
+ grpc_server_start(f->server);
+}
+
+void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) {
+ fullstack_fixture_data *ffd = f->fixture_data;
+ gpr_free(ffd->localaddr);
+ gpr_free(ffd);
+}
+
+/* All test configurations */
+static grpc_end2end_test_config configs[] = {
+ {"chttp2/fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
+ chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
+};
+
+int main(int argc, char **argv) {
+ size_t i;
+
+ grpc_test_init(argc, argv);
+ grpc_init();
+
+ for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+ grpc_end2end_tests(configs[i]);
+ }
+
+ grpc_shutdown();
+
+ return 0;
+}
diff --git a/test/core/end2end/fixtures/h2_full+pipe.c b/test/core/end2end/fixtures/h2_full+pipe.c
new file mode 100644
index 0000000000..83cde49305
--- /dev/null
+++ b/test/core/end2end/fixtures/h2_full+pipe.c
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <string.h>
+
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "src/core/iomgr/wakeup_fd_posix.h"
+
+typedef struct fullstack_fixture_data {
+ char *localaddr;
+} fullstack_fixture_data;
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
+ grpc_channel_args *client_args, grpc_channel_args *server_args) {
+ grpc_end2end_test_fixture f;
+ int port = grpc_pick_unused_port_or_die();
+ fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data));
+ memset(&f, 0, sizeof(f));
+
+ gpr_join_host_port(&ffd->localaddr, "localhost", port);
+
+ f.fixture_data = ffd;
+ f.cq = grpc_completion_queue_create(NULL);
+
+ return f;
+}
+
+void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
+ grpc_channel_args *client_args) {
+ fullstack_fixture_data *ffd = f->fixture_data;
+ f->client = grpc_insecure_channel_create(ffd->localaddr, client_args, NULL);
+ GPR_ASSERT(f->client);
+}
+
+void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
+ grpc_channel_args *server_args) {
+ fullstack_fixture_data *ffd = f->fixture_data;
+ if (f->server) {
+ grpc_server_destroy(f->server);
+ }
+ f->server = grpc_server_create(server_args, NULL);
+ grpc_server_register_completion_queue(f->server, f->cq, NULL);
+ GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
+ grpc_server_start(f->server);
+}
+
+void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) {
+ fullstack_fixture_data *ffd = f->fixture_data;
+ gpr_free(ffd->localaddr);
+ gpr_free(ffd);
+}
+
+/* All test configurations */
+static grpc_end2end_test_config configs[] = {
+ {"chttp2/fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
+ chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
+};
+
+int main(int argc, char **argv) {
+ size_t i;
+
+ grpc_allow_specialized_wakeup_fd = 0;
+
+ grpc_test_init(argc, argv);
+ grpc_init();
+
+ for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+ grpc_end2end_tests(configs[i]);
+ }
+
+ grpc_shutdown();
+
+ return 0;
+}
diff --git a/test/core/end2end/fixtures/h2_full+poll+pipe.c b/test/core/end2end/fixtures/h2_full+poll+pipe.c
new file mode 100644
index 0000000000..ffae11f90d
--- /dev/null
+++ b/test/core/end2end/fixtures/h2_full+poll+pipe.c
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <string.h>
+
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "src/core/iomgr/wakeup_fd_posix.h"
+
+typedef struct fullstack_fixture_data {
+ char *localaddr;
+} fullstack_fixture_data;
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
+ grpc_channel_args *client_args, grpc_channel_args *server_args) {
+ grpc_end2end_test_fixture f;
+ int port = grpc_pick_unused_port_or_die();
+ fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data));
+ memset(&f, 0, sizeof(f));
+
+ gpr_join_host_port(&ffd->localaddr, "localhost", port);
+
+ f.fixture_data = ffd;
+ f.cq = grpc_completion_queue_create(NULL);
+
+ return f;
+}
+
+void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
+ grpc_channel_args *client_args) {
+ fullstack_fixture_data *ffd = f->fixture_data;
+ f->client = grpc_insecure_channel_create(ffd->localaddr, client_args, NULL);
+}
+
+void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
+ grpc_channel_args *server_args) {
+ fullstack_fixture_data *ffd = f->fixture_data;
+ if (f->server) {
+ grpc_server_destroy(f->server);
+ }
+ f->server = grpc_server_create(server_args, NULL);
+ grpc_server_register_completion_queue(f->server, f->cq, NULL);
+ GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
+ grpc_server_start(f->server);
+}
+
+void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) {
+ fullstack_fixture_data *ffd = f->fixture_data;
+ gpr_free(ffd->localaddr);
+ gpr_free(ffd);
+}
+
+/* All test configurations */
+static grpc_end2end_test_config configs[] = {
+ {"chttp2/fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
+ chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
+};
+
+int main(int argc, char **argv) {
+ size_t i;
+
+ grpc_allow_specialized_wakeup_fd = 0;
+ grpc_platform_become_multipoller = grpc_poll_become_multipoller;
+
+ grpc_test_init(argc, argv);
+ grpc_init();
+
+ for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+ grpc_end2end_tests(configs[i]);
+ }
+
+ grpc_shutdown();
+
+ return 0;
+}
diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c
index 1f5051f0ab..ccc8631d94 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.c
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.c
@@ -57,14 +57,13 @@
/* chttp2 transport that is immediately available (used for testing
connected_channel without a client_channel */
-static void server_setup_transport(void *ts, grpc_transport *transport,
- grpc_mdctx *mdctx) {
+static void server_setup_transport(void *ts, grpc_transport *transport) {
grpc_end2end_test_fixture *f = ts;
static grpc_channel_filter const *extra_filters[] = {
&grpc_http_server_filter};
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_server_setup_transport(&exec_ctx, f->server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx,
+ GPR_ARRAY_SIZE(extra_filters),
grpc_server_get_channel_args(f->server));
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -75,17 +74,15 @@ typedef struct {
} sp_client_setup;
static void client_setup_transport(grpc_exec_ctx *exec_ctx, void *ts,
- grpc_transport *transport,
- grpc_mdctx *mdctx) {
+ grpc_transport *transport) {
sp_client_setup *cs = ts;
const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
&grpc_compress_filter,
&grpc_connected_channel_filter};
size_t nfilters = sizeof(filters) / sizeof(*filters);
- grpc_channel *channel =
- grpc_channel_create_from_filters(exec_ctx, "socketpair-target", filters,
- nfilters, cs->client_args, mdctx, 1);
+ grpc_channel *channel = grpc_channel_create_from_filters(
+ exec_ctx, "socketpair-target", filters, nfilters, cs->client_args, 1);
cs->f->client = channel;
@@ -112,13 +109,12 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f,
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
grpc_transport *transport;
- grpc_mdctx *mdctx = grpc_mdctx_create();
sp_client_setup cs;
cs.client_args = client_args;
cs.f = f;
- transport = grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client,
- mdctx, 1);
- client_setup_transport(&exec_ctx, &cs, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1);
+ client_setup_transport(&exec_ctx, &cs, transport);
GPR_ASSERT(f->client);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
@@ -128,15 +124,14 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
- grpc_mdctx *mdctx = grpc_mdctx_create();
grpc_transport *transport;
GPR_ASSERT(!f->server);
f->server = grpc_server_create_from_filters(NULL, 0, server_args);
grpc_server_register_completion_queue(f->server, f->cq, NULL);
grpc_server_start(f->server);
- transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server,
- mdctx, 0);
- server_setup_transport(f, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0);
+ server_setup_transport(f, transport);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
}
diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c
index b61fe98610..a6a84c9b1a 100644
--- a/test/core/end2end/fixtures/h2_sockpair.c
+++ b/test/core/end2end/fixtures/h2_sockpair.c
@@ -56,14 +56,13 @@
/* chttp2 transport that is immediately available (used for testing
connected_channel without a client_channel */
-static void server_setup_transport(void *ts, grpc_transport *transport,
- grpc_mdctx *mdctx) {
+static void server_setup_transport(void *ts, grpc_transport *transport) {
grpc_end2end_test_fixture *f = ts;
static grpc_channel_filter const *extra_filters[] = {
&grpc_http_server_filter};
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_server_setup_transport(&exec_ctx, f->server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx,
+ GPR_ARRAY_SIZE(extra_filters),
grpc_server_get_channel_args(f->server));
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -74,17 +73,15 @@ typedef struct {
} sp_client_setup;
static void client_setup_transport(grpc_exec_ctx *exec_ctx, void *ts,
- grpc_transport *transport,
- grpc_mdctx *mdctx) {
+ grpc_transport *transport) {
sp_client_setup *cs = ts;
const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
&grpc_compress_filter,
&grpc_connected_channel_filter};
size_t nfilters = sizeof(filters) / sizeof(*filters);
- grpc_channel *channel =
- grpc_channel_create_from_filters(exec_ctx, "socketpair-target", filters,
- nfilters, cs->client_args, mdctx, 1);
+ grpc_channel *channel = grpc_channel_create_from_filters(
+ exec_ctx, "socketpair-target", filters, nfilters, cs->client_args, 1);
cs->f->client = channel;
@@ -111,13 +108,12 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f,
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
grpc_transport *transport;
- grpc_mdctx *mdctx = grpc_mdctx_create();
sp_client_setup cs;
cs.client_args = client_args;
cs.f = f;
- transport = grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client,
- mdctx, 1);
- client_setup_transport(&exec_ctx, &cs, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1);
+ client_setup_transport(&exec_ctx, &cs, transport);
GPR_ASSERT(f->client);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
@@ -127,15 +123,14 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
- grpc_mdctx *mdctx = grpc_mdctx_create();
grpc_transport *transport;
GPR_ASSERT(!f->server);
f->server = grpc_server_create_from_filters(NULL, 0, server_args);
grpc_server_register_completion_queue(f->server, f->cq, NULL);
grpc_server_start(f->server);
- transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server,
- mdctx, 0);
- server_setup_transport(f, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0);
+ server_setup_transport(f, transport);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
}
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c
index 9f0fd2ea9a..4b8f9054ef 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.c
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c
@@ -56,14 +56,13 @@
/* chttp2 transport that is immediately available (used for testing
connected_channel without a client_channel */
-static void server_setup_transport(void *ts, grpc_transport *transport,
- grpc_mdctx *mdctx) {
+static void server_setup_transport(void *ts, grpc_transport *transport) {
grpc_end2end_test_fixture *f = ts;
static grpc_channel_filter const *extra_filters[] = {
&grpc_http_server_filter};
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_server_setup_transport(&exec_ctx, f->server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx,
+ GPR_ARRAY_SIZE(extra_filters),
grpc_server_get_channel_args(f->server));
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -74,17 +73,15 @@ typedef struct {
} sp_client_setup;
static void client_setup_transport(grpc_exec_ctx *exec_ctx, void *ts,
- grpc_transport *transport,
- grpc_mdctx *mdctx) {
+ grpc_transport *transport) {
sp_client_setup *cs = ts;
const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
&grpc_compress_filter,
&grpc_connected_channel_filter};
size_t nfilters = sizeof(filters) / sizeof(*filters);
- grpc_channel *channel =
- grpc_channel_create_from_filters(exec_ctx, "socketpair-target", filters,
- nfilters, cs->client_args, mdctx, 1);
+ grpc_channel *channel = grpc_channel_create_from_filters(
+ exec_ctx, "socketpair-target", filters, nfilters, cs->client_args, 1);
cs->f->client = channel;
@@ -111,13 +108,12 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f,
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
grpc_transport *transport;
- grpc_mdctx *mdctx = grpc_mdctx_create();
sp_client_setup cs;
cs.client_args = client_args;
cs.f = f;
- transport = grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client,
- mdctx, 1);
- client_setup_transport(&exec_ctx, &cs, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1);
+ client_setup_transport(&exec_ctx, &cs, transport);
GPR_ASSERT(f->client);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
@@ -127,15 +123,14 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
- grpc_mdctx *mdctx = grpc_mdctx_create();
grpc_transport *transport;
GPR_ASSERT(!f->server);
f->server = grpc_server_create_from_filters(NULL, 0, server_args);
grpc_server_register_completion_queue(f->server, f->cq, NULL);
grpc_server_start(f->server);
- transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server,
- mdctx, 0);
- server_setup_transport(f, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0);
+ server_setup_transport(f, transport);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
}
diff --git a/test/core/end2end/fixtures/h2_uchannel.c b/test/core/end2end/fixtures/h2_uchannel.c
index d1f9d38b82..ea630c3275 100644
--- a/test/core/end2end/fixtures/h2_uchannel.c
+++ b/test/core/end2end/fixtures/h2_uchannel.c
@@ -66,8 +66,6 @@ typedef struct {
grpc_endpoint *tcp;
- grpc_mdctx *mdctx;
-
grpc_closure connected;
} connector;
@@ -79,7 +77,6 @@ static void connector_ref(grpc_connector *con) {
static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
connector *c = (connector *)con;
if (gpr_unref(&c->refs)) {
- grpc_mdctx_unref(c->mdctx);
gpr_free(c);
}
}
@@ -89,8 +86,8 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, int success) {
grpc_closure *notify;
grpc_endpoint *tcp = c->tcp;
if (tcp != NULL) {
- c->result->transport = grpc_create_chttp2_transport(
- exec_ctx, c->args.channel_args, tcp, c->mdctx, 1);
+ c->result->transport =
+ grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1);
grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL,
0);
GPR_ASSERT(c->result->transport);
@@ -130,7 +127,6 @@ static const grpc_connector_vtable connector_vtable = {
typedef struct {
grpc_subchannel_factory base;
gpr_refcount refs;
- grpc_mdctx *mdctx;
grpc_channel_args *merge_args;
grpc_channel *master;
grpc_subchannel **sniffed_subchannel;
@@ -147,7 +143,6 @@ static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
if (gpr_unref(&f->refs)) {
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
grpc_channel_args_destroy(f->merge_args);
- grpc_mdctx_unref(f->mdctx);
gpr_free(f);
}
}
@@ -162,16 +157,16 @@ static grpc_subchannel *subchannel_factory_create_subchannel(
grpc_subchannel *s;
memset(c, 0, sizeof(*c));
c->base.vtable = &connector_vtable;
- c->mdctx = f->mdctx;
- grpc_mdctx_ref(c->mdctx);
gpr_ref_init(&c->refs, 1);
- args->mdctx = f->mdctx;
args->args = final_args;
- args->master = f->master;
s = grpc_subchannel_create(&c->base, args);
grpc_connector_unref(exec_ctx, &c->base);
grpc_channel_args_destroy(final_args);
+ if (*f->sniffed_subchannel) {
+ GRPC_SUBCHANNEL_UNREF(exec_ctx, *f->sniffed_subchannel, "sniffed");
+ }
*f->sniffed_subchannel = s;
+ GRPC_SUBCHANNEL_REF(s, "sniffed");
return s;
}
@@ -188,22 +183,19 @@ grpc_channel *channel_create(const char *target, const grpc_channel_args *args,
const grpc_channel_filter *filters[MAX_FILTERS];
grpc_resolver *resolver;
subchannel_factory *f;
- grpc_mdctx *mdctx = grpc_mdctx_create();
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
size_t n = 0;
filters[n++] = &grpc_client_channel_filter;
GPR_ASSERT(n <= MAX_FILTERS);
- channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, n,
- args, mdctx, 1);
+ channel =
+ grpc_channel_create_from_filters(&exec_ctx, target, filters, n, args, 1);
f = gpr_malloc(sizeof(*f));
f->sniffed_subchannel = sniffed_subchannel;
f->base.vtable = &test_subchannel_factory_vtable;
gpr_ref_init(&f->refs, 1);
- grpc_mdctx_ref(mdctx);
- f->mdctx = mdctx;
f->merge_args = grpc_channel_args_copy(args);
f->master = channel;
GRPC_CHANNEL_INTERNAL_REF(f->master, "test_subchannel_factory");
@@ -235,6 +227,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_micro_fullstack(
micro_fullstack_fixture_data *ffd =
gpr_malloc(sizeof(micro_fullstack_fixture_data));
memset(&f, 0, sizeof(f));
+ memset(ffd, 0, sizeof(*ffd));
gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port);
@@ -244,10 +237,54 @@ static grpc_end2end_test_fixture chttp2_create_fixture_micro_fullstack(
return f;
}
+grpc_connectivity_state g_state = GRPC_CHANNEL_IDLE;
+grpc_pollset_set g_interested_parties;
+
+static void state_changed(grpc_exec_ctx *exec_ctx, void *arg, int success) {
+ if (g_state != GRPC_CHANNEL_READY) {
+ grpc_subchannel_notify_on_state_change(
+ exec_ctx, arg, &g_interested_parties, &g_state,
+ grpc_closure_create(state_changed, arg));
+ }
+}
+
+static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *arg, int success) {
+ grpc_pollset_destroy(arg);
+}
+
+static grpc_connected_subchannel *connect_subchannel(grpc_subchannel *c) {
+ grpc_pollset pollset;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_pollset_init(&pollset);
+ grpc_pollset_set_init(&g_interested_parties);
+ grpc_pollset_set_add_pollset(&exec_ctx, &g_interested_parties, &pollset);
+ grpc_subchannel_notify_on_state_change(&exec_ctx, c, &g_interested_parties,
+ &g_state,
+ grpc_closure_create(state_changed, c));
+ grpc_exec_ctx_flush(&exec_ctx);
+ gpr_mu_lock(GRPC_POLLSET_MU(&pollset));
+ while (g_state != GRPC_CHANNEL_READY) {
+ grpc_pollset_worker worker;
+ grpc_pollset_work(&exec_ctx, &pollset, &worker,
+ gpr_now(GPR_CLOCK_MONOTONIC),
+ GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
+ gpr_mu_unlock(GRPC_POLLSET_MU(&pollset));
+ grpc_exec_ctx_flush(&exec_ctx);
+ gpr_mu_lock(GRPC_POLLSET_MU(&pollset));
+ }
+ grpc_pollset_shutdown(&exec_ctx, &pollset,
+ grpc_closure_create(destroy_pollset, &pollset));
+ grpc_pollset_set_destroy(&g_interested_parties);
+ gpr_mu_unlock(GRPC_POLLSET_MU(&pollset));
+ grpc_exec_ctx_finish(&exec_ctx);
+ return grpc_subchannel_get_connected_subchannel(c);
+}
+
static void chttp2_init_client_micro_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args) {
micro_fullstack_fixture_data *ffd = f->fixture_data;
grpc_connectivity_state conn_state;
+ grpc_connected_subchannel *connected;
char *ipv4_localaddr;
gpr_asprintf(&ipv4_localaddr, "ipv4:%s", ffd->localaddr);
@@ -263,8 +300,10 @@ static void chttp2_init_client_micro_fullstack(grpc_end2end_test_fixture *f,
/* here sniffed_subchannel should be ready to use */
GPR_ASSERT(conn_state == GRPC_CHANNEL_IDLE);
GPR_ASSERT(ffd->sniffed_subchannel != NULL);
+
+ connected = connect_subchannel(ffd->sniffed_subchannel);
f->client = grpc_client_uchannel_create(ffd->sniffed_subchannel, client_args);
- grpc_client_uchannel_set_subchannel(f->client, ffd->sniffed_subchannel);
+ grpc_client_uchannel_set_connected_subchannel(f->client, connected);
gpr_log(GPR_INFO, "CHANNEL WRAPPING SUBCHANNEL: %p(%p)", f->client,
ffd->sniffed_subchannel);
@@ -284,18 +323,22 @@ static void chttp2_init_server_micro_fullstack(grpc_end2end_test_fixture *f,
}
static void chttp2_tear_down_micro_fullstack(grpc_end2end_test_fixture *f) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
micro_fullstack_fixture_data *ffd = f->fixture_data;
grpc_channel_destroy(ffd->master_channel);
- ffd->master_channel = NULL;
+ if (ffd->sniffed_subchannel) {
+ GRPC_SUBCHANNEL_UNREF(&exec_ctx, ffd->sniffed_subchannel, "sniffed");
+ }
gpr_free(ffd->localaddr);
gpr_free(ffd);
+ grpc_exec_ctx_finish(&exec_ctx);
}
/* All test configurations */
static grpc_end2end_test_config configs[] = {
- {"chttp2/micro_fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
- chttp2_create_fixture_micro_fullstack, chttp2_init_client_micro_fullstack,
- chttp2_init_server_micro_fullstack, chttp2_tear_down_micro_fullstack},
+ {"chttp2/micro_fullstack", 0, chttp2_create_fixture_micro_fullstack,
+ chttp2_init_client_micro_fullstack, chttp2_init_server_micro_fullstack,
+ chttp2_tear_down_micro_fullstack},
};
int main(int argc, char **argv) {
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 33687b8cd4..9f94cfe6be 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -37,8 +37,11 @@ import collections
import hashlib
-FixtureOptions = collections.namedtuple('FixtureOptions', 'fullstack includes_proxy dns_resolver secure platforms ci_mac tracing')
-default_unsecure_fixture_options = FixtureOptions(True, False, True, False, ['windows', 'linux', 'mac', 'posix'], True, False)
+FixtureOptions = collections.namedtuple(
+ 'FixtureOptions',
+ 'fullstack includes_proxy dns_resolver secure platforms ci_mac tracing')
+default_unsecure_fixture_options = FixtureOptions(
+ True, False, True, False, ['windows', 'linux', 'mac', 'posix'], True, False)
socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace(fullstack=False, dns_resolver=False)
default_secure_fixture_options = default_unsecure_fixture_options._replace(secure=True)
uds_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, platforms=['linux', 'mac', 'posix'])
@@ -47,23 +50,34 @@ uds_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=Fal
# maps fixture name to whether it requires the security library
END2END_FIXTURES = {
'h2_compress': default_unsecure_fixture_options,
+ 'h2_census': default_unsecure_fixture_options,
'h2_fakesec': default_secure_fixture_options._replace(ci_mac=False),
'h2_full': default_unsecure_fixture_options,
- 'h2_full+poll': default_unsecure_fixture_options._replace(platforms=['linux']),
+ 'h2_full+poll': default_unsecure_fixture_options._replace(
+ platforms=['linux']),
+ 'h2_full+pipe': default_unsecure_fixture_options._replace(
+ platforms=['linux']),
+ 'h2_full+poll+pipe': default_unsecure_fixture_options._replace(
+ platforms=['linux']),
'h2_oauth2': default_secure_fixture_options._replace(ci_mac=False),
- 'h2_proxy': default_unsecure_fixture_options._replace(includes_proxy=True, ci_mac=False),
- 'h2_sockpair_1byte': socketpair_unsecure_fixture_options._replace(ci_mac=False),
+ 'h2_proxy': default_unsecure_fixture_options._replace(includes_proxy=True,
+ ci_mac=False),
+ 'h2_sockpair_1byte': socketpair_unsecure_fixture_options._replace(
+ ci_mac=False),
'h2_sockpair': socketpair_unsecure_fixture_options._replace(ci_mac=False),
- 'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace(tracing=True),
+ 'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace(
+ tracing=True),
'h2_ssl': default_secure_fixture_options,
'h2_ssl+poll': default_secure_fixture_options._replace(platforms=['linux']),
- 'h2_ssl_proxy': default_secure_fixture_options._replace(includes_proxy=True, ci_mac=False),
- 'h2_uchannel': default_unsecure_fixture_options,
+ 'h2_ssl_proxy': default_secure_fixture_options._replace(includes_proxy=True,
+ ci_mac=False),
+ 'h2_uchannel': default_unsecure_fixture_options._replace(fullstack=False),
'h2_uds+poll': uds_fixture_options._replace(platforms=['linux']),
'h2_uds': uds_fixture_options,
}
-TestOptions = collections.namedtuple('TestOptions', 'needs_fullstack needs_dns proxyable flaky secure traceable')
+TestOptions = collections.namedtuple(
+ 'TestOptions', 'needs_fullstack needs_dns proxyable flaky secure traceable')
default_test_options = TestOptions(False, False, True, False, False, True)
connectivity_test_options = default_test_options._replace(needs_fullstack=True)
@@ -78,14 +92,16 @@ END2END_TESTS = {
'cancel_before_invoke': default_test_options,
'cancel_in_a_vacuum': default_test_options,
'cancel_with_status': default_test_options,
- 'census_simple_request': default_test_options,
'channel_connectivity': connectivity_test_options._replace(proxyable=False),
+ 'channel_ping': connectivity_test_options._replace(proxyable=False),
'compressed_payload': default_test_options._replace(proxyable=False),
- 'default_host': default_test_options._replace(needs_fullstack=True, needs_dns=True),
+ 'default_host': default_test_options._replace(needs_fullstack=True,
+ needs_dns=True),
'disappearing_server': connectivity_test_options,
'empty_batch': default_test_options,
'graceful_server_shutdown': default_test_options,
- 'hpack_size': default_test_options._replace(proxyable=False, traceable=False),
+ 'hpack_size': default_test_options._replace(proxyable=False,
+ traceable=False),
'high_initial_seqno': default_test_options,
'invoke_large_request': default_test_options,
'large_metadata': default_test_options,
@@ -153,12 +169,27 @@ def main():
'language': 'c',
'secure': 'check' if END2END_FIXTURES[f].secure else False,
'src': ['test/core/end2end/fixtures/%s.c' % f],
- 'platforms': [ 'linux', 'mac', 'posix' ] if f.endswith('_posix') else END2END_FIXTURES[f].platforms,
- 'deps': sec_deps if END2END_FIXTURES[f].secure else unsec_deps,
+ 'platforms': ['linux', 'mac', 'posix'] if f.endswith('_posix')
+ else END2END_FIXTURES[f].platforms,
+ 'deps': sec_deps,
'headers': ['test/core/end2end/end2end_tests.h'],
'vs_proj_dir': 'test',
- }
- for f in sorted(END2END_FIXTURES.keys())] + [
+ } for f in sorted(END2END_FIXTURES.keys())
+ ] + [
+ {
+ 'name': 'end2end_nosec_fixture_%s' % f,
+ 'build': 'private',
+ 'language': 'c',
+ 'secure': False,
+ 'src': ['test/core/end2end/fixtures/%s.c' % f],
+ 'platforms': ['linux', 'mac', 'posix'] if f.endswith('_posix')
+ else END2END_FIXTURES[f].platforms,
+ 'deps': unsec_deps,
+ 'headers': ['test/core/end2end/end2end_tests.h'],
+ 'vs_proj_dir': 'test',
+ } for f in sorted(END2END_FIXTURES.keys())
+ if not END2END_FIXTURES[f].secure
+ ] + [
{
'name': 'end2end_test_%s' % t,
'build': 'private',
@@ -167,10 +198,23 @@ def main():
'src': ['test/core/end2end/tests/%s.c' % t],
'headers': ['test/core/end2end/tests/cancel_test_helpers.h',
'test/core/end2end/end2end_tests.h'],
- 'deps': sec_deps if END2END_TESTS[t].secure else unsec_deps,
+ 'deps': sec_deps,
'vs_proj_dir': 'test',
- }
- for t in sorted(END2END_TESTS.keys())] + [
+ } for t in sorted(END2END_TESTS.keys())
+ ] + [
+ {
+ 'name': 'end2end_nosec_test_%s' % t,
+ 'build': 'private',
+ 'language': 'c',
+ 'secure': False,
+ 'src': ['test/core/end2end/tests/%s.c' % t],
+ 'headers': ['test/core/end2end/tests/cancel_test_helpers.h',
+ 'test/core/end2end/end2end_tests.h'],
+ 'deps': unsec_deps,
+ 'vs_proj_dir': 'test',
+ } for t in sorted(END2END_TESTS.keys())
+ if not END2END_TESTS[t].secure
+ ] + [
{
'name': 'end2end_certs',
'build': 'private',
@@ -182,7 +226,7 @@ def main():
],
'vs_proj_dir': 'test',
}
- ],
+ ],
'targets': [
{
'name': '%s_%s_test' % (f, t),
@@ -191,17 +235,17 @@ def main():
'src': [],
'flaky': END2END_TESTS[t].flaky,
'platforms': END2END_FIXTURES[f].platforms,
- 'ci_platforms': (END2END_FIXTURES[f].platforms
- if END2END_FIXTURES[f].ci_mac
- else without(END2END_FIXTURES[f].platforms, 'mac')),
+ 'ci_platforms': (END2END_FIXTURES[f].platforms
+ if END2END_FIXTURES[f].ci_mac else without(
+ END2END_FIXTURES[f].platforms, 'mac')),
'deps': [
- 'end2end_fixture_%s' % f,
- 'end2end_test_%s' % t] + sec_deps,
+ 'end2end_fixture_%s' % f, 'end2end_test_%s' % t
+ ] + sec_deps,
'vs_proj_dir': 'test',
}
- for f in sorted(END2END_FIXTURES.keys())
- for t in sorted(END2END_TESTS.keys())
- if compatible(f, t)] + [
+ for f in sorted(END2END_FIXTURES.keys())
+ for t in sorted(END2END_TESTS.keys()) if compatible(f, t)
+ ] + [
{
'name': '%s_%s_nosec_test' % (f, t),
'build': 'test',
@@ -210,16 +254,20 @@ def main():
'src': [],
'flaky': END2END_TESTS[t].flaky,
'platforms': END2END_FIXTURES[f].platforms,
- 'ci_platforms': (END2END_FIXTURES[f].platforms
- if END2END_FIXTURES[f].ci_mac
- else without(END2END_FIXTURES[f].platforms, 'mac')),
+ 'ci_platforms': (END2END_FIXTURES[f].platforms
+ if END2END_FIXTURES[f].ci_mac else without(
+ END2END_FIXTURES[f].platforms, 'mac')),
'deps': [
- 'end2end_fixture_%s' % f,
- 'end2end_test_%s' % t] + unsec_deps,
+ 'end2end_nosec_fixture_%s' % f, 'end2end_nosec_test_%s' % t
+ ] + unsec_deps,
'vs_proj_dir': 'test',
}
- for f in sorted(END2END_FIXTURES.keys()) if not END2END_FIXTURES[f].secure
- for t in sorted(END2END_TESTS.keys()) if compatible(f, t) and not END2END_TESTS[t].secure]}
+ for f in sorted(END2END_FIXTURES.keys())
+ if not END2END_FIXTURES[f].secure
+ for t in sorted(END2END_TESTS.keys())
+ if compatible(f, t) and not END2END_TESTS[t].secure
+ ]
+ }
print yaml.dump(json)
diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c
new file mode 100644
index 0000000000..1fd4c0145a
--- /dev/null
+++ b/test/core/end2end/invalid_call_argument_test.c
@@ -0,0 +1,557 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <limits.h>
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+static void *tag(gpr_intptr i) { return (void *)i; }
+
+struct test_state {
+ int is_client;
+ grpc_channel *chan;
+ grpc_call *call;
+ gpr_timespec deadline;
+ grpc_completion_queue *cq;
+ cq_verifier *cqv;
+ grpc_op ops[6];
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_status_code status;
+ char *details;
+ size_t details_capacity;
+ grpc_call *server_call;
+ grpc_server *server;
+ grpc_metadata_array server_initial_metadata_recv;
+ grpc_call_details call_details;
+};
+
+static struct test_state g_state;
+
+static void prepare_test(int is_client) {
+ int port;
+ char *server_hostport;
+ grpc_op *op;
+ g_state.is_client = is_client;
+ grpc_metadata_array_init(&g_state.initial_metadata_recv);
+ grpc_metadata_array_init(&g_state.trailing_metadata_recv);
+ g_state.deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(2);
+ g_state.cq = grpc_completion_queue_create(NULL);
+ g_state.cqv = cq_verifier_create(g_state.cq);
+ g_state.details = NULL;
+ g_state.details_capacity = 0;
+
+ if (is_client) {
+ /* create a call, channel to a non existant server */
+ g_state.chan =
+ grpc_insecure_channel_create("nonexistant:54321", NULL, NULL);
+ g_state.call = grpc_channel_create_call(
+ g_state.chan, NULL, GRPC_PROPAGATE_DEFAULTS, g_state.cq, "/Foo",
+ "nonexistant", g_state.deadline, NULL);
+ } else {
+ g_state.server = grpc_server_create(NULL, NULL);
+ grpc_server_register_completion_queue(g_state.server, g_state.cq, NULL);
+ port = grpc_pick_unused_port_or_die();
+ gpr_join_host_port(&server_hostport, "0.0.0.0", port);
+ grpc_server_add_insecure_http2_port(g_state.server, server_hostport);
+ grpc_server_start(g_state.server);
+ gpr_free(server_hostport);
+ gpr_join_host_port(&server_hostport, "localhost", port);
+ g_state.chan = grpc_insecure_channel_create(server_hostport, NULL, NULL);
+ gpr_free(server_hostport);
+ g_state.call = grpc_channel_create_call(
+ g_state.chan, NULL, GRPC_PROPAGATE_DEFAULTS, g_state.cq, "/Foo", "bar",
+ g_state.deadline, NULL);
+ grpc_metadata_array_init(&g_state.server_initial_metadata_recv);
+ grpc_call_details_init(&g_state.call_details);
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops),
+ tag(1), NULL));
+ GPR_ASSERT(GRPC_CALL_OK ==
+ grpc_server_request_call(g_state.server, &g_state.server_call,
+ &g_state.call_details,
+ &g_state.server_initial_metadata_recv,
+ g_state.cq, g_state.cq, tag(101)));
+ cq_expect_completion(g_state.cqv, tag(101), 1);
+ cq_expect_completion(g_state.cqv, tag(1), 1);
+ cq_verify(g_state.cqv);
+ }
+}
+
+static void cleanup_test() {
+ grpc_call_destroy(g_state.call);
+ cq_verifier_destroy(g_state.cqv);
+ grpc_channel_destroy(g_state.chan);
+ gpr_free(g_state.details);
+ grpc_metadata_array_destroy(&g_state.initial_metadata_recv);
+ grpc_metadata_array_destroy(&g_state.trailing_metadata_recv);
+
+ if (!g_state.is_client) {
+ grpc_call_destroy(g_state.server_call);
+ grpc_server_shutdown_and_notify(g_state.server, g_state.cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(g_state.cq, tag(1000),
+ GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5),
+ NULL).type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(g_state.server);
+ grpc_call_details_destroy(&g_state.call_details);
+ grpc_metadata_array_destroy(&g_state.server_initial_metadata_recv);
+ }
+ grpc_completion_queue_shutdown(g_state.cq);
+ while (grpc_completion_queue_next(g_state.cq,
+ gpr_inf_future(GPR_CLOCK_REALTIME),
+ NULL).type != GRPC_QUEUE_SHUTDOWN)
+ ;
+ grpc_completion_queue_destroy(g_state.cq);
+}
+
+static void test_non_null_reserved_on_start_batch() {
+ prepare_test(1);
+ GPR_ASSERT(GRPC_CALL_ERROR ==
+ grpc_call_start_batch(g_state.call, NULL, 0, NULL, tag(1)));
+ cleanup_test();
+}
+
+static void test_non_null_reserved_on_op() {
+ grpc_op *op;
+ prepare_test(1);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = tag(2);
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ cleanup_test();
+}
+
+static void test_send_initial_metadata_more_than_once() {
+ grpc_op *op;
+ prepare_test(1);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops),
+ tag(1), NULL));
+ cq_expect_completion(g_state.cqv, tag(1), 0);
+ cq_verify(g_state.cqv);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ cleanup_test();
+}
+
+static void test_too_many_metadata() {
+ grpc_op *op;
+ prepare_test(1);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = (size_t)INT_MAX + 1;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_INVALID_METADATA ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ cleanup_test();
+}
+
+static void test_send_null_message() {
+ grpc_op *op;
+ prepare_test(1);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message = NULL;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_INVALID_MESSAGE ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ cleanup_test();
+}
+
+static void test_send_messages_at_the_same_time() {
+ grpc_op *op;
+ gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world");
+ grpc_byte_buffer *request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ prepare_test(1);
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message = request_payload;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message = tag(2);
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ grpc_byte_buffer_destroy(request_payload);
+ cleanup_test();
+}
+
+static void test_send_server_status_from_client() {
+ grpc_op *op;
+ prepare_test(1);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+ op->data.send_status_from_server.status_details = "xyz";
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_NOT_ON_CLIENT ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ cleanup_test();
+}
+
+static void test_receive_initial_metadata_twice_at_client() {
+ grpc_op *op;
+ prepare_test(1);
+ op = g_state.ops;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata = &g_state.initial_metadata_recv;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops),
+ tag(1), NULL));
+ cq_expect_completion(g_state.cqv, tag(1), 0);
+ cq_verify(g_state.cqv);
+ op = g_state.ops;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata = &g_state.initial_metadata_recv;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ cleanup_test();
+}
+
+static void test_receive_message_with_invalid_flags() {
+ grpc_op *op;
+ grpc_byte_buffer *payload = NULL;
+ prepare_test(1);
+ op = g_state.ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message = &payload;
+ op->flags = 1;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_INVALID_FLAGS ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ cleanup_test();
+}
+
+static void test_receive_two_messages_at_the_same_time() {
+ grpc_op *op;
+ grpc_byte_buffer *payload = NULL;
+ prepare_test(1);
+ op = g_state.ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message = &payload;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message = &payload;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ cleanup_test();
+}
+
+static void test_recv_close_on_server_from_client() {
+ grpc_op *op;
+ prepare_test(1);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = NULL;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_NOT_ON_CLIENT ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ cleanup_test();
+}
+
+static void test_recv_status_on_client_twice() {
+ grpc_op *op;
+ prepare_test(1);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata =
+ &g_state.trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &g_state.status;
+ op->data.recv_status_on_client.status_details = &g_state.details;
+ op->data.recv_status_on_client.status_details_capacity =
+ &g_state.details_capacity;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops),
+ tag(1), NULL));
+ cq_expect_completion(g_state.cqv, tag(1), 1);
+ cq_verify(g_state.cqv);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = NULL;
+ op->data.recv_status_on_client.status = NULL;
+ op->data.recv_status_on_client.status_details = NULL;
+ op->data.recv_status_on_client.status_details_capacity = NULL;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS ==
+ grpc_call_start_batch(g_state.call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(1), NULL));
+ cleanup_test();
+}
+
+static void test_send_close_from_client_on_server() {
+ grpc_op *op;
+ prepare_test(0);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_NOT_ON_SERVER ==
+ grpc_call_start_batch(g_state.server_call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(2), NULL));
+ cleanup_test();
+}
+
+static void test_recv_status_on_client_from_server() {
+ grpc_op *op;
+ prepare_test(0);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata =
+ &g_state.trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &g_state.status;
+ op->data.recv_status_on_client.status_details = &g_state.details;
+ op->data.recv_status_on_client.status_details_capacity =
+ &g_state.details_capacity;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_NOT_ON_SERVER ==
+ grpc_call_start_batch(g_state.server_call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(2), NULL));
+ cleanup_test();
+}
+
+static void test_send_status_from_server_with_invalid_flags() {
+ grpc_op *op;
+ prepare_test(0);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+ op->data.send_status_from_server.status_details = "xyz";
+ op->flags = 1;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_INVALID_FLAGS ==
+ grpc_call_start_batch(g_state.server_call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(2), NULL));
+ cleanup_test();
+}
+
+static void test_too_many_trailing_metadata() {
+ grpc_op *op;
+ prepare_test(0);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count =
+ (size_t)INT_MAX + 1;
+ op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+ op->data.send_status_from_server.status_details = "xyz";
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_INVALID_METADATA ==
+ grpc_call_start_batch(g_state.server_call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(2), NULL));
+ cleanup_test();
+}
+
+static void test_send_server_status_twice() {
+ grpc_op *op;
+ prepare_test(0);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+ op->data.send_status_from_server.status_details = "xyz";
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+ op->data.send_status_from_server.status_details = "xyz";
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS ==
+ grpc_call_start_batch(g_state.server_call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(2), NULL));
+ cleanup_test();
+}
+
+static void test_recv_close_on_server_with_invalid_flags() {
+ grpc_op *op;
+ prepare_test(0);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = NULL;
+ op->flags = 1;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_INVALID_FLAGS ==
+ grpc_call_start_batch(g_state.server_call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(2), NULL));
+ cleanup_test();
+}
+
+static void test_recv_close_on_server_twice() {
+ grpc_op *op;
+ prepare_test(0);
+
+ op = g_state.ops;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = NULL;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = NULL;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ GPR_ASSERT(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS ==
+ grpc_call_start_batch(g_state.server_call, g_state.ops,
+ (size_t)(op - g_state.ops), tag(2), NULL));
+ cleanup_test();
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+ test_non_null_reserved_on_start_batch();
+ test_non_null_reserved_on_op();
+ test_send_initial_metadata_more_than_once();
+ test_too_many_metadata();
+ test_send_null_message();
+ test_send_messages_at_the_same_time();
+ test_send_server_status_from_client();
+ test_receive_initial_metadata_twice_at_client();
+ test_receive_message_with_invalid_flags();
+ test_receive_two_messages_at_the_same_time();
+ test_recv_close_on_server_from_client();
+ test_recv_status_on_client_twice();
+ test_send_close_from_client_on_server();
+ test_recv_status_on_client_from_server();
+ test_send_status_from_server_with_invalid_flags();
+ test_too_many_trailing_metadata();
+ test_send_server_status_twice();
+ test_recv_close_on_server_with_invalid_flags();
+ test_recv_close_on_server_twice();
+ grpc_shutdown();
+
+ return 0;
+}
diff --git a/test/core/end2end/tests/binary_metadata.c b/test/core/end2end/tests/binary_metadata.c
index 58636ac2a2..e6404d6f51 100644
--- a/test/core/end2end/tests/binary_metadata.c
+++ b/test/core/end2end/tests/binary_metadata.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index d384cd1150..68bd4bc36e 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -55,8 +55,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/cancel_after_client_done.c b/test/core/end2end/tests/cancel_after_client_done.c
index e267d80493..1e919ce19e 100644
--- a/test/core/end2end/tests/cancel_after_client_done.c
+++ b/test/core/end2end/tests/cancel_after_client_done.c
@@ -55,8 +55,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index ef9165ee25..a84f9be14e 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -56,8 +56,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s/%s", test_name, config.name, mode.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index ce2b402f1b..61574df3d0 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c
index 6c57299e1a..6435d22ee9 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum.c
@@ -55,8 +55,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c
index 2005e5f881..2e36902a51 100644
--- a/test/core/end2end/tests/cancel_with_status.c
+++ b/test/core/end2end/tests/cancel_with_status.c
@@ -56,8 +56,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/census_simple_request.c b/test/core/end2end/tests/census_simple_request.c
deleted file mode 100644
index 29f52ed35a..0000000000
--- a/test/core/end2end/tests/census_simple_request.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "test/core/end2end/end2end_tests.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include "src/core/support/string.h"
-#include <grpc/byte_buffer.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/time.h>
-#include <grpc/support/useful.h>
-#include "test/core/end2end/cq_verifier.h"
-
-static gpr_timespec n_seconds_time(int n) {
- return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
-}
-
-static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
- const char *test_name,
- grpc_channel_args *client_args,
- grpc_channel_args *server_args) {
- grpc_end2end_test_fixture f;
- gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
- f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
- config.init_server(&f, server_args);
- return f;
-}
-
-static void *tag(gpr_intptr t) { return (void *)t; }
-
-static void shutdown_server(grpc_end2end_test_fixture *f) {
- if (!f->server) return;
- grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
- GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000),
- GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5),
- NULL).type == GRPC_OP_COMPLETE);
- grpc_server_destroy(f->server);
- f->server = NULL;
-}
-
-static void shutdown_client(grpc_end2end_test_fixture *f) {
- if (!f->client) return;
- grpc_channel_destroy(f->client);
- f->client = NULL;
-}
-
-static void drain_cq(grpc_completion_queue *cq) {
- grpc_event ev;
- do {
- ev = grpc_completion_queue_next(cq, n_seconds_time(5), NULL);
- } while (ev.type != GRPC_QUEUE_SHUTDOWN);
-}
-
-static void end_test(grpc_end2end_test_fixture *f) {
- shutdown_server(f);
- shutdown_client(f);
-
- grpc_completion_queue_shutdown(f->cq);
- drain_cq(f->cq);
- grpc_completion_queue_destroy(f->cq);
-}
-
-static void test_body(grpc_end2end_test_fixture f) {
- grpc_call *c;
- grpc_call *s;
- gpr_timespec deadline = n_seconds_time(5);
- cq_verifier *cqv = cq_verifier_create(f.cq);
- grpc_op ops[6];
- grpc_op *op;
- grpc_metadata_array initial_metadata_recv;
- grpc_metadata_array trailing_metadata_recv;
- grpc_metadata_array request_metadata_recv;
- grpc_call_details call_details;
- grpc_status_code status;
- grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
- int was_cancelled = 2;
-
- c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
- "/foo", "foo.test.google.fr:1234", deadline,
- NULL);
- GPR_ASSERT(c);
-
- grpc_metadata_array_init(&initial_metadata_recv);
- grpc_metadata_array_init(&trailing_metadata_recv);
- grpc_metadata_array_init(&request_metadata_recv);
- grpc_call_details_init(&call_details);
-
- op = ops;
- op->op = GRPC_OP_SEND_INITIAL_METADATA;
- op->data.send_initial_metadata.count = 0;
- op->flags = 0;
- op->reserved = NULL;
- op++;
- op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
- op->flags = 0;
- op->reserved = NULL;
- op++;
- op->op = GRPC_OP_RECV_INITIAL_METADATA;
- op->data.recv_initial_metadata = &initial_metadata_recv;
- op->flags = 0;
- op->reserved = NULL;
- op++;
- op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
- op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
- op->data.recv_status_on_client.status = &status;
- op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
- op->flags = 0;
- op->reserved = NULL;
- op++;
- error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
- GPR_ASSERT(GRPC_CALL_OK == error);
-
- error =
- grpc_server_request_call(f.server, &s, &call_details,
- &request_metadata_recv, f.cq, f.cq, tag(101));
- GPR_ASSERT(GRPC_CALL_OK == error);
- cq_expect_completion(cqv, tag(101), 1);
- cq_verify(cqv);
-
- op = ops;
- op->op = GRPC_OP_SEND_INITIAL_METADATA;
- op->data.send_initial_metadata.count = 0;
- op->flags = 0;
- op->reserved = NULL;
- op++;
- op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
- op->data.send_status_from_server.trailing_metadata_count = 0;
- op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
- op->flags = 0;
- op->reserved = NULL;
- op++;
- op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
- op->data.recv_close_on_server.cancelled = &was_cancelled;
- op->flags = 0;
- op->reserved = NULL;
- op++;
- error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
- GPR_ASSERT(GRPC_CALL_OK == error);
-
- cq_expect_completion(cqv, tag(102), 1);
- cq_expect_completion(cqv, tag(1), 1);
- cq_verify(cqv);
-
- GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
- GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234"));
- GPR_ASSERT(was_cancelled == 1);
-
- gpr_free(details);
- grpc_metadata_array_destroy(&initial_metadata_recv);
- grpc_metadata_array_destroy(&trailing_metadata_recv);
- grpc_metadata_array_destroy(&request_metadata_recv);
- grpc_call_details_destroy(&call_details);
-
- grpc_call_destroy(c);
- grpc_call_destroy(s);
-
- cq_verifier_destroy(cqv);
-}
-
-static void test_invoke_request_with_census(
- grpc_end2end_test_config config, const char *name,
- void (*body)(grpc_end2end_test_fixture f)) {
- char *fullname;
- grpc_end2end_test_fixture f;
- grpc_arg client_arg, server_arg;
- grpc_channel_args client_args, server_args;
-
- client_arg.type = GRPC_ARG_INTEGER;
- client_arg.key = GRPC_ARG_ENABLE_CENSUS;
- client_arg.value.integer = 1;
-
- client_args.num_args = 1;
- client_args.args = &client_arg;
-
- server_arg.type = GRPC_ARG_INTEGER;
- server_arg.key = GRPC_ARG_ENABLE_CENSUS;
- server_arg.value.integer = 1;
- server_args.num_args = 1;
- server_args.args = &server_arg;
-
- gpr_asprintf(&fullname, "%s/%s", "test_invoke_request_with_census", name);
- f = begin_test(config, fullname, &client_args, &server_args);
- body(f);
- end_test(&f);
- config.tear_down_data(&f);
- gpr_free(fullname);
-}
-
-void grpc_end2end_tests(grpc_end2end_test_config config) {
- test_invoke_request_with_census(config, "census_simple_request", test_body);
-}
diff --git a/test/core/end2end/tests/channel_connectivity.c b/test/core/end2end/tests/channel_connectivity.c
index 46085bbdaf..0e0ac03015 100644
--- a/test/core/end2end/tests/channel_connectivity.c
+++ b/test/core/end2end/tests/channel_connectivity.c
@@ -153,7 +153,7 @@ static void test_connectivity(grpc_end2end_test_config config) {
cq_verify(cqv);
state = grpc_channel_check_connectivity_state(f.client, 0);
GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
- state == GRPC_CHANNEL_CONNECTING);
+ state == GRPC_CHANNEL_CONNECTING || state == GRPC_CHANNEL_IDLE);
/* cleanup server */
grpc_server_destroy(f.server);
diff --git a/test/core/end2end/tests/channel_ping.c b/test/core/end2end/tests/channel_ping.c
new file mode 100644
index 0000000000..441e49ee7a
--- /dev/null
+++ b/test/core/end2end/tests/channel_ping.c
@@ -0,0 +1,97 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+
+#include "test/core/end2end/cq_verifier.h"
+
+static void *tag(gpr_intptr t) { return (void *)t; }
+
+static void test_ping(grpc_end2end_test_config config) {
+ grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
+ cq_verifier *cqv = cq_verifier_create(f.cq);
+ grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
+ int i;
+
+ config.init_client(&f, NULL);
+ config.init_server(&f, NULL);
+
+ grpc_channel_ping(f.client, f.cq, tag(0), NULL);
+ cq_expect_completion(cqv, tag(0), 0);
+
+ /* check that we're still in idle, and start connecting */
+ GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) ==
+ GRPC_CHANNEL_IDLE);
+ /* we'll go through some set of transitions (some might be missed), until
+ READY is reached */
+ while (state != GRPC_CHANNEL_READY) {
+ grpc_channel_watch_connectivity_state(
+ f.client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(99));
+ cq_expect_completion(cqv, tag(99), 1);
+ cq_verify(cqv);
+ state = grpc_channel_check_connectivity_state(f.client, 0);
+ GPR_ASSERT(state == GRPC_CHANNEL_READY ||
+ state == GRPC_CHANNEL_CONNECTING ||
+ state == GRPC_CHANNEL_TRANSIENT_FAILURE);
+ }
+
+ for (i = 1; i <= 5; i++) {
+ grpc_channel_ping(f.client, f.cq, tag(i), NULL);
+ cq_expect_completion(cqv, tag(i), 1);
+ cq_verify(cqv);
+ }
+
+ grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
+ cq_expect_completion(cqv, tag(0xdead), 1);
+ cq_verify(cqv);
+
+ /* cleanup server */
+ grpc_server_destroy(f.server);
+
+ grpc_channel_destroy(f.client);
+ grpc_completion_queue_shutdown(f.cq);
+ grpc_completion_queue_destroy(f.cq);
+ config.tear_down_data(&f);
+
+ cq_verifier_destroy(cqv);
+}
+
+void grpc_end2end_tests(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION);
+ test_ping(config);
+}
diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c
index f321fe1e7c..0d07110aef 100644
--- a/test/core/end2end/tests/compressed_payload.c
+++ b/test/core/end2end/tests/compressed_payload.c
@@ -59,8 +59,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c
index 59eb8f18f9..f331aa92e0 100644
--- a/test/core/end2end/tests/empty_batch.c
+++ b/test/core/end2end/tests/empty_batch.c
@@ -56,8 +56,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c
index 6b786aa89a..8efa5a34d0 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.c
+++ b/test/core/end2end/tests/graceful_server_shutdown.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c
index 75bb133439..399b6e2183 100644
--- a/test/core/end2end/tests/high_initial_seqno.c
+++ b/test/core/end2end/tests/high_initial_seqno.c
@@ -36,13 +36,15 @@
#include <stdio.h>
#include <string.h>
-#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
+
+#include "src/core/support/string.h"
#include "test/core/end2end/cq_verifier.h"
enum { TIMEOUT = 200000 };
@@ -56,8 +58,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
@@ -208,6 +210,7 @@ static void test_invoke_10_simple_requests(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
grpc_arg client_arg;
grpc_channel_args client_args;
+ char *name;
client_arg.type = GRPC_ARG_INTEGER;
client_arg.key = GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER;
@@ -216,13 +219,16 @@ static void test_invoke_10_simple_requests(grpc_end2end_test_config config,
client_args.num_args = 1;
client_args.args = &client_arg;
- f = begin_test(config, "test_invoke_10_simple_requests", &client_args, NULL);
+ gpr_asprintf(&name, "test_invoke_requests first_seqno=%d",
+ initial_sequence_number);
+ f = begin_test(config, name, &client_args, NULL);
for (i = 0; i < 10; i++) {
simple_request_body(f);
gpr_log(GPR_INFO, "Passed simple request %d", i);
}
end_test(&f);
config.tear_down_data(&f);
+ gpr_free(name);
}
void grpc_end2end_tests(grpc_end2end_test_config config) {
diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c
index 297ea8d542..f16883ecfd 100644
--- a/test/core/end2end/tests/hpack_size.c
+++ b/test/core/end2end/tests/hpack_size.c
@@ -241,8 +241,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
@@ -262,9 +262,9 @@ static void drain_cq(grpc_completion_queue *cq) {
static void shutdown_server(grpc_end2end_test_fixture *f) {
if (!f->server) return;
grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
- GPR_ASSERT(grpc_completion_queue_pluck(
- f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL)
- .type == GRPC_OP_COMPLETE);
+ GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000),
+ GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5),
+ NULL).type == GRPC_OP_COMPLETE);
grpc_server_destroy(f->server);
f->server = NULL;
}
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index 67cd303fa6..c612af91e3 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/large_metadata.c b/test/core/end2end/tests/large_metadata.c
index 75d3f71cae..763f75d59d 100644
--- a/test/core/end2end/tests/large_metadata.c
+++ b/test/core/end2end/tests/large_metadata.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c
index bb64200d9e..d39aabaf70 100644
--- a/test/core/end2end/tests/max_concurrent_streams.c
+++ b/test/core/end2end/tests/max_concurrent_streams.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c
index b3d8304d0b..c311f0a44e 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/metadata.c b/test/core/end2end/tests/metadata.c
index c325d5a37c..2593cde027 100644
--- a/test/core/end2end/tests/metadata.c
+++ b/test/core/end2end/tests/metadata.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c
index 8fe9e7bcc5..23b8591e25 100644
--- a/test/core/end2end/tests/negative_deadline.c
+++ b/test/core/end2end/tests/negative_deadline.c
@@ -56,8 +56,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c
index ec33af78ef..dbaad3004e 100644
--- a/test/core/end2end/tests/no_op.c
+++ b/test/core/end2end/tests/no_op.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c
index b440fbab21..df44c0de1e 100644
--- a/test/core/end2end/tests/payload.c
+++ b/test/core/end2end/tests/payload.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c
index 804862ff58..27180dd679 100644
--- a/test/core/end2end/tests/ping_pong_streaming.c
+++ b/test/core/end2end/tests/ping_pong_streaming.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c
index eea91e6c3b..ef4d5063b5 100644
--- a/test/core/end2end/tests/registered_call.c
+++ b/test/core/end2end/tests/registered_call.c
@@ -56,8 +56,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c
index 5ea845e0e5..0ad5a4612e 100644
--- a/test/core/end2end/tests/request_with_flags.c
+++ b/test/core/end2end/tests/request_with_flags.c
@@ -55,8 +55,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c
index 56c199baf3..ee5b071372 100644
--- a/test/core/end2end/tests/request_with_payload.c
+++ b/test/core/end2end/tests/request_with_payload.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c
index c77e31bca3..94863e7280 100644
--- a/test/core/end2end/tests/server_finishes_request.c
+++ b/test/core/end2end/tests/server_finishes_request.c
@@ -56,8 +56,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/shutdown_finishes_calls.c b/test/core/end2end/tests/shutdown_finishes_calls.c
index ad7def09a9..aa679081ec 100644
--- a/test/core/end2end/tests/shutdown_finishes_calls.c
+++ b/test/core/end2end/tests/shutdown_finishes_calls.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/shutdown_finishes_tags.c b/test/core/end2end/tests/shutdown_finishes_tags.c
index 9b678a1754..53a1573e16 100644
--- a/test/core/end2end/tests/shutdown_finishes_tags.c
+++ b/test/core/end2end/tests/shutdown_finishes_tags.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c
index e9965a91ba..ce5df86a92 100644
--- a/test/core/end2end/tests/simple_request.c
+++ b/test/core/end2end/tests/simple_request.c
@@ -56,8 +56,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/end2end/tests/trailing_metadata.c b/test/core/end2end/tests/trailing_metadata.c
index 306ef7e3aa..71f10eb8f5 100644
--- a/test/core/end2end/tests/trailing_metadata.c
+++ b/test/core/end2end/tests/trailing_metadata.c
@@ -54,8 +54,8 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
- config.init_client(&f, client_args);
config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
return f;
}
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index 14a1a815bc..ae218b4cc1 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -50,9 +50,9 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "src/core/profiling/timers.h"
-#include "test/core/util/port.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/grpc_profiler.h"
+#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
static grpc_completion_queue *cq;
diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c
index 4012f995c7..612388c61d 100644
--- a/test/core/httpcli/httpcli_test.c
+++ b/test/core/httpcli/httpcli_test.c
@@ -69,13 +69,13 @@ static void on_finish(grpc_exec_ctx *exec_ctx, void *arg,
gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
}
-static void test_get(int use_ssl, int port) {
+static void test_get(int port) {
grpc_httpcli_request req;
char *host;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
g_done = 0;
- gpr_log(GPR_INFO, "running %s with use_ssl=%d.", "test_get", use_ssl);
+ gpr_log(GPR_INFO, "test_get");
gpr_asprintf(&host, "localhost:%d", port);
gpr_log(GPR_INFO, "requesting from %s", host);
@@ -83,7 +83,7 @@ static void test_get(int use_ssl, int port) {
memset(&req, 0, sizeof(req));
req.host = host;
req.path = "/get";
- req.handshaker = use_ssl ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
+ req.handshaker = &grpc_httpcli_plaintext;
grpc_httpcli_get(&exec_ctx, &g_context, &g_pollset, &req, n_seconds_time(15),
on_finish, (void *)42);
@@ -100,13 +100,13 @@ static void test_get(int use_ssl, int port) {
gpr_free(host);
}
-static void test_post(int use_ssl, int port) {
+static void test_post(int port) {
grpc_httpcli_request req;
char *host;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
g_done = 0;
- gpr_log(GPR_INFO, "running %s with use_ssl=%d.", "test_post", (int)use_ssl);
+ gpr_log(GPR_INFO, "test_post");
gpr_asprintf(&host, "localhost:%d", port);
gpr_log(GPR_INFO, "posting to %s", host);
@@ -114,7 +114,7 @@ static void test_post(int use_ssl, int port) {
memset(&req, 0, sizeof(req));
req.host = host;
req.path = "/post";
- req.handshaker = use_ssl ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
+ req.handshaker = &grpc_httpcli_plaintext;
grpc_httpcli_post(&exec_ctx, &g_context, &g_pollset, &req, "hello", 5,
n_seconds_time(15), on_finish, (void *)42);
@@ -142,19 +142,26 @@ int main(int argc, char **argv) {
char *me = argv[0];
char *lslash = strrchr(me, '/');
char *args[4];
- char root[1024];
int port = grpc_pick_unused_port_or_die();
- /* figure out where we are */
- if (lslash) {
- memcpy(root, me, (size_t)(lslash - me));
- root[lslash - me] = 0;
+ GPR_ASSERT(argc <= 2);
+ if (argc == 2) {
+ args[0] = gpr_strdup(argv[1]);
} else {
- strcpy(root, ".");
+ /* figure out where we are */
+ char *root;
+ if (lslash) {
+ root = gpr_malloc((size_t)(lslash - me + 1));
+ memcpy(root, me, (size_t)(lslash - me));
+ root[lslash - me] = 0;
+ } else {
+ root = gpr_strdup(".");
+ }
+ gpr_asprintf(&args[0], "%s/../../test/core/httpcli/test_server.py", root);
+ gpr_free(root);
}
/* start the server */
- gpr_asprintf(&args[0], "%s/../../test/core/httpcli/test_server.py", root);
args[1] = "--port";
gpr_asprintf(&args[2], "%d", port);
server = gpr_subprocess_create(3, (const char **)args);
@@ -170,8 +177,8 @@ int main(int argc, char **argv) {
grpc_httpcli_context_init(&g_context);
grpc_pollset_init(&g_pollset);
- test_get(0, port);
- test_post(0, port);
+ test_get(port);
+ test_post(port);
grpc_httpcli_context_destroy(&g_context);
grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
diff --git a/test/core/httpcli/httpscli_test.c b/test/core/httpcli/httpscli_test.c
new file mode 100644
index 0000000000..ba5660bd18
--- /dev/null
+++ b/test/core/httpcli/httpscli_test.c
@@ -0,0 +1,195 @@
+/*
+ *
+ * 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/httpcli/httpcli.h"
+
+#include <string.h>
+
+#include <grpc/grpc.h>
+#include "src/core/iomgr/iomgr.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/subprocess.h>
+#include <grpc/support/sync.h>
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+static int g_done = 0;
+static grpc_httpcli_context g_context;
+static grpc_pollset g_pollset;
+
+static gpr_timespec n_seconds_time(int seconds) {
+ return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds);
+}
+
+static void on_finish(grpc_exec_ctx *exec_ctx, void *arg,
+ const grpc_httpcli_response *response) {
+ const char *expect =
+ "<html><head><title>Hello world!</title></head>"
+ "<body><p>This is a test</p></body></html>";
+ GPR_ASSERT(arg == (void *)42);
+ GPR_ASSERT(response);
+ GPR_ASSERT(response->status == 200);
+ GPR_ASSERT(response->body_length == strlen(expect));
+ GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length));
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ g_done = 1;
+ grpc_pollset_kick(&g_pollset, NULL);
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+}
+
+static void test_get(int port) {
+ grpc_httpcli_request req;
+ char *host;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+ g_done = 0;
+ gpr_log(GPR_INFO, "test_get");
+
+ gpr_asprintf(&host, "localhost:%d", port);
+ gpr_log(GPR_INFO, "requesting from %s", host);
+
+ memset(&req, 0, sizeof(req));
+ req.host = host;
+ req.ssl_host_override = "foo.test.google.fr";
+ req.path = "/get";
+ req.handshaker = &grpc_httpcli_ssl;
+
+ grpc_httpcli_get(&exec_ctx, &g_context, &g_pollset, &req, n_seconds_time(15),
+ on_finish, (void *)42);
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ while (!g_done) {
+ grpc_pollset_worker worker;
+ grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_exec_ctx_finish(&exec_ctx);
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ }
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_free(host);
+}
+
+static void test_post(int port) {
+ grpc_httpcli_request req;
+ char *host;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+ g_done = 0;
+ gpr_log(GPR_INFO, "test_post");
+
+ gpr_asprintf(&host, "localhost:%d", port);
+ gpr_log(GPR_INFO, "posting to %s", host);
+
+ memset(&req, 0, sizeof(req));
+ req.host = host;
+ req.ssl_host_override = "foo.test.google.fr";
+ req.path = "/post";
+ req.handshaker = &grpc_httpcli_ssl;
+
+ grpc_httpcli_post(&exec_ctx, &g_context, &g_pollset, &req, "hello", 5,
+ n_seconds_time(15), on_finish, (void *)42);
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ while (!g_done) {
+ grpc_pollset_worker worker;
+ grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_exec_ctx_finish(&exec_ctx);
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ }
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_free(host);
+}
+
+static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, int success) {
+ grpc_pollset_destroy(p);
+}
+
+int main(int argc, char **argv) {
+ grpc_closure destroyed;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ gpr_subprocess *server;
+ char *me = argv[0];
+ char *lslash = strrchr(me, '/');
+ char *args[5];
+ int port = grpc_pick_unused_port_or_die();
+
+ GPR_ASSERT(argc <= 2);
+ if (argc == 2) {
+ args[0] = gpr_strdup(argv[1]);
+ } else {
+ /* figure out where we are */
+ char *root;
+ if (lslash) {
+ root = gpr_malloc((size_t)(lslash - me + 1));
+ memcpy(root, me, (size_t)(lslash - me));
+ root[lslash - me] = 0;
+ } else {
+ root = gpr_strdup(".");
+ }
+ gpr_asprintf(&args[0], "%s/../../test/core/httpcli/test_server.py", root);
+ gpr_free(root);
+ }
+
+ /* start the server */
+ args[1] = "--port";
+ gpr_asprintf(&args[2], "%d", port);
+ args[3] = "--ssl";
+ server = gpr_subprocess_create(4, (const char **)args);
+ GPR_ASSERT(server);
+ gpr_free(args[0]);
+ gpr_free(args[2]);
+
+ gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_seconds(5, GPR_TIMESPAN)));
+
+ grpc_test_init(argc, argv);
+ grpc_init();
+ grpc_httpcli_context_init(&g_context);
+ grpc_pollset_init(&g_pollset);
+
+ test_get(port);
+ test_post(port);
+
+ grpc_httpcli_context_destroy(&g_context);
+ grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
+ grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+ grpc_exec_ctx_finish(&exec_ctx);
+ grpc_shutdown();
+
+ gpr_subprocess_destroy(server);
+
+ return 0;
+}
diff --git a/test/core/httpcli/parser_test.c b/test/core/httpcli/parser_test.c
index dacec0f72f..a26ddd2821 100644
--- a/test/core/httpcli/parser_test.c
+++ b/test/core/httpcli/parser_test.c
@@ -38,6 +38,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
#include "test/core/util/slice_splitter.h"
#include "test/core/util/test_config.h"
@@ -123,6 +124,7 @@ int main(int argc, char **argv) {
size_t i;
const grpc_slice_split_mode split_modes[] = {GRPC_SLICE_SPLIT_IDENTITY,
GRPC_SLICE_SPLIT_ONE_BYTE};
+ char *tmp1, *tmp2;
grpc_test_init(argc, argv);
@@ -149,6 +151,20 @@ int main(int argc, char **argv) {
test_fails(split_modes[i], "HTTP/1.0 200 OK\n");
test_fails(split_modes[i], "HTTP/1.0 200 OK\r\n");
test_fails(split_modes[i], "HTTP/1.0 200 OK\r\nFoo x\r\n");
+ test_fails(split_modes[i],
+ "HTTP/1.0 200 OK\r\n"
+ "xyz: abc\r\n"
+ " def\r\n"
+ "\r\n"
+ "hello world!");
+
+ tmp1 = gpr_malloc(2 * GRPC_HTTPCLI_MAX_HEADER_LENGTH);
+ memset(tmp1, 'a', 2 * GRPC_HTTPCLI_MAX_HEADER_LENGTH - 1);
+ tmp1[2 * GRPC_HTTPCLI_MAX_HEADER_LENGTH - 1] = 0;
+ gpr_asprintf(&tmp2, "HTTP/1.0 200 OK\r\nxyz: %s\r\n\r\n", tmp1);
+ test_fails(split_modes[i], tmp2);
+ gpr_free(tmp1);
+ gpr_free(tmp2);
}
return 0;
diff --git a/test/core/httpcli/test_server.py b/test/core/httpcli/test_server.py
index 4aaf5e30f8..225c2a6b0f 100755
--- a/test/core/httpcli/test_server.py
+++ b/test/core/httpcli/test_server.py
@@ -4,9 +4,18 @@
import argparse
import BaseHTTPServer
+import os
+import ssl
+import sys
+
+_PEM = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.pem'))
+_KEY = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.key'))
+print _PEM
+open(_PEM).close()
argp = argparse.ArgumentParser(description='Server for httpcli_test')
argp.add_argument('-p', '--port', default=10080, type=int)
+argp.add_argument('-s', '--ssl', default=False, action='store_true')
args = argp.parse_args()
print 'server running on port %d' % args.port
@@ -28,4 +37,7 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
if self.path == '/post' and content == 'hello':
self.good()
-BaseHTTPServer.HTTPServer(('', args.port), Handler).serve_forever()
+httpd = BaseHTTPServer.HTTPServer(('localhost', args.port), Handler)
+if args.ssl:
+ httpd.socket = ssl.wrap_socket(httpd.socket, certfile=_PEM, keyfile=_KEY, server_side=True)
+httpd.serve_forever()
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index f592f63ba9..4be6957a83 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -121,7 +121,7 @@ static void session_shutdown_cb(grpc_exec_ctx *exec_ctx, void *arg, /*session */
int success) {
session *se = arg;
server *sv = se->sv;
- grpc_fd_orphan(exec_ctx, se->em_fd, NULL, "a");
+ grpc_fd_orphan(exec_ctx, se->em_fd, NULL, NULL, "a");
gpr_free(se);
/* Start to shutdown listen fd. */
grpc_fd_shutdown(exec_ctx, sv->em_fd);
@@ -177,7 +177,7 @@ static void listen_shutdown_cb(grpc_exec_ctx *exec_ctx, void *arg /*server */,
int success) {
server *sv = arg;
- grpc_fd_orphan(exec_ctx, sv->em_fd, NULL, "b");
+ grpc_fd_orphan(exec_ctx, sv->em_fd, NULL, NULL, "b");
gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
sv->done = 1;
@@ -294,7 +294,7 @@ static void client_init(client *cl) {
static void client_session_shutdown_cb(grpc_exec_ctx *exec_ctx,
void *arg /*client */, int success) {
client *cl = arg;
- grpc_fd_orphan(exec_ctx, cl->em_fd, NULL, "c");
+ grpc_fd_orphan(exec_ctx, cl->em_fd, NULL, NULL, "c");
cl->done = 1;
grpc_pollset_kick(&g_pollset, NULL);
}
@@ -503,7 +503,7 @@ static void test_grpc_fd_change(void) {
GPR_ASSERT(b.cb_that_ran == second_read_callback);
gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
- grpc_fd_orphan(&exec_ctx, em_fd, NULL, "d");
+ grpc_fd_orphan(&exec_ctx, em_fd, NULL, NULL, "d");
grpc_exec_ctx_finish(&exec_ctx);
destroy_change_data(&a);
destroy_change_data(&b);
diff --git a/test/core/iomgr/sockaddr_utils_test.c b/test/core/iomgr/sockaddr_utils_test.c
index 5009a641ea..5cf0994f39 100644
--- a/test/core/iomgr/sockaddr_utils_test.c
+++ b/test/core/iomgr/sockaddr_utils_test.c
@@ -236,6 +236,29 @@ static void test_sockaddr_to_string(void) {
GPR_ASSERT(errno == 0x7EADBEEF);
}
+static void test_sockaddr_set_get_port(void) {
+ struct sockaddr_in input4;
+ struct sockaddr_in6 input6;
+ struct sockaddr dummy;
+
+ gpr_log(GPR_DEBUG, "test_sockaddr_set_get_port");
+
+ input4 = make_addr4(kIPv4, sizeof(kIPv4));
+ GPR_ASSERT(grpc_sockaddr_get_port((struct sockaddr *)&input4) == 12345);
+ GPR_ASSERT(grpc_sockaddr_set_port((struct sockaddr *)&input4, 54321));
+ GPR_ASSERT(grpc_sockaddr_get_port((struct sockaddr *)&input4) == 54321);
+
+ input6 = make_addr6(kIPv6, sizeof(kIPv6));
+ GPR_ASSERT(grpc_sockaddr_get_port((struct sockaddr *)&input6) == 12345);
+ GPR_ASSERT(grpc_sockaddr_set_port((struct sockaddr *)&input6, 54321));
+ GPR_ASSERT(grpc_sockaddr_get_port((struct sockaddr *)&input6) == 54321);
+
+ memset(&dummy, 0, sizeof(dummy));
+ dummy.sa_family = 123;
+ GPR_ASSERT(grpc_sockaddr_get_port(&dummy) == 0);
+ GPR_ASSERT(grpc_sockaddr_set_port(&dummy, 1234) == 0);
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
@@ -243,6 +266,7 @@ int main(int argc, char **argv) {
test_sockaddr_to_v4mapped();
test_sockaddr_is_wildcard();
test_sockaddr_to_string();
+ test_sockaddr_set_get_port();
return 0;
}
diff --git a/test/core/iomgr/socket_utils_test.c b/test/core/iomgr/socket_utils_test.c
new file mode 100644
index 0000000000..58c3fbc0ae
--- /dev/null
+++ b/test/core/iomgr/socket_utils_test.c
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+#include "src/core/iomgr/socket_utils_posix.h"
+
+#include <errno.h>
+#include <string.h>
+
+#include <grpc/support/log.h>
+#include "test/core/util/test_config.h"
+
+int main(int argc, char **argv) {
+ int sock;
+ grpc_test_init(argc, argv);
+
+ sock = socket(PF_INET, SOCK_STREAM, 0);
+ GPR_ASSERT(sock > 0);
+
+ GPR_ASSERT(grpc_set_socket_nonblocking(sock, 1));
+ GPR_ASSERT(grpc_set_socket_nonblocking(sock, 0));
+ GPR_ASSERT(grpc_set_socket_cloexec(sock, 1));
+ GPR_ASSERT(grpc_set_socket_cloexec(sock, 0));
+ GPR_ASSERT(grpc_set_socket_reuse_addr(sock, 1));
+ GPR_ASSERT(grpc_set_socket_reuse_addr(sock, 0));
+ GPR_ASSERT(grpc_set_socket_low_latency(sock, 1));
+ GPR_ASSERT(grpc_set_socket_low_latency(sock, 0));
+
+ close(sock);
+
+ return 0;
+}
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index a61cccdb02..833ceace54 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -234,8 +234,9 @@ void test_times_out(void) {
if (gpr_time_cmp(now, finish_time) > 0) {
break;
}
- gpr_log(GPR_DEBUG, "now=%d.%09d connect_deadline=%d.%09d", now.tv_sec,
- now.tv_nsec, connect_deadline.tv_sec, connect_deadline.tv_nsec);
+ gpr_log(GPR_DEBUG, "now=%lld.%09d connect_deadline=%lld.%09d",
+ (long long)now.tv_sec, (int)now.tv_nsec,
+ (long long)connect_deadline.tv_sec, (int)connect_deadline.tv_nsec);
if (is_after_deadline && gpr_time_cmp(now, restart_verifying_time) <= 0) {
/* allow some slack before insisting that things be done */
} else {
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index f676454b7f..9feac931a3 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -383,6 +383,76 @@ static void write_test(size_t num_bytes, size_t slice_size) {
grpc_exec_ctx_finish(&exec_ctx);
}
+void on_fd_released(grpc_exec_ctx *exec_ctx, void *arg, int success) {
+ int *done = arg;
+ *done = 1;
+ grpc_pollset_kick(&g_pollset, NULL);
+}
+
+/* Do a read_test, then release fd and try to read/write again. */
+static void release_fd_test(size_t num_bytes, size_t slice_size) {
+ int sv[2];
+ grpc_endpoint *ep;
+ struct read_socket_state state;
+ size_t written_bytes;
+ int fd;
+ gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_closure fd_released_cb;
+ int fd_released_done = 0;
+ grpc_closure_init(&fd_released_cb, &on_fd_released, &fd_released_done);
+
+ gpr_log(GPR_INFO, "Release fd read_test of size %d, slice size %d", num_bytes,
+ slice_size);
+
+ create_sockets(sv);
+
+ ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), slice_size, "test");
+ grpc_endpoint_add_to_pollset(&exec_ctx, ep, &g_pollset);
+
+ written_bytes = fill_socket_partial(sv[0], num_bytes);
+ gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
+
+ state.ep = ep;
+ state.read_bytes = 0;
+ state.target_read_bytes = written_bytes;
+ gpr_slice_buffer_init(&state.incoming);
+ grpc_closure_init(&state.read_cb, read_cb, &state);
+
+ grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
+
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ while (state.read_bytes < state.target_read_bytes) {
+ grpc_pollset_worker worker;
+ grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ gpr_now(GPR_CLOCK_MONOTONIC), deadline);
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_exec_ctx_finish(&exec_ctx);
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ }
+ GPR_ASSERT(state.read_bytes == state.target_read_bytes);
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+
+ gpr_slice_buffer_destroy(&state.incoming);
+ grpc_tcp_destroy_and_release_fd(&exec_ctx, ep, &fd, &fd_released_cb);
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ while (!fd_released_done) {
+ grpc_pollset_worker worker;
+ grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ gpr_now(GPR_CLOCK_MONOTONIC), deadline);
+ }
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ GPR_ASSERT(fd_released_done == 1);
+ GPR_ASSERT(fd == sv[1]);
+ grpc_exec_ctx_finish(&exec_ctx);
+
+ written_bytes = fill_socket_partial(sv[0], num_bytes);
+ drain_socket_blocking(fd, written_bytes, written_bytes);
+ written_bytes = fill_socket_partial(fd, num_bytes);
+ drain_socket_blocking(sv[0], written_bytes, written_bytes);
+ close(fd);
+}
+
void run_tests(void) {
size_t i = 0;
@@ -402,6 +472,8 @@ void run_tests(void) {
for (i = 1; i < 1000; i = GPR_MAX(i + 1, i * 5 / 4)) {
write_test(40320, i);
}
+
+ release_fd_test(100, 8192);
}
static void clean_up(void) {}
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index 86e8767937..85e28732e4 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -43,6 +43,8 @@
#include <string.h>
#include <unistd.h>
+#ifdef GRPC_NEED_UDP
+
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
static grpc_pollset g_pollset;
@@ -195,3 +197,9 @@ int main(int argc, char **argv) {
grpc_iomgr_shutdown();
return 0;
}
+
+#else
+
+int main(int argc, char **argv) { return 0; }
+
+#endif
diff --git a/test/core/iomgr/workqueue_test.c b/test/core/iomgr/workqueue_test.c
index 90f7ba7a83..d1f9dabc57 100644
--- a/test/core/iomgr/workqueue_test.c
+++ b/test/core/iomgr/workqueue_test.c
@@ -48,6 +48,15 @@ static void must_succeed(grpc_exec_ctx *exec_ctx, void *p, int success) {
gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
}
+static void test_ref_unref(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_workqueue *wq = grpc_workqueue_create(&exec_ctx);
+ GRPC_WORKQUEUE_REF(wq, "test");
+ GRPC_WORKQUEUE_UNREF(&exec_ctx, wq, "test");
+ GRPC_WORKQUEUE_UNREF(&exec_ctx, wq, "destroy");
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
static void test_add_closure(void) {
grpc_closure c;
int done = 0;
@@ -72,6 +81,31 @@ static void test_add_closure(void) {
grpc_exec_ctx_finish(&exec_ctx);
}
+static void test_flush(void) {
+ grpc_closure c;
+ int done = 0;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_workqueue *wq = grpc_workqueue_create(&exec_ctx);
+ gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
+ grpc_pollset_worker worker;
+ grpc_closure_init(&c, must_succeed, &done);
+
+ grpc_exec_ctx_enqueue(&exec_ctx, &c, 1);
+ grpc_workqueue_flush(&exec_ctx, wq);
+ grpc_workqueue_add_to_pollset(&exec_ctx, wq, &g_pollset);
+
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ GPR_ASSERT(!done);
+ grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ gpr_now(deadline.clock_type), deadline);
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(done);
+
+ GRPC_WORKQUEUE_UNREF(&exec_ctx, wq, "destroy");
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, int success) {
grpc_pollset_destroy(p);
}
@@ -83,7 +117,9 @@ int main(int argc, char **argv) {
grpc_init();
grpc_pollset_init(&g_pollset);
+ test_ref_unref();
test_add_closure();
+ test_flush();
grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
diff --git a/test/core/json/json_stream_error_test.c b/test/core/json/json_stream_error_test.c
new file mode 100644
index 0000000000..3464eb2a9c
--- /dev/null
+++ b/test/core/json/json_stream_error_test.c
@@ -0,0 +1,74 @@
+/*
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/useful.h>
+#include <grpc/support/log.h>
+#include "test/core/util/test_config.h"
+
+#include "src/core/json/json_reader.h"
+#include "src/core/json/json_writer.h"
+
+static int g_string_clear_once = 0;
+
+static void string_clear(void *userdata) {
+ GPR_ASSERT(!g_string_clear_once);
+ g_string_clear_once = 1;
+}
+
+static gpr_uint32 read_char(void *userdata) {
+ return GRPC_JSON_READ_CHAR_ERROR;
+}
+
+static grpc_json_reader_vtable reader_vtable = {
+ string_clear, NULL, NULL, read_char, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL};
+
+static void read_error() {
+ grpc_json_reader reader;
+ grpc_json_reader_status status;
+ grpc_json_reader_init(&reader, &reader_vtable, NULL);
+
+ status = grpc_json_reader_run(&reader);
+ GPR_ASSERT(status == GRPC_JSON_READ_ERROR);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ read_error();
+ gpr_log(GPR_INFO, "json_stream_error success");
+ return 0;
+}
diff --git a/test/core/json/json_test.c b/test/core/json/json_test.c
index 15019913da..5add80d753 100644
--- a/test/core/json/json_test.c
+++ b/test/core/json/json_test.c
@@ -49,10 +49,10 @@ typedef struct testing_pair {
static testing_pair testing_pairs[] = {
/* Testing valid parsing. */
-
/* Testing trivial parses, with de-indentation. */
{" 0 ", "0"},
{" 1 ", "1"},
+ {" \" \" ", "\" \""},
{" \"a\" ", "\"a\""},
{" true ", "true"},
/* Testing the parser's ability to decode trivial UTF-16. */
@@ -69,8 +69,8 @@ static testing_pair testing_pairs[] = {
" [ [ ] , { } , [ ] ] ", "[[],{},[]]",
},
/* Testing escapes and control chars in key strings. */
- {" { \"\x7f\\n\\\\a , b\": 1, \"\": 0 } ",
- "{\"\\u007f\\n\\\\a , b\":1,\"\":0}"},
+ {" { \"\\u007f\x7f\\n\\r\\\"\\f\\b\\\\a , b\": 1, \"\": 0 } ",
+ "{\"\\u007f\\u007f\\n\\r\\\"\\f\\b\\\\a , b\":1,\"\":0}"},
/* Testing the writer's ability to cut off invalid UTF-8 sequences. */
{"\"abc\xf0\x9d\x24\"", "\"abc\""},
{"\"\xff\"", "\"\""},
@@ -96,6 +96,9 @@ static testing_pair testing_pairs[] = {
{"\"\\udd1ef", NULL},
{"\"\\ud834\\ud834\"", NULL},
{"\"\\ud834\\u1234\"", NULL},
+ {"\"\\ud834]\"", NULL},
+ {"\"\\ud834 \"", NULL},
+ {"\"\\ud834\\\\\"", NULL},
/* Testing embedded invalid whitechars. */
{"\"\n\"", NULL},
{"\"\t\"", NULL},
@@ -110,9 +113,15 @@ static testing_pair testing_pairs[] = {
{"[[]", NULL},
{"[}", NULL},
{"{]", NULL},
- /*Testing trailing comma. */
+ /* Testing bad containers. */
+ {"{x}", NULL},
+ {"{x=0,y}", NULL},
+ /* Testing trailing comma. */
{"{,}", NULL},
{"[1,2,3,4,]", NULL},
+ {"{\"a\": 1, }", NULL},
+ /* Testing after-ending characters. */
+ {"{}x", NULL},
/* Testing having a key syntax in an array. */
{"[\"x\":0]", NULL},
/* Testing invalid numbers. */
@@ -160,7 +169,7 @@ static void test_pairs() {
}
static void test_atypical() {
- char *scratchpad = gpr_strdup("[[],[]]");
+ char *scratchpad = gpr_strdup("[[],[],[]]");
grpc_json *json = grpc_json_parse_string(scratchpad);
grpc_json *brother;
@@ -168,7 +177,8 @@ static void test_atypical() {
GPR_ASSERT(json->child);
brother = json->child->next;
grpc_json_destroy(json->child);
- json->child = brother;
+ GPR_ASSERT(json->child == brother);
+ grpc_json_destroy(json->child->next);
grpc_json_destroy(json);
gpr_free(scratchpad);
}
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index 4cfef7be78..a32ddd2ec7 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -31,8 +31,10 @@
*
*/
+#include <grpc/support/port_platform.h>
#include "src/core/security/credentials.h"
+#include <stdlib.h>
#include <string.h>
#include "src/core/httpcli/httpcli.h"
@@ -126,6 +128,8 @@ static const char test_signed_jwt[] =
static const char test_service_url[] = "https://foo.com/foo.v1";
static const char other_test_service_url[] = "https://bar.com/bar.v1";
+static const char test_method[] = "ThisIsNotAMethod";
+
/* -- Utils. -- */
static char *test_json_key_str(void) {
@@ -352,9 +356,10 @@ static void test_google_iam_creds(void) {
grpc_call_credentials *creds = grpc_google_iam_credentials_create(
test_google_iam_authorization_token, test_google_iam_authority_selector,
NULL);
- grpc_call_credentials_get_request_metadata(&exec_ctx, creds, NULL,
- test_service_url,
- check_google_iam_metadata, creds);
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
+ grpc_call_credentials_get_request_metadata(
+ &exec_ctx, creds, NULL, auth_md_ctx, check_google_iam_metadata, creds);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -375,10 +380,11 @@ static void test_access_token_creds(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_call_credentials *creds =
grpc_access_token_credentials_create("blah", NULL);
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, creds, NULL, test_service_url, check_access_token_metadata,
- creds);
+ &exec_ctx, creds, NULL, auth_md_ctx, check_access_token_metadata, creds);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -430,6 +436,8 @@ static void check_oauth2_google_iam_composite_metadata(
static void test_oauth2_google_iam_composite_creds(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
const grpc_call_credentials_array *creds_array;
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
grpc_call_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
"authorization", test_oauth2_bearer_token, 0);
grpc_call_credentials *google_iam_creds = grpc_google_iam_credentials_create(
@@ -450,7 +458,7 @@ static void test_oauth2_google_iam_composite_creds(void) {
GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, composite_creds, NULL, test_service_url,
+ &exec_ctx, composite_creds, NULL, auth_md_ctx,
check_oauth2_google_iam_composite_metadata, composite_creds);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -578,12 +586,14 @@ static void test_compute_engine_creds_success(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_call_credentials *compute_engine_creds =
grpc_google_compute_engine_credentials_create(NULL);
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
/* First request: http get should be called. */
grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
httpcli_post_should_not_be_called);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, compute_engine_creds, NULL, test_service_url,
+ &exec_ctx, compute_engine_creds, NULL, auth_md_ctx,
on_oauth2_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx);
@@ -591,7 +601,7 @@ static void test_compute_engine_creds_success(void) {
grpc_httpcli_set_override(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, compute_engine_creds, NULL, test_service_url,
+ &exec_ctx, compute_engine_creds, NULL, auth_md_ctx,
on_oauth2_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_finish(&exec_ctx);
@@ -601,12 +611,14 @@ static void test_compute_engine_creds_success(void) {
static void test_compute_engine_creds_failure(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
grpc_call_credentials *compute_engine_creds =
grpc_google_compute_engine_credentials_create(NULL);
grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override,
httpcli_post_should_not_be_called);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, compute_engine_creds, NULL, test_service_url,
+ &exec_ctx, compute_engine_creds, NULL, auth_md_ctx,
on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
grpc_call_credentials_unref(compute_engine_creds);
grpc_httpcli_set_override(NULL, NULL);
@@ -658,6 +670,8 @@ static int refresh_token_httpcli_post_failure(
static void test_refresh_token_creds_success(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
grpc_call_credentials *refresh_token_creds =
grpc_google_refresh_token_credentials_create(test_refresh_token_str,
NULL);
@@ -666,7 +680,7 @@ static void test_refresh_token_creds_success(void) {
grpc_httpcli_set_override(httpcli_get_should_not_be_called,
refresh_token_httpcli_post_success);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, refresh_token_creds, NULL, test_service_url,
+ &exec_ctx, refresh_token_creds, NULL, auth_md_ctx,
on_oauth2_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx);
@@ -674,7 +688,7 @@ static void test_refresh_token_creds_success(void) {
grpc_httpcli_set_override(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, refresh_token_creds, NULL, test_service_url,
+ &exec_ctx, refresh_token_creds, NULL, auth_md_ctx,
on_oauth2_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx);
@@ -685,13 +699,15 @@ static void test_refresh_token_creds_success(void) {
static void test_refresh_token_creds_failure(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
grpc_call_credentials *refresh_token_creds =
grpc_google_refresh_token_credentials_create(test_refresh_token_str,
NULL);
grpc_httpcli_set_override(httpcli_get_should_not_be_called,
refresh_token_httpcli_post_failure);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, refresh_token_creds, NULL, test_service_url,
+ &exec_ctx, refresh_token_creds, NULL, auth_md_ctx,
on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
grpc_call_credentials_unref(refresh_token_creds);
grpc_httpcli_set_override(NULL, NULL);
@@ -774,6 +790,8 @@ static void on_jwt_creds_get_metadata_failure(grpc_exec_ctx *exec_ctx,
static void test_jwt_creds_success(void) {
char *json_key_string = test_json_key_str();
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
grpc_call_credentials *jwt_creds =
grpc_service_account_jwt_access_credentials_create(
json_key_string, grpc_max_auth_token_lifetime, NULL);
@@ -781,7 +799,7 @@ static void test_jwt_creds_success(void) {
/* First request: jwt_encode_and_sign should be called. */
grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, jwt_creds, NULL, test_service_url,
+ &exec_ctx, jwt_creds, NULL, auth_md_ctx,
on_jwt_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx);
@@ -789,15 +807,16 @@ static void test_jwt_creds_success(void) {
grpc_jwt_encode_and_sign_set_override(
encode_and_sign_jwt_should_not_be_called);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, jwt_creds, NULL, test_service_url,
+ &exec_ctx, jwt_creds, NULL, auth_md_ctx,
on_jwt_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx);
/* Third request: Different service url so jwt_encode_and_sign should be
called again (no caching). */
+ auth_md_ctx.service_url = other_test_service_url;
grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, jwt_creds, NULL, other_test_service_url,
+ &exec_ctx, jwt_creds, NULL, auth_md_ctx,
on_jwt_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx);
@@ -809,13 +828,15 @@ static void test_jwt_creds_success(void) {
static void test_jwt_creds_signing_failure(void) {
char *json_key_string = test_json_key_str();
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
grpc_call_credentials *jwt_creds =
grpc_service_account_jwt_access_credentials_create(
json_key_string, grpc_max_auth_token_lifetime, NULL);
grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_failure);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, jwt_creds, NULL, test_service_url,
+ &exec_ctx, jwt_creds, NULL, auth_md_ctx,
on_jwt_creds_get_metadata_failure, (void *)test_user_data);
gpr_free(json_key_string);
@@ -857,7 +878,7 @@ static void test_google_default_creds_auth_key(void) {
gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
}
-static void test_google_default_creds_access_token(void) {
+static void test_google_default_creds_refresh_token(void) {
grpc_google_refresh_token_credentials *refresh;
grpc_composite_channel_credentials *creds;
grpc_flush_cached_google_default_credentials();
@@ -873,6 +894,102 @@ static void test_google_default_creds_access_token(void) {
gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
}
+static int default_creds_gce_detection_httpcli_get_success_override(
+ grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
+ gpr_timespec deadline, grpc_httpcli_response_cb on_response,
+ void *user_data) {
+ grpc_httpcli_response response = http_response(200, "");
+ grpc_httpcli_header header;
+ header.key = "Metadata-Flavor";
+ header.value = "Google";
+ response.hdr_count = 1;
+ response.hdrs = &header;
+ GPR_ASSERT(strcmp(request->path, "/") == 0);
+ GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0);
+ on_response(exec_ctx, user_data, &response);
+ return 1;
+}
+
+static char *null_well_known_creds_path_getter(void) { return NULL; }
+
+static void test_google_default_creds_gce(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_composite_channel_credentials *creds;
+ grpc_channel_credentials *cached_creds;
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
+ grpc_flush_cached_google_default_credentials();
+ gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
+ grpc_override_well_known_credentials_path_getter(
+ null_well_known_creds_path_getter);
+
+ /* Simulate a successful detection of GCE. */
+ grpc_httpcli_set_override(
+ default_creds_gce_detection_httpcli_get_success_override,
+ httpcli_post_should_not_be_called);
+ creds = (grpc_composite_channel_credentials *)
+ grpc_google_default_credentials_create();
+
+ /* Verify that the default creds actually embeds a GCE creds. */
+ GPR_ASSERT(creds != NULL);
+ GPR_ASSERT(creds->call_creds != NULL);
+ grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
+ httpcli_post_should_not_be_called);
+ grpc_call_credentials_get_request_metadata(
+ &exec_ctx, creds->call_creds, NULL, auth_md_ctx,
+ on_oauth2_creds_get_metadata_success, (void *)test_user_data);
+ grpc_exec_ctx_flush(&exec_ctx);
+ grpc_exec_ctx_finish(&exec_ctx);
+
+ /* Check that we get a cached creds if we call
+ grpc_google_default_credentials_create again.
+ GCE detection should not occur anymore either. */
+ grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+ httpcli_post_should_not_be_called);
+ cached_creds = grpc_google_default_credentials_create();
+ GPR_ASSERT(cached_creds == &creds->base);
+
+ /* Cleanup. */
+ grpc_channel_credentials_release(cached_creds);
+ grpc_channel_credentials_release(&creds->base);
+ grpc_httpcli_set_override(NULL, NULL);
+ grpc_override_well_known_credentials_path_getter(NULL);
+}
+
+static int default_creds_gce_detection_httpcli_get_failure_override(
+ grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
+ gpr_timespec deadline, grpc_httpcli_response_cb on_response,
+ void *user_data) {
+ /* No magic header. */
+ grpc_httpcli_response response = http_response(200, "");
+ GPR_ASSERT(strcmp(request->path, "/") == 0);
+ GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0);
+ on_response(exec_ctx, user_data, &response);
+ return 1;
+}
+
+static void test_no_google_default_creds(void) {
+ grpc_flush_cached_google_default_credentials();
+ gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
+ grpc_override_well_known_credentials_path_getter(
+ null_well_known_creds_path_getter);
+
+ /* Simulate a successful detection of GCE. */
+ grpc_httpcli_set_override(
+ default_creds_gce_detection_httpcli_get_failure_override,
+ httpcli_post_should_not_be_called);
+ GPR_ASSERT(grpc_google_default_credentials_create() == NULL);
+
+ /* Try a cached one. GCE detection should not occur anymore. */
+ grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+ httpcli_post_should_not_be_called);
+ GPR_ASSERT(grpc_google_default_credentials_create() == NULL);
+
+ /* Cleanup. */
+ grpc_httpcli_set_override(NULL, NULL);
+ grpc_override_well_known_credentials_path_getter(NULL);
+}
+
typedef enum {
PLUGIN_INITIAL_STATE,
PLUGIN_GET_METADATA_CALLED_STATE,
@@ -886,13 +1003,17 @@ typedef struct {
static const plugin_metadata plugin_md[] = {{"foo", "bar"}, {"hi", "there"}};
-static void plugin_get_metadata_success(void *state, const char *service_url,
+static void plugin_get_metadata_success(void *state,
+ grpc_auth_metadata_context context,
grpc_credentials_plugin_metadata_cb cb,
void *user_data) {
size_t i;
grpc_metadata md[GPR_ARRAY_SIZE(plugin_md)];
plugin_state *s = (plugin_state *)state;
- GPR_ASSERT(strcmp(service_url, test_service_url) == 0);
+ GPR_ASSERT(strcmp(context.service_url, test_service_url) == 0);
+ GPR_ASSERT(strcmp(context.method_name, test_method) == 0);
+ GPR_ASSERT(context.channel_auth_context == NULL);
+ GPR_ASSERT(context.reserved == NULL);
*s = PLUGIN_GET_METADATA_CALLED_STATE;
for (i = 0; i < GPR_ARRAY_SIZE(plugin_md); i++) {
memset(&md[i], 0, sizeof(grpc_metadata));
@@ -903,11 +1024,15 @@ static void plugin_get_metadata_success(void *state, const char *service_url,
cb(user_data, md, GPR_ARRAY_SIZE(md), GRPC_STATUS_OK, NULL);
}
-static void plugin_get_metadata_failure(void *state, const char *service_url,
+static void plugin_get_metadata_failure(void *state,
+ grpc_auth_metadata_context context,
grpc_credentials_plugin_metadata_cb cb,
void *user_data) {
plugin_state *s = (plugin_state *)state;
- GPR_ASSERT(strcmp(service_url, test_service_url) == 0);
+ GPR_ASSERT(strcmp(context.service_url, test_service_url) == 0);
+ GPR_ASSERT(strcmp(context.method_name, test_method) == 0);
+ GPR_ASSERT(context.channel_auth_context == NULL);
+ GPR_ASSERT(context.reserved == NULL);
*s = PLUGIN_GET_METADATA_CALLED_STATE;
cb(user_data, NULL, 0, GRPC_STATUS_UNAUTHENTICATED,
"Could not get metadata for plugin.");
@@ -945,6 +1070,8 @@ static void test_metadata_plugin_success(void) {
plugin_state state = PLUGIN_INITIAL_STATE;
grpc_metadata_credentials_plugin plugin;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
plugin.state = &state;
plugin.get_metadata = plugin_get_metadata_success;
@@ -953,8 +1080,8 @@ static void test_metadata_plugin_success(void) {
creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, creds, NULL, test_service_url,
- on_plugin_metadata_received_success, NULL);
+ &exec_ctx, creds, NULL, auth_md_ctx, on_plugin_metadata_received_success,
+ NULL);
GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
grpc_call_credentials_release(creds);
GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
@@ -966,6 +1093,8 @@ static void test_metadata_plugin_failure(void) {
plugin_state state = PLUGIN_INITIAL_STATE;
grpc_metadata_credentials_plugin plugin;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
+ NULL};
plugin.state = &state;
plugin.get_metadata = plugin_get_metadata_failure;
@@ -974,16 +1103,42 @@ static void test_metadata_plugin_failure(void) {
creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
grpc_call_credentials_get_request_metadata(
- &exec_ctx, creds, NULL, test_service_url,
- on_plugin_metadata_received_failure, NULL);
+ &exec_ctx, creds, NULL, auth_md_ctx, on_plugin_metadata_received_failure,
+ NULL);
GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
grpc_call_credentials_release(creds);
GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
grpc_exec_ctx_finish(&exec_ctx);
}
+static void test_get_well_known_google_credentials_file_path(void) {
+#ifdef GPR_POSIX_FILE
+ char *path;
+ char *old_home = gpr_getenv("HOME");
+ gpr_setenv("HOME", "/tmp");
+ path = grpc_get_well_known_google_credentials_file_path();
+ GPR_ASSERT(path != NULL);
+ GPR_ASSERT(0 == strcmp("/tmp/.config/" GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY
+ "/" GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE,
+ path));
+ gpr_free(path);
+#if defined(GPR_POSIX_ENV) || defined(GPR_LINUX_ENV)
+ unsetenv("HOME");
+ path = grpc_get_well_known_google_credentials_file_path();
+ GPR_ASSERT(path == NULL);
+#endif /* GPR_POSIX_ENV || GPR_LINUX_ENV */
+ gpr_setenv("HOME", old_home);
+ gpr_free(old_home);
+#else /* GPR_POSIX_FILE */
+ char *path = grpc_get_well_known_google_credentials_file_path();
+ GPR_ASSERT(path != NULL);
+ gpr_free(path);
+#endif
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
+ grpc_init();
test_empty_md_store();
test_ref_unref_empty_md_store();
test_add_to_empty_md_store();
@@ -1009,8 +1164,12 @@ int main(int argc, char **argv) {
test_jwt_creds_success();
test_jwt_creds_signing_failure();
test_google_default_creds_auth_key();
- test_google_default_creds_access_token();
+ test_google_default_creds_refresh_token();
+ test_google_default_creds_gce();
+ test_no_google_default_creds();
test_metadata_plugin_success();
test_metadata_plugin_failure();
+ test_get_well_known_google_credentials_file_path();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c
index fcfe8a6377..fb62bf4134 100644
--- a/test/core/security/oauth2_utils.c
+++ b/test/core/security/oauth2_utils.c
@@ -80,13 +80,16 @@ char *grpc_test_fetch_oauth2_token_with_credentials(
oauth2_request request;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_closure do_nothing_closure;
+ grpc_auth_metadata_context null_ctx = {"", "", NULL, NULL};
+
grpc_pollset_init(&request.pollset);
request.is_done = 0;
grpc_closure_init(&do_nothing_closure, do_nothing, NULL);
grpc_call_credentials_get_request_metadata(&exec_ctx, creds, &request.pollset,
- "", on_oauth2_response, &request);
+ null_ctx, on_oauth2_response,
+ &request);
grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c
index eb63724715..50fe61c996 100644
--- a/test/core/security/print_google_default_creds_token.c
+++ b/test/core/security/print_google_default_creds_token.c
@@ -74,10 +74,13 @@ int main(int argc, char **argv) {
synchronizer sync;
grpc_channel_credentials *creds = NULL;
char *service_url = "https://test.foo.google.com/Foo";
+ grpc_auth_metadata_context context;
gpr_cmdline *cl = gpr_cmdline_create("print_google_default_creds_token");
gpr_cmdline_add_string(cl, "service_url",
"Service URL for the token request.", &service_url);
gpr_cmdline_parse(cl, argc, argv);
+ memset(&context, 0, sizeof(context));
+ context.service_url = service_url;
grpc_init();
@@ -93,7 +96,7 @@ int main(int argc, char **argv) {
grpc_call_credentials_get_request_metadata(
&exec_ctx, ((grpc_composite_channel_credentials *)creds)->call_creds,
- &sync.pollset, service_url, on_metadata_response, &sync);
+ &sync.pollset, context, on_metadata_response, &sync);
gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
while (!sync.is_done) {
diff --git a/test/core/security/security_connector_test.c b/test/core/security/security_connector_test.c
index 3f6c592b0b..0dcffa40ce 100644
--- a/test/core/security/security_connector_test.c
+++ b/test/core/security/security_connector_test.c
@@ -60,8 +60,39 @@ static int check_transport_security_type(const grpc_auth_context *ctx) {
return 1;
}
+static int check_peer_property(const tsi_peer *peer,
+ const tsi_peer_property *expected) {
+ size_t i;
+ for (i = 0; i < peer->property_count; i++) {
+ const tsi_peer_property *prop = &peer->properties[i];
+ if ((strcmp(prop->name, expected->name) == 0) &&
+ (prop->value.length == expected->value.length) &&
+ (memcmp(prop->value.data, expected->value.data,
+ expected->value.length) == 0)) {
+ return 1;
+ }
+ }
+ return 0; /* Not found... */
+}
+
+static int check_ssl_peer_equivalence(const tsi_peer *original,
+ const tsi_peer *reconstructed) {
+ /* The reconstructed peer only has CN and SAN properties. */
+ size_t i;
+ for (i = 0; i < original->property_count; i++) {
+ const tsi_peer_property *prop = &original->properties[i];
+ if ((strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) ||
+ (strcmp(prop->name, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) ==
+ 0)) {
+ if (!check_peer_property(reconstructed, prop)) return 0;
+ }
+ }
+ return 1;
+}
+
static void test_unauthenticated_ssl_peer(void) {
tsi_peer peer;
+ tsi_peer rpeer;
grpc_auth_context *ctx;
GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK);
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
@@ -72,6 +103,10 @@ static void test_unauthenticated_ssl_peer(void) {
GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx));
GPR_ASSERT(check_transport_security_type(ctx));
+ rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
+ GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
+
+ tsi_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
@@ -128,6 +163,7 @@ static int check_x509_cn(const grpc_auth_context *ctx,
static void test_cn_only_ssl_peer_to_auth_context(void) {
tsi_peer peer;
+ tsi_peer rpeer;
grpc_auth_context *ctx;
const char *expected_cn = "cn1";
GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
@@ -144,12 +180,17 @@ static void test_cn_only_ssl_peer_to_auth_context(void) {
GPR_ASSERT(check_transport_security_type(ctx));
GPR_ASSERT(check_x509_cn(ctx, expected_cn));
+ rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
+ GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
+
+ tsi_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
static void test_cn_and_one_san_ssl_peer_to_auth_context(void) {
tsi_peer peer;
+ tsi_peer rpeer;
grpc_auth_context *ctx;
const char *expected_cn = "cn1";
const char *expected_san = "san1";
@@ -171,12 +212,17 @@ static void test_cn_and_one_san_ssl_peer_to_auth_context(void) {
GPR_ASSERT(check_transport_security_type(ctx));
GPR_ASSERT(check_x509_cn(ctx, expected_cn));
+ rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
+ GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
+
+ tsi_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) {
tsi_peer peer;
+ tsi_peer rpeer;
grpc_auth_context *ctx;
const char *expected_cn = "cn1";
const char *expected_sans[] = {"san1", "san2", "san3"};
@@ -202,6 +248,10 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) {
GPR_ASSERT(check_transport_security_type(ctx));
GPR_ASSERT(check_x509_cn(ctx, expected_cn));
+ rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
+ GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
+
+ tsi_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
@@ -209,6 +259,7 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) {
static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(
void) {
tsi_peer peer;
+ tsi_peer rpeer;
grpc_auth_context *ctx;
const char *expected_cn = "cn1";
const char *expected_sans[] = {"san1", "san2", "san3"};
@@ -238,10 +289,16 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(
GPR_ASSERT(check_transport_security_type(ctx));
GPR_ASSERT(check_x509_cn(ctx, expected_cn));
+ rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
+ GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
+
+ tsi_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
+/* TODO(jboeuf): Unit-test tsi_shallow_peer_from_auth_context. */
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
grpc_init();
diff --git a/test/core/support/alloc_test.c b/test/core/support/alloc_test.c
new file mode 100644
index 0000000000..dc0a2acfa5
--- /dev/null
+++ b/test/core/support/alloc_test.c
@@ -0,0 +1,68 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/log.h>
+#include <grpc/support/alloc.h>
+#include "test/core/util/test_config.h"
+
+static void *fake_malloc(size_t size) { return (void *)size; }
+
+static void *fake_realloc(void *addr, size_t size) { return (void *)size; }
+
+static void fake_free(void *addr) { *((gpr_intptr *)addr) = 0xdeadd00d; }
+
+static void test_custom_allocs() {
+ const gpr_allocation_functions default_fns = gpr_get_allocation_functions();
+ gpr_intptr addr_to_free = 0;
+ int *i;
+ gpr_allocation_functions fns = {fake_malloc, fake_realloc, fake_free};
+
+ gpr_set_allocation_functions(fns);
+ GPR_ASSERT((void*)(size_t)0xdeadbeef == gpr_malloc(0xdeadbeef));
+ GPR_ASSERT((void*)(size_t)0xcafed00d == gpr_realloc(0, 0xcafed00d));
+
+ gpr_free(&addr_to_free);
+ GPR_ASSERT(addr_to_free == 0xdeadd00d);
+
+ /* Restore and check we don't get funky values and that we don't leak */
+ gpr_set_allocation_functions(default_fns);
+ GPR_ASSERT((void *)1 != (i = gpr_malloc(sizeof(*i))));
+ GPR_ASSERT((void *)2 != (i = gpr_realloc(i, 2)));
+ gpr_free(i);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ test_custom_allocs();
+ return 0;
+}
diff --git a/test/core/support/cmdline_test.c b/test/core/support/cmdline_test.c
index 1c77c15233..4730fcc1b5 100644
--- a/test/core/support/cmdline_test.c
+++ b/test/core/support/cmdline_test.c
@@ -40,7 +40,7 @@
#include <grpc/support/useful.h>
#include "test/core/util/test_config.h"
-#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FILE__)
+#define LOG_TEST() gpr_log(GPR_INFO, "test at %s:%d", __FILE__, __LINE__)
static void test_simple_int(void) {
int x = 1;
@@ -273,6 +273,44 @@ static void test_many(void) {
gpr_cmdline_destroy(cl);
}
+static void extra_arg_cb(void *user_data, const char *arg) {
+ int *count = user_data;
+ GPR_ASSERT(arg != NULL);
+ GPR_ASSERT(strlen(arg) == 1);
+ GPR_ASSERT(arg[0] == 'a' + *count);
+ ++*count;
+}
+
+static void test_extra(void) {
+ gpr_cmdline *cl;
+ int count = 0;
+ char *args[] = {(char *)__FILE__, "a", "b", "c"};
+
+ LOG_TEST();
+
+ cl = gpr_cmdline_create(NULL);
+ gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
+ &count);
+ gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
+ GPR_ASSERT(count == 3);
+ gpr_cmdline_destroy(cl);
+}
+
+static void test_extra_dashdash(void) {
+ gpr_cmdline *cl;
+ int count = 0;
+ char *args[] = {(char *)__FILE__, "--", "a", "b", "c"};
+
+ LOG_TEST();
+
+ cl = gpr_cmdline_create(NULL);
+ gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
+ &count);
+ gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
+ GPR_ASSERT(count == 3);
+ gpr_cmdline_destroy(cl);
+}
+
static void test_usage(void) {
gpr_cmdline *cl;
char *usage;
@@ -281,20 +319,154 @@ static void test_usage(void) {
int x = 0;
int flag = 2;
+ LOG_TEST();
+
cl = gpr_cmdline_create(NULL);
gpr_cmdline_add_string(cl, "str", NULL, &str);
gpr_cmdline_add_int(cl, "x", NULL, &x);
gpr_cmdline_add_flag(cl, "flag", NULL, &flag);
+ gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
+ NULL);
usage = gpr_cmdline_usage_string(cl, "test");
- GPR_ASSERT(
- 0 == strcmp(usage,
- "Usage: test [--str=string] [--x=int] [--flag|--no-flag]\n"));
+ GPR_ASSERT(0 == strcmp(usage,
+ "Usage: test [--str=string] [--x=int] "
+ "[--flag|--no-flag] [file...]\n"));
+ gpr_free(usage);
+
+ usage = gpr_cmdline_usage_string(cl, "/foo/test");
+ GPR_ASSERT(0 == strcmp(usage,
+ "Usage: test [--str=string] [--x=int] "
+ "[--flag|--no-flag] [file...]\n"));
gpr_free(usage);
gpr_cmdline_destroy(cl);
}
+static void test_help(void) {
+ gpr_cmdline *cl;
+
+ char *str = NULL;
+ int x = 0;
+ int flag = 2;
+
+ char *help[] = {(char *)__FILE__, "-h"};
+
+ LOG_TEST();
+
+ cl = gpr_cmdline_create(NULL);
+ gpr_cmdline_set_survive_failure(cl);
+ gpr_cmdline_add_string(cl, "str", NULL, &str);
+ gpr_cmdline_add_int(cl, "x", NULL, &x);
+ gpr_cmdline_add_flag(cl, "flag", NULL, &flag);
+ gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
+ NULL);
+
+ GPR_ASSERT(0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(help), help));
+
+ gpr_cmdline_destroy(cl);
+}
+
+static void test_badargs1(void) {
+ gpr_cmdline *cl;
+
+ char *str = NULL;
+ int x = 0;
+ int flag = 2;
+
+ char *bad_arg_name[] = {(char *)__FILE__, "--y"};
+
+ LOG_TEST();
+
+ cl = gpr_cmdline_create(NULL);
+ gpr_cmdline_set_survive_failure(cl);
+ gpr_cmdline_add_string(cl, "str", NULL, &str);
+ gpr_cmdline_add_int(cl, "x", NULL, &x);
+ gpr_cmdline_add_flag(cl, "flag", NULL, &flag);
+ gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
+ NULL);
+
+ GPR_ASSERT(0 ==
+ gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_arg_name), bad_arg_name));
+
+ gpr_cmdline_destroy(cl);
+}
+
+static void test_badargs2(void) {
+ gpr_cmdline *cl;
+
+ char *str = NULL;
+ int x = 0;
+ int flag = 2;
+
+ char *bad_int_value[] = {(char *)__FILE__, "--x", "henry"};
+
+ LOG_TEST();
+
+ cl = gpr_cmdline_create(NULL);
+ gpr_cmdline_set_survive_failure(cl);
+ gpr_cmdline_add_string(cl, "str", NULL, &str);
+ gpr_cmdline_add_int(cl, "x", NULL, &x);
+ gpr_cmdline_add_flag(cl, "flag", NULL, &flag);
+ gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
+ NULL);
+
+ GPR_ASSERT(
+ 0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_int_value), bad_int_value));
+
+ gpr_cmdline_destroy(cl);
+}
+
+static void test_badargs3(void) {
+ gpr_cmdline *cl;
+
+ char *str = NULL;
+ int x = 0;
+ int flag = 2;
+
+ char *bad_bool_value[] = {(char *)__FILE__, "--flag=henry"};
+
+ LOG_TEST();
+
+ cl = gpr_cmdline_create(NULL);
+ gpr_cmdline_set_survive_failure(cl);
+ gpr_cmdline_add_string(cl, "str", NULL, &str);
+ gpr_cmdline_add_int(cl, "x", NULL, &x);
+ gpr_cmdline_add_flag(cl, "flag", NULL, &flag);
+ gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
+ NULL);
+
+ GPR_ASSERT(0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_bool_value),
+ bad_bool_value));
+
+ gpr_cmdline_destroy(cl);
+}
+
+static void test_badargs4(void) {
+ gpr_cmdline *cl;
+
+ char *str = NULL;
+ int x = 0;
+ int flag = 2;
+
+ char *bad_bool_value[] = {(char *)__FILE__, "--no-str"};
+
+ LOG_TEST();
+
+ cl = gpr_cmdline_create(NULL);
+ gpr_cmdline_set_survive_failure(cl);
+ gpr_cmdline_add_string(cl, "str", NULL, &str);
+ gpr_cmdline_add_int(cl, "x", NULL, &x);
+ gpr_cmdline_add_flag(cl, "flag", NULL, &flag);
+ gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
+ NULL);
+
+ GPR_ASSERT(0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_bool_value),
+ bad_bool_value));
+
+ gpr_cmdline_destroy(cl);
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_simple_int();
@@ -312,6 +484,13 @@ int main(int argc, char **argv) {
test_flag_val_true();
test_flag_val_false();
test_many();
+ test_extra();
+ test_extra_dashdash();
test_usage();
+ test_help();
+ test_badargs1();
+ test_badargs2();
+ test_badargs3();
+ test_badargs4();
return 0;
}
diff --git a/test/core/support/slice_buffer_test.c b/test/core/support/slice_buffer_test.c
index a48278434f..cf2da84c2b 100644
--- a/test/core/support/slice_buffer_test.c
+++ b/test/core/support/slice_buffer_test.c
@@ -35,13 +35,12 @@
#include <grpc/support/slice_buffer.h>
#include "test/core/util/test_config.h"
-int main(int argc, char **argv) {
+void test_slice_buffer_add() {
gpr_slice_buffer buf;
gpr_slice aaa = gpr_slice_from_copied_string("aaa");
gpr_slice bb = gpr_slice_from_copied_string("bb");
size_t i;
- grpc_test_init(argc, argv);
gpr_slice_buffer_init(&buf);
for (i = 0; i < 10; i++) {
gpr_slice_ref(aaa);
@@ -70,6 +69,61 @@ int main(int argc, char **argv) {
GPR_ASSERT(buf.count == 0);
GPR_ASSERT(buf.length == 0);
gpr_slice_buffer_destroy(&buf);
+}
+
+void test_slice_buffer_move_first() {
+ gpr_slice slices[3];
+ gpr_slice_buffer src;
+ gpr_slice_buffer dst;
+ int idx = 0;
+ size_t src_len = 0;
+ size_t dst_len = 0;
+
+ slices[0] = gpr_slice_from_copied_string("aaa");
+ slices[1] = gpr_slice_from_copied_string("bbbb");
+ slices[2] = gpr_slice_from_copied_string("ccc");
+
+ gpr_slice_buffer_init(&src);
+ gpr_slice_buffer_init(&dst);
+ for (idx = 0; idx < 3; idx++) {
+ gpr_slice_ref(slices[idx]);
+ /* For this test, it is important that we add each slice at a new
+ slice index */
+ gpr_slice_buffer_add_indexed(&src, slices[idx]);
+ gpr_slice_buffer_add_indexed(&dst, slices[idx]);
+ }
+
+ /* Case 1: Move more than the first slice's length from src to dst */
+ src_len = src.length;
+ dst_len = dst.length;
+ gpr_slice_buffer_move_first(&src, 4, &dst);
+ src_len -= 4;
+ dst_len += 4;
+ GPR_ASSERT(src.length == src_len);
+ GPR_ASSERT(dst.length == dst_len);
+
+ /* src now has two slices ["bbb"] and ["ccc"] */
+ /* Case 2: Move the first slice from src to dst */
+ gpr_slice_buffer_move_first(&src, 3, &dst);
+ src_len -= 3;
+ dst_len += 3;
+ GPR_ASSERT(src.length == src_len);
+ GPR_ASSERT(dst.length == dst_len);
+
+ /* src now has one slice ["ccc"] */
+ /* Case 3: Move less than the first slice's length from src to dst*/
+ gpr_slice_buffer_move_first(&src, 2, &dst);
+ src_len -= 2;
+ dst_len += 2;
+ GPR_ASSERT(src.length == src.length);
+ GPR_ASSERT(dst.length == dst.length);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+
+ test_slice_buffer_add();
+ test_slice_buffer_move_first();
return 0;
}
diff --git a/test/core/support/slice_test.c b/test/core/support/slice_test.c
index 1d202f0618..9e0e22c24b 100644
--- a/test/core/support/slice_test.c
+++ b/test/core/support/slice_test.c
@@ -94,12 +94,27 @@ static void do_nothing_with_len_1(void *ignored, size_t len) {
static void test_slice_new_with_len_returns_something_sensible(void) {
gpr_uint8 x;
+ int num_refs = 5; /* To test adding/removing an arbitrary number of refs */
+ int i;
gpr_slice slice = gpr_slice_new_with_len(&x, 1, do_nothing_with_len_1);
- GPR_ASSERT(slice.refcount);
+ GPR_ASSERT(slice.refcount); /* ref count is initialized to 1 at this point */
GPR_ASSERT(slice.data.refcounted.bytes == &x);
GPR_ASSERT(slice.data.refcounted.length == 1);
GPR_ASSERT(do_nothing_with_len_1_calls == 0);
+
+ /* Add an arbitrary number of refs to the slice and remoe the refs. This is to
+ make sure that that the destroy callback (i.e do_nothing_with_len_1()) is
+ not called until the last unref operation */
+ for (i = 0; i < num_refs; i++) {
+ gpr_slice_ref(slice);
+ }
+ for (i = 0; i < num_refs; i++) {
+ gpr_slice_unref(slice);
+ }
+ GPR_ASSERT(do_nothing_with_len_1_calls == 0); /* Shouldn't be called yet */
+
+ /* last unref */
gpr_slice_unref(slice);
GPR_ASSERT(do_nothing_with_len_1_calls == 1);
}
diff --git a/test/core/support/string_test.c b/test/core/support/string_test.c
index f62cbe3435..c97d3176c5 100644
--- a/test/core/support/string_test.c
+++ b/test/core/support/string_test.c
@@ -33,6 +33,7 @@
#include "src/core/support/string.h"
+#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@@ -286,6 +287,53 @@ static void test_strsplit(void) {
gpr_free(parts);
}
+static void test_ltoa() {
+ char *str;
+ char buf[GPR_LTOA_MIN_BUFSIZE];
+
+ LOG_TEST_NAME("test_ltoa");
+
+ /* zero */
+ GPR_ASSERT(1 == gpr_ltoa(0, buf));
+ GPR_ASSERT(0 == strcmp("0", buf));
+
+ /* positive number */
+ GPR_ASSERT(3 == gpr_ltoa(123, buf));
+ GPR_ASSERT(0 == strcmp("123", buf));
+
+ /* negative number */
+ GPR_ASSERT(6 == gpr_ltoa(-12345, buf));
+ GPR_ASSERT(0 == strcmp("-12345", buf));
+
+ /* large negative - we don't know the size of long in advance */
+ GPR_ASSERT(gpr_asprintf(&str, "%lld", (long long)LONG_MIN));
+ GPR_ASSERT(strlen(str) == (size_t)gpr_ltoa(LONG_MIN, buf));
+ GPR_ASSERT(0 == strcmp(str, buf));
+ gpr_free(str);
+}
+
+static void test_int64toa() {
+ char buf[GPR_INT64TOA_MIN_BUFSIZE];
+
+ LOG_TEST_NAME("test_int64toa");
+
+ /* zero */
+ GPR_ASSERT(1 == gpr_int64toa(0, buf));
+ GPR_ASSERT(0 == strcmp("0", buf));
+
+ /* positive */
+ GPR_ASSERT(3 == gpr_int64toa(123, buf));
+ GPR_ASSERT(0 == strcmp("123", buf));
+
+ /* large positive */
+ GPR_ASSERT(19 == gpr_int64toa(9223372036854775807LL, buf));
+ GPR_ASSERT(0 == strcmp("9223372036854775807", buf));
+
+ /* large negative */
+ GPR_ASSERT(20 == gpr_int64toa(-9223372036854775807LL - 1, buf));
+ GPR_ASSERT(0 == strcmp("-9223372036854775808", buf));
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_strdup();
@@ -296,5 +344,7 @@ int main(int argc, char **argv) {
test_strjoin();
test_strjoin_sep();
test_strsplit();
+ test_ltoa();
+ test_int64toa();
return 0;
}
diff --git a/test/core/support/sync_test.c b/test/core/support/sync_test.c
index 220b16b60f..73f68e4dbd 100644
--- a/test/core/support/sync_test.c
+++ b/test/core/support/sync_test.c
@@ -153,6 +153,7 @@ struct test {
gpr_int64 counter;
int thread_count; /* used to allocate thread ids */
int done; /* threads not yet completed */
+ int incr_step; /* how much to increment/decrement refcount each time */
gpr_mu mu; /* protects iterations, counter, thread_count, done */
@@ -170,13 +171,14 @@ struct test {
};
/* Return pointer to a new struct test. */
-static struct test *test_new(int threads, gpr_int64 iterations) {
+static struct test *test_new(int threads, gpr_int64 iterations, int incr_step) {
struct test *m = gpr_malloc(sizeof(*m));
m->threads = threads;
m->iterations = iterations;
m->counter = 0;
m->thread_count = 0;
m->done = threads;
+ m->incr_step = incr_step;
gpr_mu_init(&m->mu);
gpr_cv_init(&m->cv);
gpr_cv_init(&m->done_cv);
@@ -238,9 +240,12 @@ static void mark_thread_done(struct test *m) {
/* Test several threads running (*body)(struct test *m) for increasing settings
of m->iterations, until about timeout_s to 2*timeout_s seconds have elapsed.
- If extra!=NULL, run (*extra)(m) in an additional thread. */
+ If extra!=NULL, run (*extra)(m) in an additional thread.
+ incr_step controls by how much m->refcount should be incremented/decremented
+ (if at all) each time in the tests.
+ */
static void test(const char *name, void (*body)(void *m),
- void (*extra)(void *m), int timeout_s) {
+ void (*extra)(void *m), int timeout_s, int incr_step) {
gpr_int64 iterations = 1024;
struct test *m;
gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
@@ -251,7 +256,7 @@ static void test(const char *name, void (*body)(void *m),
while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) {
iterations <<= 1;
fprintf(stderr, " %ld", (long)iterations);
- m = test_new(10, iterations);
+ m = test_new(10, iterations, incr_step);
if (extra != NULL) {
gpr_thd_id id;
GPR_ASSERT(gpr_thd_new(&id, extra, m, NULL));
@@ -259,7 +264,7 @@ static void test(const char *name, void (*body)(void *m),
}
test_create_threads(m, body);
test_wait(m);
- if (m->counter != m->threads * m->iterations) {
+ if (m->counter != m->threads * m->iterations * m->incr_step) {
fprintf(stderr, "counter %ld threads %d iterations %ld\n",
(long)m->counter, m->threads, (long)m->iterations);
GPR_ASSERT(0);
@@ -267,7 +272,7 @@ static void test(const char *name, void (*body)(void *m),
test_destroy(m);
}
time_taken = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start);
- fprintf(stderr, " done %ld.%09d s\n", (long)time_taken.tv_sec,
+ fprintf(stderr, " done %lld.%09d s\n", (long long)time_taken.tv_sec,
(int)time_taken.tv_nsec);
}
@@ -406,14 +411,18 @@ static void statsinc(void *v /*=m*/) {
mark_thread_done(m);
}
-/* Increment m->refcount m->iterations times, decrement m->thread_refcount
- once, and if it reaches zero, set m->event to (void*)1; then mark thread as
- done. */
+/* Increment m->refcount by m->incr_step for m->iterations times. Decrement
+ m->thread_refcount once, and if it reaches zero, set m->event to (void*)1;
+ then mark thread as done. */
static void refinc(void *v /*=m*/) {
struct test *m = v;
gpr_int64 i;
for (i = 0; i != m->iterations; i++) {
- gpr_ref(&m->refcount);
+ if (m->incr_step == 1) {
+ gpr_ref(&m->refcount);
+ } else {
+ gpr_refn(&m->refcount, m->incr_step);
+ }
}
if (gpr_unref(&m->thread_refcount)) {
gpr_event_set(&m->event, (void *)1);
@@ -421,12 +430,12 @@ static void refinc(void *v /*=m*/) {
mark_thread_done(m);
}
-/* Wait until m->event is set to (void *)1, then decrement m->refcount
- m->stats_counter m->iterations times, and ensure that the last decrement
- caused the counter to reach zero, then mark thread as done. */
+/* Wait until m->event is set to (void *)1, then decrement m->refcount by 1
+ (m->threads * m->iterations * m->incr_step) times, and ensure that the last
+ decrement caused the counter to reach zero, then mark thread as done. */
static void refcheck(void *v /*=m*/) {
struct test *m = v;
- gpr_int64 n = m->iterations * m->threads;
+ gpr_int64 n = m->iterations * m->threads * m->incr_step;
gpr_int64 i;
GPR_ASSERT(gpr_event_wait(&m->event, gpr_inf_future(GPR_CLOCK_REALTIME)) ==
(void *)1);
@@ -444,13 +453,16 @@ static void refcheck(void *v /*=m*/) {
int main(int argc, char *argv[]) {
grpc_test_init(argc, argv);
- test("mutex", &inc, NULL, 1);
- test("mutex try", &inctry, NULL, 1);
- test("cv", &inc_by_turns, NULL, 1);
- test("timedcv", &inc_with_1ms_delay, NULL, 1);
- test("queue", &many_producers, &consumer, 10);
- test("stats_counter", &statsinc, NULL, 1);
- test("refcount", &refinc, &refcheck, 1);
- test("timedevent", &inc_with_1ms_delay_event, NULL, 1);
+ test("mutex", &inc, NULL, 1, 1);
+ test("mutex try", &inctry, NULL, 1, 1);
+ test("cv", &inc_by_turns, NULL, 1, 1);
+ test("timedcv", &inc_with_1ms_delay, NULL, 1, 1);
+ test("queue", &many_producers, &consumer, 10, 1);
+ test("stats_counter", &statsinc, NULL, 1, 1);
+ test("refcount by 1", &refinc, &refcheck, 1, 1);
+ test("refcount by 3", &refinc, &refcheck, 1, 3); /* incr_step of 3 is an
+ arbitrary choice. Any
+ number > 1 is okay here */
+ test("timedevent", &inc_with_1ms_delay_event, NULL, 1, 1);
return 0;
}
diff --git a/test/core/support/thd_test.c b/test/core/support/thd_test.c
index faba33c5e8..f7807d280a 100644
--- a/test/core/support/thd_test.c
+++ b/test/core/support/thd_test.c
@@ -62,6 +62,19 @@ static void thd_body(void *v) {
static void thd_body_joinable(void *v) {}
+/* Test thread options work as expected */
+static void test_options(void) {
+ gpr_thd_options options = gpr_thd_options_default();
+ GPR_ASSERT(!gpr_thd_options_is_joinable(&options));
+ GPR_ASSERT(gpr_thd_options_is_detached(&options));
+ gpr_thd_options_set_joinable(&options);
+ GPR_ASSERT(gpr_thd_options_is_joinable(&options));
+ GPR_ASSERT(!gpr_thd_options_is_detached(&options));
+ gpr_thd_options_set_detached(&options);
+ GPR_ASSERT(!gpr_thd_options_is_joinable(&options));
+ GPR_ASSERT(gpr_thd_options_is_detached(&options));
+}
+
/* Test that we can create a number of threads and wait for them. */
static void test(void) {
int i;
@@ -96,6 +109,7 @@ static void test(void) {
int main(int argc, char *argv[]) {
grpc_test_init(argc, argv);
+ test_options();
test();
return 0;
}
diff --git a/test/core/support/time_test.c b/test/core/support/time_test.c
index ce35edd83c..b921052e7b 100644
--- a/test/core/support/time_test.c
+++ b/test/core/support/time_test.c
@@ -98,7 +98,7 @@ static void test_values(void) {
fprintf(stderr, "far future ");
i_to_s(x.tv_sec, 16, 16, &to_fp, stderr);
fprintf(stderr, "\n");
- GPR_ASSERT(x.tv_sec >= INT_MAX);
+ GPR_ASSERT(x.tv_sec == INT64_MAX);
fprintf(stderr, "far future ");
ts_to_s(x, &to_fp, stderr);
fprintf(stderr, "\n");
@@ -107,7 +107,7 @@ static void test_values(void) {
fprintf(stderr, "far past ");
i_to_s(x.tv_sec, 16, 16, &to_fp, stderr);
fprintf(stderr, "\n");
- GPR_ASSERT(x.tv_sec <= INT_MIN);
+ GPR_ASSERT(x.tv_sec == INT64_MIN);
fprintf(stderr, "far past ");
ts_to_s(x, &to_fp, stderr);
fprintf(stderr, "\n");
diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c
index 6b41698717..c87fbdc897 100644
--- a/test/core/surface/byte_buffer_reader_test.c
+++ b/test/core/surface/byte_buffer_reader_test.c
@@ -217,6 +217,42 @@ static void test_readall(void) {
grpc_byte_buffer_destroy(buffer);
}
+static void test_byte_buffer_copy(void) {
+ char *lotsa_as[512];
+ char *lotsa_bs[1024];
+ gpr_slice slices[2];
+ grpc_byte_buffer *buffer;
+ grpc_byte_buffer *copied_buffer;
+ grpc_byte_buffer_reader reader;
+ gpr_slice slice_out;
+
+ LOG_TEST("test_byte_buffer_copy");
+
+ memset(lotsa_as, 'a', 512);
+ memset(lotsa_bs, 'b', 1024);
+ /* use slices large enough to overflow inlining */
+ slices[0] = gpr_slice_malloc(512);
+ memcpy(GPR_SLICE_START_PTR(slices[0]), lotsa_as, 512);
+ slices[1] = gpr_slice_malloc(1024);
+ memcpy(GPR_SLICE_START_PTR(slices[1]), lotsa_bs, 1024);
+
+ buffer = grpc_raw_byte_buffer_create(slices, 2);
+ gpr_slice_unref(slices[0]);
+ gpr_slice_unref(slices[1]);
+ copied_buffer = grpc_byte_buffer_copy(buffer);
+
+ grpc_byte_buffer_reader_init(&reader, copied_buffer);
+ slice_out = grpc_byte_buffer_reader_readall(&reader);
+
+ GPR_ASSERT(GPR_SLICE_LENGTH(slice_out) == 512 + 1024);
+ GPR_ASSERT(memcmp(GPR_SLICE_START_PTR(slice_out), lotsa_as, 512) == 0);
+ GPR_ASSERT(memcmp(&(GPR_SLICE_START_PTR(slice_out)[512]), lotsa_bs, 1024) ==
+ 0);
+ gpr_slice_unref(slice_out);
+ grpc_byte_buffer_destroy(buffer);
+ grpc_byte_buffer_destroy(copied_buffer);
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_read_one_slice();
@@ -225,6 +261,7 @@ int main(int argc, char **argv) {
test_read_gzip_compressed_slice();
test_read_deflate_compressed_slice();
test_byte_buffer_from_reader();
+ test_byte_buffer_copy();
test_readall();
return 0;
}
diff --git a/test/core/surface/channel_create_test.c b/test/core/surface/channel_create_test.c
new file mode 100644
index 0000000000..044e766473
--- /dev/null
+++ b/test/core/surface/channel_create_test.c
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include "src/core/client_config/resolver_registry.h"
+#include "test/core/util/test_config.h"
+
+void test_unknown_scheme_target(void) {
+ grpc_channel *chan;
+ /* avoid default prefix */
+ grpc_resolver_registry_shutdown();
+ grpc_resolver_registry_init("");
+
+ chan = grpc_insecure_channel_create("blah://blah", NULL, NULL);
+ GPR_ASSERT(chan == NULL);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+ test_unknown_scheme_target();
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c
index e3fc789788..8a24d826bb 100644
--- a/test/core/surface/completion_queue_test.c
+++ b/test/core/surface/completion_queue_test.c
@@ -89,7 +89,7 @@ static void test_cq_end_op(void) {
cc = grpc_completion_queue_create(NULL);
- grpc_cq_begin_op(cc);
+ grpc_cq_begin_op(cc, tag);
grpc_cq_end_op(&exec_ctx, cc, tag, 1, do_nothing_end_completion, NULL,
&completion);
@@ -148,7 +148,7 @@ static void test_pluck(void) {
cc = grpc_completion_queue_create(NULL);
for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
- grpc_cq_begin_op(cc);
+ grpc_cq_begin_op(cc, tags[i]);
grpc_cq_end_op(&exec_ctx, cc, tags[i], 1, do_nothing_end_completion, NULL,
&completions[i]);
}
@@ -160,7 +160,7 @@ static void test_pluck(void) {
}
for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
- grpc_cq_begin_op(cc);
+ grpc_cq_begin_op(cc, tags[i]);
grpc_cq_end_op(&exec_ctx, cc, tags[i], 1, do_nothing_end_completion, NULL,
&completions[i]);
}
@@ -175,6 +175,77 @@ static void test_pluck(void) {
grpc_exec_ctx_finish(&exec_ctx);
}
+static void test_pluck_after_shutdown(void) {
+ grpc_event ev;
+ grpc_completion_queue *cc;
+
+ LOG_TEST("test_pluck_after_shutdown");
+ cc = grpc_completion_queue_create(NULL);
+ grpc_completion_queue_shutdown(cc);
+ ev = grpc_completion_queue_pluck(cc, NULL, gpr_inf_future(GPR_CLOCK_REALTIME),
+ NULL);
+ GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN);
+ grpc_completion_queue_destroy(cc);
+}
+
+struct thread_state {
+ grpc_completion_queue *cc;
+ void *tag;
+};
+
+static void pluck_one(void *arg) {
+ struct thread_state *state = arg;
+ grpc_completion_queue_pluck(state->cc, state->tag,
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+}
+
+static void test_too_many_plucks(void) {
+ grpc_event ev;
+ grpc_completion_queue *cc;
+ void *tags[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS];
+ grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)];
+ gpr_thd_id thread_ids[GPR_ARRAY_SIZE(tags)];
+ struct thread_state thread_states[GPR_ARRAY_SIZE(tags)];
+ gpr_thd_options thread_options = gpr_thd_options_default();
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ unsigned i, j;
+
+ LOG_TEST("test_too_many_plucks");
+
+ cc = grpc_completion_queue_create(NULL);
+ gpr_thd_options_set_joinable(&thread_options);
+
+ for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
+ tags[i] = create_test_tag();
+ for (j = 0; j < i; j++) {
+ GPR_ASSERT(tags[i] != tags[j]);
+ }
+ thread_states[i].cc = cc;
+ thread_states[i].tag = tags[i];
+ gpr_thd_new(thread_ids + i, pluck_one, thread_states + i, &thread_options);
+ }
+
+ /* wait until all other threads are plucking */
+ gpr_sleep_until(GRPC_TIMEOUT_MILLIS_TO_DEADLINE(1000));
+
+ ev = grpc_completion_queue_pluck(cc, create_test_tag(),
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ GPR_ASSERT(ev.type == GRPC_QUEUE_TIMEOUT);
+
+ for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
+ grpc_cq_begin_op(cc, tags[i]);
+ grpc_cq_end_op(&exec_ctx, cc, tags[i], 1, do_nothing_end_completion, NULL,
+ &completions[i]);
+ }
+
+ for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
+ gpr_thd_join(thread_ids[i]);
+ }
+
+ shutdown_and_destroy(cc);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
#define TEST_THREAD_EVENTS 10000
typedef struct test_thread_options {
@@ -208,7 +279,7 @@ static void producer_thread(void *arg) {
gpr_log(GPR_INFO, "producer %d phase 1", opt->id);
for (i = 0; i < TEST_THREAD_EVENTS; i++) {
- grpc_cq_begin_op(opt->cc);
+ grpc_cq_begin_op(opt->cc, (void *)(gpr_intptr)1);
}
gpr_log(GPR_INFO, "producer %d phase 1 done", opt->id);
@@ -343,6 +414,8 @@ int main(int argc, char **argv) {
test_shutdown_then_next_with_timeout();
test_cq_end_op();
test_pluck();
+ test_pluck_after_shutdown();
+ test_too_many_plucks();
test_threading(1, 1);
test_threading(1, 10);
test_threading(10, 1);
diff --git a/test/core/surface/init_test.c b/test/core/surface/init_test.c
new file mode 100644
index 0000000000..d4451e4567
--- /dev/null
+++ b/test/core/surface/init_test.c
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include "test/core/util/test_config.h"
+
+static int g_flag;
+
+static void test(int rounds) {
+ int i;
+ for (i = 0; i < rounds; i++) {
+ grpc_init();
+ }
+ for (i = 0; i < rounds; i++) {
+ grpc_shutdown();
+ }
+}
+
+static void test_mixed(void) {
+ grpc_init();
+ grpc_init();
+ grpc_shutdown();
+ grpc_init();
+ grpc_shutdown();
+ grpc_shutdown();
+}
+
+static void plugin_init(void) { g_flag = 1; }
+static void plugin_destroy(void) { g_flag = 2; }
+
+static void test_plugin() {
+ grpc_register_plugin(plugin_init, plugin_destroy);
+ grpc_init();
+ GPR_ASSERT(g_flag == 1);
+ grpc_shutdown();
+ GPR_ASSERT(g_flag == 2);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ test(1);
+ test(2);
+ test(3);
+ test_mixed();
+ test_plugin();
+ return 0;
+}
diff --git a/test/core/surface/invalid_channel_args_test.c b/test/core/surface/invalid_channel_args_test.c
new file mode 100644
index 0000000000..1b1b8b8f92
--- /dev/null
+++ b/test/core/surface/invalid_channel_args_test.c
@@ -0,0 +1,186 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include "test/core/util/test_config.h"
+
+static char *g_last_log_error_message = NULL;
+static const char *g_file_name = "channel.c";
+
+static int ends_with(const char *src, const char *suffix) {
+ size_t src_len = strlen(src);
+ size_t suffix_len = strlen(suffix);
+ if (src_len < suffix_len) {
+ return 0;
+ }
+ return strcmp(src + src_len - suffix_len, suffix) == 0;
+}
+
+static void log_error_sink(gpr_log_func_args *args) {
+ if (args->severity == GPR_LOG_SEVERITY_ERROR &&
+ ends_with(args->file, g_file_name)) {
+ g_last_log_error_message = gpr_strdup(args->message);
+ }
+}
+
+static void verify_last_error(const char *message) {
+ if (message == NULL) {
+ GPR_ASSERT(g_last_log_error_message == NULL);
+ return;
+ }
+ GPR_ASSERT(strcmp(message, g_last_log_error_message) == 0);
+ gpr_free(g_last_log_error_message);
+ g_last_log_error_message = NULL;
+}
+
+static char *compose_error_string(const char *key, const char *message) {
+ char *ret;
+ gpr_asprintf(&ret, "%s%s", key, message);
+ return ret;
+}
+
+static void one_test(grpc_channel_args *args, char *expected_error_message) {
+ grpc_channel *chan =
+ grpc_insecure_channel_create("nonexistant:54321", args, NULL);
+ verify_last_error(expected_error_message);
+ gpr_free(expected_error_message);
+ grpc_channel_destroy(chan);
+}
+
+static void test_no_error_message(void) { one_test(NULL, NULL); }
+
+static void test_max_message_length_type(void) {
+ grpc_arg client_arg;
+ grpc_channel_args client_args;
+ char *expected_error_message;
+
+ client_arg.type = GRPC_ARG_STRING;
+ client_arg.key = GRPC_ARG_MAX_MESSAGE_LENGTH;
+ client_arg.value.string = NULL;
+
+ client_args.num_args = 1;
+ client_args.args = &client_arg;
+ expected_error_message = compose_error_string(
+ GRPC_ARG_MAX_MESSAGE_LENGTH, " ignored: it must be an integer");
+ one_test(&client_args, expected_error_message);
+}
+
+static void test_max_message_length_negative(void) {
+ grpc_arg client_arg;
+ grpc_channel_args client_args;
+ char *expected_error_message;
+
+ client_arg.type = GRPC_ARG_INTEGER;
+ client_arg.key = GRPC_ARG_MAX_MESSAGE_LENGTH;
+ client_arg.value.integer = -1;
+
+ client_args.num_args = 1;
+ client_args.args = &client_arg;
+ expected_error_message = compose_error_string(GRPC_ARG_MAX_MESSAGE_LENGTH,
+ " ignored: it must be >= 0");
+ one_test(&client_args, expected_error_message);
+}
+
+static void test_default_authority_type(void) {
+ grpc_arg client_arg;
+ grpc_channel_args client_args;
+ char *expected_error_message;
+
+ client_arg.type = GRPC_ARG_INTEGER;
+ client_arg.key = GRPC_ARG_DEFAULT_AUTHORITY;
+ client_arg.value.integer = 0;
+
+ client_args.num_args = 1;
+ client_args.args = &client_arg;
+ expected_error_message = compose_error_string(
+ GRPC_ARG_DEFAULT_AUTHORITY, " ignored: it must be a string");
+ one_test(&client_args, expected_error_message);
+}
+
+static void test_ssl_name_override_type(void) {
+ grpc_arg client_arg;
+ grpc_channel_args client_args;
+ char *expected_error_message;
+
+ client_arg.type = GRPC_ARG_INTEGER;
+ client_arg.key = GRPC_SSL_TARGET_NAME_OVERRIDE_ARG;
+ client_arg.value.integer = 0;
+
+ client_args.num_args = 1;
+ client_args.args = &client_arg;
+ expected_error_message = compose_error_string(
+ GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, " ignored: it must be a string");
+ one_test(&client_args, expected_error_message);
+}
+
+static void test_ssl_name_override_failed(void) {
+ grpc_arg client_arg[2];
+ grpc_channel_args client_args;
+ char *expected_error_message;
+
+ client_arg[0].type = GRPC_ARG_STRING;
+ client_arg[0].key = GRPC_ARG_DEFAULT_AUTHORITY;
+ client_arg[0].value.string = "default";
+ client_arg[1].type = GRPC_ARG_STRING;
+ client_arg[1].key = GRPC_SSL_TARGET_NAME_OVERRIDE_ARG;
+ client_arg[1].value.string = "ssl";
+
+ client_args.num_args = 2;
+ client_args.args = client_arg;
+ expected_error_message =
+ compose_error_string(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
+ " ignored: default host already set some other way");
+ one_test(&client_args, expected_error_message);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+ gpr_set_log_function(log_error_sink);
+
+ test_no_error_message();
+ test_max_message_length_type();
+ test_max_message_length_negative();
+ test_default_authority_type();
+ test_ssl_name_override_type();
+ test_ssl_name_override_failed();
+
+ grpc_shutdown();
+
+ return 0;
+}
diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c
index 0d29bea555..35b0212fcf 100644
--- a/test/core/surface/lame_client_test.c
+++ b/test/core/surface/lame_client_test.c
@@ -31,15 +31,52 @@
*
*/
-#include <grpc/grpc.h>
+#include <string.h>
-#include "test/core/end2end/cq_verifier.h"
-#include "test/core/util/test_config.h"
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/channel/channel_stack.h"
+#include "src/core/iomgr/closure.h"
+#include "src/core/surface/channel.h"
+#include "src/core/transport/transport.h"
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/util/test_config.h"
+
+grpc_closure transport_op_cb;
static void *tag(gpr_intptr x) { return (void *)x; }
+void verify_connectivity(grpc_exec_ctx *exec_ctx, void *arg, int success) {
+ grpc_transport_op *op = arg;
+ GPR_ASSERT(GRPC_CHANNEL_FATAL_FAILURE == *op->connectivity_state);
+ GPR_ASSERT(success);
+}
+
+void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, int success) {}
+
+void test_transport_op(grpc_channel *channel) {
+ grpc_transport_op op;
+ grpc_channel_element *elem;
+ grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+ memset(&op, 0, sizeof(op));
+ grpc_closure_init(&transport_op_cb, verify_connectivity, &op);
+
+ op.on_connectivity_state_change = &transport_op_cb;
+ op.connectivity_state = &state;
+ elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
+ elem->filter->start_transport_op(&exec_ctx, elem, &op);
+ grpc_exec_ctx_finish(&exec_ctx);
+
+ memset(&op, 0, sizeof(op));
+ grpc_closure_init(&transport_op_cb, do_nothing, NULL);
+ op.on_consumed = &transport_op_cb;
+ elem->filter->start_transport_op(&exec_ctx, elem, &op);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
int main(int argc, char **argv) {
grpc_channel *chan;
grpc_call *call;
@@ -47,21 +84,31 @@ int main(int argc, char **argv) {
cq_verifier *cqv;
grpc_op ops[6];
grpc_op *op;
+ grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_status_code status;
grpc_call_error error;
char *details = NULL;
size_t details_capacity = 0;
+ char *peer;
grpc_test_init(argc, argv);
grpc_init();
+ grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
chan = grpc_lame_client_channel_create(
"lampoon:national", GRPC_STATUS_UNKNOWN, "Rpc sent on a lame channel.");
GPR_ASSERT(chan);
+
+ test_transport_op(chan);
+
+ GPR_ASSERT(GRPC_CHANNEL_FATAL_FAILURE ==
+ grpc_channel_check_connectivity_state(chan, 0));
+
cq = grpc_completion_queue_create(NULL);
+
call = grpc_channel_create_call(chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
"/Foo", "anywhere",
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100), NULL);
@@ -74,6 +121,19 @@ int main(int argc, char **argv) {
op->flags = 0;
op->reserved = NULL;
op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata = &initial_metadata_recv;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ error = grpc_call_start_batch(call, ops, (size_t)(op - ops), tag(1), NULL);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ /* the call should immediately fail */
+ cq_expect_completion(cqv, tag(1), 0);
+ cq_verify(cqv);
+
+ op = ops;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
@@ -82,18 +142,23 @@ int main(int argc, char **argv) {
op->flags = 0;
op->reserved = NULL;
op++;
- error = grpc_call_start_batch(call, ops, (size_t)(op - ops), tag(1), NULL);
+ error = grpc_call_start_batch(call, ops, (size_t)(op - ops), tag(2), NULL);
GPR_ASSERT(GRPC_CALL_OK == error);
/* the call should immediately fail */
- cq_expect_completion(cqv, tag(1), 1);
+ cq_expect_completion(cqv, tag(2), 1);
cq_verify(cqv);
+ peer = grpc_call_get_peer(call);
+ GPR_ASSERT(strcmp(peer, "lampoon:national") == 0);
+ gpr_free(peer);
+
grpc_call_destroy(call);
grpc_channel_destroy(chan);
cq_verifier_destroy(cqv);
grpc_completion_queue_destroy(cq);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
gpr_free(details);
diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c
new file mode 100644
index 0000000000..f3e5fefaf0
--- /dev/null
+++ b/test/core/surface/secure_channel_create_test.c
@@ -0,0 +1,95 @@
+/*
+ *
+ * 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 <string.h>
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/log.h>
+#include "src/core/client_config/resolver_registry.h"
+#include "src/core/security/credentials.h"
+#include "src/core/security/security_connector.h"
+#include "src/core/surface/channel.h"
+#include "test/core/util/test_config.h"
+
+void test_unknown_scheme_target(void) {
+ grpc_channel *chan;
+ grpc_channel_credentials *creds;
+ grpc_resolver_registry_shutdown();
+ grpc_resolver_registry_init("");
+
+ creds = grpc_fake_transport_security_credentials_create();
+ chan = grpc_secure_channel_create(creds, "blah://blah", NULL, NULL);
+ GPR_ASSERT(chan == NULL);
+ grpc_channel_credentials_unref(creds);
+}
+
+void test_security_connector_already_in_arg(void) {
+ grpc_channel *chan;
+ grpc_channel_element *elem;
+ grpc_channel_args args;
+ grpc_arg arg;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+ arg.type = GRPC_ARG_POINTER;
+ arg.value.pointer.p = NULL;
+ arg.key = GRPC_SECURITY_CONNECTOR_ARG;
+ args.num_args = 1;
+ args.args = &arg;
+ chan = grpc_secure_channel_create(NULL, NULL, &args, NULL);
+ elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0);
+ GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client"));
+ GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, chan, "test");
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+void test_null_creds(void) {
+ grpc_channel *chan;
+ grpc_channel_element *elem;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ chan = grpc_secure_channel_create(NULL, NULL, NULL, NULL);
+ elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0);
+ GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client"));
+ GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, chan, "test");
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+ test_security_connector_already_in_arg();
+ test_null_creds();
+ test_unknown_scheme_target();
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/core/surface/multi_init_test.c b/test/core/surface/server_chttp2_test.c
index 99b7a52ff9..ec7df6f0e3 100644
--- a/test/core/surface/multi_init_test.c
+++ b/test/core/surface/server_chttp2_test.c
@@ -32,32 +32,18 @@
*/
#include <grpc/grpc.h>
+#include <grpc/support/log.h>
#include "test/core/util/test_config.h"
-static void test(int rounds) {
- int i;
- for (i = 0; i < rounds; i++) {
- grpc_init();
- }
- for (i = 0; i < rounds; i++) {
- grpc_shutdown();
- }
-}
-
-static void test_mixed() {
- grpc_init();
- grpc_init();
- grpc_shutdown();
- grpc_init();
- grpc_shutdown();
- grpc_shutdown();
+void test_unparsable_target(void) {
+ int port = grpc_server_add_insecure_http2_port(NULL, "[");
+ GPR_ASSERT(port == 0);
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
- test(1);
- test(2);
- test(3);
- test_mixed();
+ grpc_init();
+ test_unparsable_target();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/surface/server_test.c b/test/core/surface/server_test.c
new file mode 100644
index 0000000000..1d5211d225
--- /dev/null
+++ b/test/core/surface/server_test.c
@@ -0,0 +1,93 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+void test_register_method_fail(void) {
+ grpc_server *server = grpc_server_create(NULL, NULL);
+ void *method;
+ void *method_old;
+ method = grpc_server_register_method(server, NULL, NULL);
+ GPR_ASSERT(method == NULL);
+ method_old = grpc_server_register_method(server, "m", "h");
+ GPR_ASSERT(method_old != NULL);
+ method = grpc_server_register_method(server, "m", "h");
+ GPR_ASSERT(method == NULL);
+ grpc_server_destroy(server);
+}
+
+void test_request_call_on_no_server_cq(void) {
+ grpc_completion_queue *cc = grpc_completion_queue_create(NULL);
+ GPR_ASSERT(GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE ==
+ grpc_server_request_call(NULL, NULL, NULL, NULL, cc, cc, NULL));
+ GPR_ASSERT(GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE ==
+ grpc_server_request_registered_call(NULL, NULL, NULL, NULL, NULL,
+ NULL, cc, cc, NULL));
+ grpc_completion_queue_destroy(cc);
+}
+
+void test_bind_server_twice(void) {
+ char *addr;
+ grpc_server *server1 = grpc_server_create(NULL, NULL);
+ grpc_server *server2 = grpc_server_create(NULL, NULL);
+ grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+ int port = grpc_pick_unused_port_or_die();
+ gpr_asprintf(&addr, "[::]:%d", port);
+ grpc_server_register_completion_queue(server1, cq, NULL);
+ grpc_server_register_completion_queue(server2, cq, NULL);
+ GPR_ASSERT(port == grpc_server_add_insecure_http2_port(server1, addr));
+ GPR_ASSERT(0 == grpc_server_add_insecure_http2_port(server2, addr));
+ grpc_server_shutdown_and_notify(server1, cq, NULL);
+ grpc_server_shutdown_and_notify(server2, cq, NULL);
+ grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL);
+ grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL);
+ grpc_server_destroy(server1);
+ grpc_server_destroy(server2);
+ grpc_completion_queue_destroy(cq);
+ gpr_free(addr);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+ test_register_method_fail();
+ test_request_call_on_no_server_cq();
+ test_bind_server_twice();
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c
index 6553e0da20..4a9d143640 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.c
+++ b/test/core/transport/chttp2/hpack_encoder_test.c
@@ -37,6 +37,7 @@
#include "src/core/support/string.h"
#include "src/core/transport/chttp2/hpack_parser.h"
+#include "src/core/transport/metadata.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
@@ -46,7 +47,6 @@
#define TEST(x) run_test(x, #x)
-grpc_mdctx *g_mdctx;
grpc_chttp2_hpack_compressor g_compressor;
int g_failure = 0;
@@ -76,7 +76,7 @@ static void verify(size_t window_available, int eof, size_t expect_window_used,
e[i - 1].next = &e[i];
e[i].prev = &e[i - 1];
}
- e[i].md = grpc_mdelem_from_strings(g_mdctx, key, value);
+ e[i].md = grpc_mdelem_from_strings(key, value);
}
e[0].prev = NULL;
e[nheaders - 1].next = NULL;
@@ -181,18 +181,19 @@ static void test_decode_table_overflow(void) {
static void run_test(void (*test)(), const char *name) {
gpr_log(GPR_INFO, "RUN TEST: %s", name);
- g_mdctx = grpc_mdctx_create_with_seed(0);
- grpc_chttp2_hpack_compressor_init(&g_compressor, g_mdctx);
+ grpc_chttp2_hpack_compressor_init(&g_compressor);
test();
grpc_chttp2_hpack_compressor_destroy(&g_compressor);
- grpc_mdctx_unref(g_mdctx);
}
int main(int argc, char **argv) {
size_t i;
+ grpc_test_only_set_metadata_hash_seed(0);
grpc_test_init(argc, argv);
+ grpc_init();
TEST(test_basic_headers);
TEST(test_decode_table_overflow);
+ grpc_shutdown();
for (i = 0; i < num_to_delete; i++) {
gpr_free(to_delete[i]);
}
diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c
index c6b35fba79..4456e197af 100644
--- a/test/core/transport/chttp2/hpack_parser_test.c
+++ b/test/core/transport/chttp2/hpack_parser_test.c
@@ -35,6 +35,7 @@
#include <stdarg.h>
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/slice.h>
@@ -90,9 +91,8 @@ static void test_vector(grpc_chttp2_hpack_parser *parser,
static void test_vectors(grpc_slice_split_mode mode) {
grpc_chttp2_hpack_parser parser;
- grpc_mdctx *mdctx = grpc_mdctx_create();
- grpc_chttp2_hpack_parser_init(&parser, mdctx);
+ grpc_chttp2_hpack_parser_init(&parser);
/* D.2.1 */
test_vector(&parser, mode,
"400a 6375 7374 6f6d 2d6b 6579 0d63 7573"
@@ -110,7 +110,7 @@ static void test_vectors(grpc_slice_split_mode mode) {
test_vector(&parser, mode, "82", ":method", "GET", NULL);
grpc_chttp2_hpack_parser_destroy(&parser);
- grpc_chttp2_hpack_parser_init(&parser, mdctx);
+ grpc_chttp2_hpack_parser_init(&parser);
/* D.3.1 */
test_vector(&parser, mode,
"8286 8441 0f77 7777 2e65 7861 6d70 6c65"
@@ -130,7 +130,7 @@ static void test_vectors(grpc_slice_split_mode mode) {
NULL);
grpc_chttp2_hpack_parser_destroy(&parser);
- grpc_chttp2_hpack_parser_init(&parser, mdctx);
+ grpc_chttp2_hpack_parser_init(&parser);
/* D.4.1 */
test_vector(&parser, mode,
"8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4"
@@ -150,7 +150,7 @@ static void test_vectors(grpc_slice_split_mode mode) {
NULL);
grpc_chttp2_hpack_parser_destroy(&parser);
- grpc_chttp2_hpack_parser_init(&parser, mdctx);
+ grpc_chttp2_hpack_parser_init(&parser);
grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256);
grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256);
/* D.5.1 */
@@ -184,7 +184,7 @@ static void test_vectors(grpc_slice_split_mode mode) {
"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
grpc_chttp2_hpack_parser_destroy(&parser);
- grpc_chttp2_hpack_parser_init(&parser, mdctx);
+ grpc_chttp2_hpack_parser_init(&parser);
grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256);
grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256);
/* D.6.1 */
@@ -214,12 +214,13 @@ static void test_vectors(grpc_slice_split_mode mode) {
"set-cookie",
"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
grpc_chttp2_hpack_parser_destroy(&parser);
- grpc_mdctx_unref(mdctx);
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
+ grpc_init();
test_vectors(GRPC_SLICE_SPLIT_MERGE_ALL);
test_vectors(GRPC_SLICE_SPLIT_ONE_BYTE);
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c
index 5eb52d6d9a..fde352433b 100644
--- a/test/core/transport/chttp2/hpack_table_test.c
+++ b/test/core/transport/chttp2/hpack_table_test.c
@@ -36,10 +36,12 @@
#include <string.h>
#include <stdio.h>
-#include "src/core/support/string.h"
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+
+#include "src/core/support/string.h"
#include "test/core/util/test_config.h"
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)
@@ -58,10 +60,8 @@ static void assert_index(const grpc_chttp2_hptbl *tbl, gpr_uint32 idx,
static void test_static_lookup(void) {
grpc_chttp2_hptbl tbl;
- grpc_mdctx *mdctx;
- mdctx = grpc_mdctx_create();
- grpc_chttp2_hptbl_init(&tbl, mdctx);
+ grpc_chttp2_hptbl_init(&tbl);
LOG_TEST("test_static_lookup");
assert_index(&tbl, 1, ":authority", "");
@@ -127,7 +127,6 @@ static void test_static_lookup(void) {
assert_index(&tbl, 61, "www-authenticate", "");
grpc_chttp2_hptbl_destroy(&tbl);
- grpc_mdctx_unref(mdctx);
}
static void test_many_additions(void) {
@@ -135,18 +134,16 @@ static void test_many_additions(void) {
int i;
char *key;
char *value;
- grpc_mdctx *mdctx;
LOG_TEST("test_many_additions");
- mdctx = grpc_mdctx_create();
- grpc_chttp2_hptbl_init(&tbl, mdctx);
+ grpc_chttp2_hptbl_init(&tbl);
for (i = 0; i < 1000000; i++) {
grpc_mdelem *elem;
gpr_asprintf(&key, "K:%d", i);
gpr_asprintf(&value, "VALUE:%d", i);
- elem = grpc_mdelem_from_strings(mdctx, key, value);
+ elem = grpc_mdelem_from_strings(key, value);
GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
GRPC_MDELEM_UNREF(elem);
assert_index(&tbl, 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY, key, value);
@@ -162,13 +159,12 @@ static void test_many_additions(void) {
}
grpc_chttp2_hptbl_destroy(&tbl);
- grpc_mdctx_unref(mdctx);
}
static grpc_chttp2_hptbl_find_result find_simple(grpc_chttp2_hptbl *tbl,
const char *key,
const char *value) {
- grpc_mdelem *md = grpc_mdelem_from_strings(tbl->mdctx, key, value);
+ grpc_mdelem *md = grpc_mdelem_from_strings(key, value);
grpc_chttp2_hptbl_find_result r = grpc_chttp2_hptbl_find(tbl, md);
GRPC_MDELEM_UNREF(md);
return r;
@@ -178,21 +174,19 @@ static void test_find(void) {
grpc_chttp2_hptbl tbl;
gpr_uint32 i;
char buffer[32];
- grpc_mdctx *mdctx;
grpc_mdelem *elem;
grpc_chttp2_hptbl_find_result r;
LOG_TEST("test_find");
- mdctx = grpc_mdctx_create();
- grpc_chttp2_hptbl_init(&tbl, mdctx);
- elem = grpc_mdelem_from_strings(mdctx, "abc", "xyz");
+ grpc_chttp2_hptbl_init(&tbl);
+ elem = grpc_mdelem_from_strings("abc", "xyz");
GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
GRPC_MDELEM_UNREF(elem);
- elem = grpc_mdelem_from_strings(mdctx, "abc", "123");
+ elem = grpc_mdelem_from_strings("abc", "123");
GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
GRPC_MDELEM_UNREF(elem);
- elem = grpc_mdelem_from_strings(mdctx, "x", "1");
+ elem = grpc_mdelem_from_strings("x", "1");
GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
GRPC_MDELEM_UNREF(elem);
@@ -243,7 +237,7 @@ static void test_find(void) {
/* overflow the string buffer, check find still works */
for (i = 0; i < 10000; i++) {
gpr_ltoa(i, buffer);
- elem = grpc_mdelem_from_strings(mdctx, "test", buffer);
+ elem = grpc_mdelem_from_strings("test", buffer);
GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
GRPC_MDELEM_UNREF(elem);
}
@@ -274,13 +268,14 @@ static void test_find(void) {
GPR_ASSERT(r.has_value == 0);
grpc_chttp2_hptbl_destroy(&tbl);
- grpc_mdctx_unref(mdctx);
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
+ grpc_init();
test_static_lookup();
test_many_additions();
test_find();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/transport/chttp2/varint_test.c b/test/core/transport/chttp2/varint_test.c
new file mode 100644
index 0000000000..31fcb7e182
--- /dev/null
+++ b/test/core/transport/chttp2/varint_test.c
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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/transport/chttp2/varint.h"
+
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+
+#include "test/core/util/test_config.h"
+
+static void test_varint(gpr_uint32 value, gpr_uint32 prefix_bits,
+ gpr_uint8 prefix_or, const char *expect_bytes,
+ size_t expect_length) {
+ gpr_uint32 nbytes = GRPC_CHTTP2_VARINT_LENGTH(value, prefix_bits);
+ gpr_slice expect = gpr_slice_from_copied_buffer(expect_bytes, expect_length);
+ gpr_slice slice;
+ gpr_log(GPR_DEBUG, "Test: 0x%08x", value);
+ GPR_ASSERT(nbytes == expect_length);
+ slice = gpr_slice_malloc(nbytes);
+ GRPC_CHTTP2_WRITE_VARINT(value, prefix_bits, prefix_or,
+ GPR_SLICE_START_PTR(slice), nbytes);
+ GPR_ASSERT(gpr_slice_cmp(expect, slice) == 0);
+ gpr_slice_unref(expect);
+ gpr_slice_unref(slice);
+}
+
+#define TEST_VARINT(value, prefix_bits, prefix_or, expect) \
+ test_varint(value, prefix_bits, prefix_or, expect, sizeof(expect) - 1)
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ TEST_VARINT(0, 1, 0, "\x00");
+ TEST_VARINT(128, 1, 0, "\x7f\x01");
+ TEST_VARINT(16384, 1, 0, "\x7f\x81\x7f");
+ TEST_VARINT(2097152, 1, 0, "\x7f\x81\xff\x7f");
+ TEST_VARINT(268435456, 1, 0, "\x7f\x81\xff\xff\x7f");
+ TEST_VARINT(0xffffffff, 1, 0, "\x7f\x80\xff\xff\xff\x0f");
+ return 0;
+}
diff --git a/test/core/transport/connectivity_state_test.c b/test/core/transport/connectivity_state_test.c
new file mode 100644
index 0000000000..34ab45d260
--- /dev/null
+++ b/test/core/transport/connectivity_state_test.c
@@ -0,0 +1,154 @@
+/*
+ *
+ * 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/transport/connectivity_state.h"
+
+#include <string.h>
+
+#include <grpc/support/log.h>
+
+#include "test/core/util/test_config.h"
+
+#define THE_ARG ((void *)(size_t)0xcafebabe)
+
+int g_counter;
+
+static void must_succeed(grpc_exec_ctx *exec_ctx, void *arg, int success) {
+ GPR_ASSERT(success);
+ GPR_ASSERT(arg == THE_ARG);
+ g_counter++;
+}
+
+static void must_fail(grpc_exec_ctx *exec_ctx, void *arg, int success) {
+ GPR_ASSERT(!success);
+ GPR_ASSERT(arg == THE_ARG);
+ g_counter++;
+}
+
+static void test_connectivity_state_name(void) {
+ gpr_log(GPR_DEBUG, "test_connectivity_state_name");
+ GPR_ASSERT(0 ==
+ strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_IDLE), "IDLE"));
+ GPR_ASSERT(0 == strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_CONNECTING),
+ "CONNECTING"));
+ GPR_ASSERT(0 ==
+ strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_READY), "READY"));
+ GPR_ASSERT(
+ 0 == strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_TRANSIENT_FAILURE),
+ "TRANSIENT_FAILURE"));
+ GPR_ASSERT(0 ==
+ strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_FATAL_FAILURE),
+ "FATAL_FAILURE"));
+}
+
+static void test_check(void) {
+ grpc_connectivity_state_tracker tracker;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ gpr_log(GPR_DEBUG, "test_check");
+ grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_IDLE, "xxx");
+ GPR_ASSERT(grpc_connectivity_state_check(&tracker) == GRPC_CHANNEL_IDLE);
+ grpc_connectivity_state_destroy(&exec_ctx, &tracker);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void test_subscribe_then_unsubscribe(void) {
+ grpc_connectivity_state_tracker tracker;
+ grpc_closure *closure = grpc_closure_create(must_fail, THE_ARG);
+ grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ gpr_log(GPR_DEBUG, "test_subscribe_then_unsubscribe");
+ g_counter = 0;
+ grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_IDLE, "xxx");
+ GPR_ASSERT(grpc_connectivity_state_notify_on_state_change(&exec_ctx, &tracker,
+ &state, closure));
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(state == GRPC_CHANNEL_IDLE);
+ GPR_ASSERT(g_counter == 0);
+ grpc_connectivity_state_notify_on_state_change(&exec_ctx, &tracker, NULL,
+ closure);
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(state == GRPC_CHANNEL_IDLE);
+ GPR_ASSERT(g_counter == 1);
+
+ grpc_connectivity_state_destroy(&exec_ctx, &tracker);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void test_subscribe_then_destroy(void) {
+ grpc_connectivity_state_tracker tracker;
+ grpc_closure *closure = grpc_closure_create(must_succeed, THE_ARG);
+ grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ gpr_log(GPR_DEBUG, "test_subscribe_then_destroy");
+ g_counter = 0;
+ grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_IDLE, "xxx");
+ GPR_ASSERT(grpc_connectivity_state_notify_on_state_change(&exec_ctx, &tracker,
+ &state, closure));
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(state == GRPC_CHANNEL_IDLE);
+ GPR_ASSERT(g_counter == 0);
+ grpc_connectivity_state_destroy(&exec_ctx, &tracker);
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(state == GRPC_CHANNEL_FATAL_FAILURE);
+ GPR_ASSERT(g_counter == 1);
+}
+
+static void test_subscribe_with_failure_then_destroy(void) {
+ grpc_connectivity_state_tracker tracker;
+ grpc_closure *closure = grpc_closure_create(must_fail, THE_ARG);
+ grpc_connectivity_state state = GRPC_CHANNEL_FATAL_FAILURE;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ gpr_log(GPR_DEBUG, "test_subscribe_with_failure_then_destroy");
+ g_counter = 0;
+ grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_FATAL_FAILURE, "xxx");
+ GPR_ASSERT(0 == grpc_connectivity_state_notify_on_state_change(
+ &exec_ctx, &tracker, &state, closure));
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(state == GRPC_CHANNEL_FATAL_FAILURE);
+ GPR_ASSERT(g_counter == 0);
+ grpc_connectivity_state_destroy(&exec_ctx, &tracker);
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(state == GRPC_CHANNEL_FATAL_FAILURE);
+ GPR_ASSERT(g_counter == 1);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ grpc_connectivity_state_trace = 1;
+ test_connectivity_state_name();
+ test_check();
+ test_subscribe_then_unsubscribe();
+ test_subscribe_then_destroy();
+ test_subscribe_with_failure_then_destroy();
+ return 0;
+}
diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c
index 080e86cb63..928fba7f45 100644
--- a/test/core/transport/metadata_test.c
+++ b/test/core/transport/metadata_test.c
@@ -35,11 +35,13 @@
#include <stdio.h>
-#include "src/core/support/string.h"
-#include "src/core/transport/chttp2/bin_encoder.h"
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+
+#include "src/core/support/string.h"
+#include "src/core/transport/chttp2/bin_encoder.h"
#include "test/core/util/test_config.h"
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)
@@ -48,44 +50,39 @@
#define MANY 10000
static void test_no_op(void) {
- grpc_mdctx *ctx;
-
LOG_TEST("test_no_op");
-
- ctx = grpc_mdctx_create();
- grpc_mdctx_unref(ctx);
+ grpc_init();
+ grpc_shutdown();
}
static void test_create_string(void) {
- grpc_mdctx *ctx;
grpc_mdstr *s1, *s2, *s3;
LOG_TEST("test_create_string");
- ctx = grpc_mdctx_create();
- s1 = grpc_mdstr_from_string(ctx, "hello");
- s2 = grpc_mdstr_from_string(ctx, "hello");
- s3 = grpc_mdstr_from_string(ctx, "very much not hello");
+ grpc_init();
+ s1 = grpc_mdstr_from_string("hello");
+ s2 = grpc_mdstr_from_string("hello");
+ s3 = grpc_mdstr_from_string("very much not hello");
GPR_ASSERT(s1 == s2);
GPR_ASSERT(s3 != s1);
GPR_ASSERT(gpr_slice_str_cmp(s1->slice, "hello") == 0);
GPR_ASSERT(gpr_slice_str_cmp(s3->slice, "very much not hello") == 0);
GRPC_MDSTR_UNREF(s1);
GRPC_MDSTR_UNREF(s2);
- grpc_mdctx_unref(ctx);
GRPC_MDSTR_UNREF(s3);
+ grpc_shutdown();
}
static void test_create_metadata(void) {
- grpc_mdctx *ctx;
grpc_mdelem *m1, *m2, *m3;
LOG_TEST("test_create_metadata");
- ctx = grpc_mdctx_create();
- m1 = grpc_mdelem_from_strings(ctx, "a", "b");
- m2 = grpc_mdelem_from_strings(ctx, "a", "b");
- m3 = grpc_mdelem_from_strings(ctx, "a", "c");
+ grpc_init();
+ m1 = grpc_mdelem_from_strings("a", "b");
+ m2 = grpc_mdelem_from_strings("a", "b");
+ m3 = grpc_mdelem_from_strings("a", "c");
GPR_ASSERT(m1 == m2);
GPR_ASSERT(m3 != m1);
GPR_ASSERT(m3->key == m1->key);
@@ -96,32 +93,25 @@ static void test_create_metadata(void) {
GRPC_MDELEM_UNREF(m1);
GRPC_MDELEM_UNREF(m2);
GRPC_MDELEM_UNREF(m3);
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
}
static void test_create_many_ephemeral_metadata(void) {
- grpc_mdctx *ctx;
char buffer[GPR_LTOA_MIN_BUFSIZE];
long i;
- size_t mdtab_capacity_before;
LOG_TEST("test_create_many_ephemeral_metadata");
- ctx = grpc_mdctx_create();
- mdtab_capacity_before = grpc_mdctx_get_mdtab_capacity_test_only(ctx);
+ grpc_init();
/* add, and immediately delete a bunch of different elements */
for (i = 0; i < MANY; i++) {
gpr_ltoa(i, buffer);
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings(ctx, "a", buffer));
+ GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", buffer));
}
- /* capacity should not grow */
- GPR_ASSERT(mdtab_capacity_before ==
- grpc_mdctx_get_mdtab_capacity_test_only(ctx));
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
}
static void test_create_many_persistant_metadata(void) {
- grpc_mdctx *ctx;
char buffer[GPR_LTOA_MIN_BUFSIZE];
long i;
grpc_mdelem **created = gpr_malloc(sizeof(grpc_mdelem *) * MANY);
@@ -129,16 +119,16 @@ static void test_create_many_persistant_metadata(void) {
LOG_TEST("test_create_many_persistant_metadata");
- ctx = grpc_mdctx_create();
+ grpc_init();
/* add phase */
for (i = 0; i < MANY; i++) {
gpr_ltoa(i, buffer);
- created[i] = grpc_mdelem_from_strings(ctx, "a", buffer);
+ created[i] = grpc_mdelem_from_strings("a", buffer);
}
/* verify phase */
for (i = 0; i < MANY; i++) {
gpr_ltoa(i, buffer);
- md = grpc_mdelem_from_strings(ctx, "a", buffer);
+ md = grpc_mdelem_from_strings("a", buffer);
GPR_ASSERT(md == created[i]);
GRPC_MDELEM_UNREF(md);
}
@@ -146,37 +136,22 @@ static void test_create_many_persistant_metadata(void) {
for (i = 0; i < MANY; i++) {
GRPC_MDELEM_UNREF(created[i]);
}
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
gpr_free(created);
}
static void test_spin_creating_the_same_thing(void) {
- grpc_mdctx *ctx;
-
LOG_TEST("test_spin_creating_the_same_thing");
- ctx = grpc_mdctx_create();
- GPR_ASSERT(grpc_mdctx_get_mdtab_count_test_only(ctx) == 0);
- GPR_ASSERT(grpc_mdctx_get_mdtab_free_test_only(ctx) == 0);
-
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings(ctx, "a", "b"));
- GPR_ASSERT(grpc_mdctx_get_mdtab_count_test_only(ctx) == 1);
- GPR_ASSERT(grpc_mdctx_get_mdtab_free_test_only(ctx) == 1);
-
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings(ctx, "a", "b"));
- GPR_ASSERT(grpc_mdctx_get_mdtab_count_test_only(ctx) == 1);
- GPR_ASSERT(grpc_mdctx_get_mdtab_free_test_only(ctx) == 1);
-
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings(ctx, "a", "b"));
- GPR_ASSERT(grpc_mdctx_get_mdtab_count_test_only(ctx) == 1);
- GPR_ASSERT(grpc_mdctx_get_mdtab_free_test_only(ctx) == 1);
-
- grpc_mdctx_unref(ctx);
+ grpc_init();
+ GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
+ GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
+ GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
+ grpc_shutdown();
}
static void test_things_stick_around(void) {
- grpc_mdctx *ctx;
size_t i, j;
char *buffer;
size_t nstrs = 1000;
@@ -186,11 +161,11 @@ static void test_things_stick_around(void) {
LOG_TEST("test_things_stick_around");
- ctx = grpc_mdctx_create();
+ grpc_init();
for (i = 0; i < nstrs; i++) {
gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", i);
- strs[i] = grpc_mdstr_from_string(ctx, buffer);
+ strs[i] = grpc_mdstr_from_string(buffer);
shuf[i] = i;
gpr_free(buffer);
}
@@ -212,60 +187,77 @@ static void test_things_stick_around(void) {
GRPC_MDSTR_UNREF(strs[shuf[i]]);
for (j = i + 1; j < nstrs; j++) {
gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", shuf[j]);
- test = grpc_mdstr_from_string(ctx, buffer);
+ test = grpc_mdstr_from_string(buffer);
GPR_ASSERT(test == strs[shuf[j]]);
GRPC_MDSTR_UNREF(test);
gpr_free(buffer);
}
}
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
gpr_free(strs);
gpr_free(shuf);
}
static void test_slices_work(void) {
/* ensure no memory leaks when switching representation from mdstr to slice */
- grpc_mdctx *ctx;
grpc_mdstr *str;
gpr_slice slice;
LOG_TEST("test_slices_work");
- ctx = grpc_mdctx_create();
+ grpc_init();
str = grpc_mdstr_from_string(
- ctx, "123456789012345678901234567890123456789012345678901234567890");
+ "123456789012345678901234567890123456789012345678901234567890");
slice = gpr_slice_ref(str->slice);
GRPC_MDSTR_UNREF(str);
gpr_slice_unref(slice);
str = grpc_mdstr_from_string(
- ctx, "123456789012345678901234567890123456789012345678901234567890");
+ "123456789012345678901234567890123456789012345678901234567890");
slice = gpr_slice_ref(str->slice);
gpr_slice_unref(slice);
GRPC_MDSTR_UNREF(str);
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
}
static void test_base64_and_huffman_works(void) {
- grpc_mdctx *ctx;
grpc_mdstr *str;
gpr_slice slice1;
gpr_slice slice2;
LOG_TEST("test_base64_and_huffman_works");
- ctx = grpc_mdctx_create();
- str = grpc_mdstr_from_string(ctx, "abcdefg");
+ grpc_init();
+ str = grpc_mdstr_from_string("abcdefg");
slice1 = grpc_mdstr_as_base64_encoded_and_huffman_compressed(str);
slice2 = grpc_chttp2_base64_encode_and_huffman_compress(str->slice);
GPR_ASSERT(0 == gpr_slice_cmp(slice1, slice2));
gpr_slice_unref(slice2);
GRPC_MDSTR_UNREF(str);
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
+}
+
+static void test_user_data_works(void) {
+ int *ud1;
+ int *ud2;
+ grpc_mdelem *md;
+ LOG_TEST("test_user_data_works");
+
+ grpc_init();
+ ud1 = gpr_malloc(sizeof(int));
+ *ud1 = 1;
+ ud2 = gpr_malloc(sizeof(int));
+ *ud2 = 2;
+ md = grpc_mdelem_from_strings("abc", "123");
+ grpc_mdelem_set_user_data(md, gpr_free, ud1);
+ grpc_mdelem_set_user_data(md, gpr_free, ud2);
+ GPR_ASSERT(grpc_mdelem_get_user_data(md, gpr_free) == ud1);
+ GRPC_MDELEM_UNREF(md);
+ grpc_shutdown();
}
int main(int argc, char **argv) {
@@ -279,5 +271,6 @@ int main(int argc, char **argv) {
test_things_stick_around();
test_slices_work();
test_base64_and_huffman_works();
+ test_user_data_works();
return 0;
}
diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c
index 858b92fc9d..7ce343987b 100644
--- a/test/core/tsi/transport_security_test.c
+++ b/test/core/tsi/transport_security_test.c
@@ -43,6 +43,7 @@
#include <openssl/crypto.h>
#include "src/core/support/string.h"
+#include "src/core/tsi/fake_transport_security.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "test/core/util/test_config.h"
@@ -296,8 +297,70 @@ static void test_peer_matches_name(void) {
}
}
+typedef struct {
+ tsi_result res;
+ const char *str;
+} tsi_result_string_pair;
+
+static void test_result_strings(void) {
+ const tsi_result_string_pair results[] = {
+ {TSI_OK, "TSI_OK"},
+ {TSI_UNKNOWN_ERROR, "TSI_UNKNOWN_ERROR"},
+ {TSI_INVALID_ARGUMENT, "TSI_INVALID_ARGUMENT"},
+ {TSI_PERMISSION_DENIED, "TSI_PERMISSION_DENIED"},
+ {TSI_INCOMPLETE_DATA, "TSI_INCOMPLETE_DATA"},
+ {TSI_FAILED_PRECONDITION, "TSI_FAILED_PRECONDITION"},
+ {TSI_UNIMPLEMENTED, "TSI_UNIMPLEMENTED"},
+ {TSI_INTERNAL_ERROR, "TSI_INTERNAL_ERROR"},
+ {TSI_DATA_CORRUPTED, "TSI_DATA_CORRUPTED"},
+ {TSI_NOT_FOUND, "TSI_NOT_FOUND"},
+ {TSI_PROTOCOL_FAILURE, "TSI_PROTOCOL_FAILURE"},
+ {TSI_HANDSHAKE_IN_PROGRESS, "TSI_HANDSHAKE_IN_PROGRESS"},
+ {TSI_OUT_OF_RESOURCES, "TSI_OUT_OF_RESOURCES"}};
+ size_t i;
+ for (i = 0; i < GPR_ARRAY_SIZE(results); i++) {
+ GPR_ASSERT(strcmp(results[i].str, tsi_result_to_string(results[i].res)) ==
+ 0);
+ }
+ GPR_ASSERT(strcmp("UNKNOWN", tsi_result_to_string((tsi_result)42)) == 0);
+}
+
+static void test_protector_invalid_args(void) {
+ GPR_ASSERT(tsi_frame_protector_protect(NULL, NULL, NULL, NULL, NULL) ==
+ TSI_INVALID_ARGUMENT);
+ GPR_ASSERT(tsi_frame_protector_protect_flush(NULL, NULL, NULL, NULL) ==
+ TSI_INVALID_ARGUMENT);
+ GPR_ASSERT(tsi_frame_protector_unprotect(NULL, NULL, NULL, NULL, NULL) ==
+ TSI_INVALID_ARGUMENT);
+}
+
+static void test_handshaker_invalid_args(void) {
+ GPR_ASSERT(tsi_handshaker_get_result(NULL) == TSI_INVALID_ARGUMENT);
+ GPR_ASSERT(tsi_handshaker_extract_peer(NULL, NULL) == TSI_INVALID_ARGUMENT);
+ GPR_ASSERT(tsi_handshaker_create_frame_protector(NULL, NULL, NULL) ==
+ TSI_INVALID_ARGUMENT);
+ GPR_ASSERT(tsi_handshaker_process_bytes_from_peer(NULL, NULL, NULL) ==
+ TSI_INVALID_ARGUMENT);
+ GPR_ASSERT(tsi_handshaker_get_bytes_to_send_to_peer(NULL, NULL, NULL) ==
+ TSI_INVALID_ARGUMENT);
+}
+
+static void test_handshaker_invalid_state(void) {
+ tsi_handshaker *h = tsi_create_fake_handshaker(0);
+ tsi_peer peer;
+ tsi_frame_protector *p;
+ GPR_ASSERT(tsi_handshaker_extract_peer(h, &peer) == TSI_FAILED_PRECONDITION);
+ GPR_ASSERT(tsi_handshaker_create_frame_protector(h, NULL, &p) ==
+ TSI_FAILED_PRECONDITION);
+ tsi_handshaker_destroy(h);
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_peer_matches_name();
+ test_result_strings();
+ test_protector_invalid_args();
+ test_handshaker_invalid_args();
+ test_handshaker_invalid_state();
return 0;
}
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 84b376ad3e..14bfc957cb 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -127,6 +127,8 @@ static void crash_handler(int signum, siginfo_t *info, void *data) {
backtrace_symbols_fd(addrlist, addrlen, STDERR_FILENO);
}
+ /* try to get a core dump for SIGTERM */
+ if (signum == SIGTERM) signum = SIGQUIT;
raise(signum);
}
@@ -145,6 +147,8 @@ static void install_crash_handler() {
GPR_ASSERT(sigaction(SIGABRT, &sa, NULL) == 0);
GPR_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0);
GPR_ASSERT(sigaction(SIGSEGV, &sa, NULL) == 0);
+ GPR_ASSERT(sigaction(SIGTERM, &sa, NULL) == 0);
+ GPR_ASSERT(sigaction(SIGQUIT, &sa, NULL) == 0);
}
#else
static void install_crash_handler() {}
diff --git a/test/cpp/client/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc
index 3d75e7b0e6..e010d375cf 100644
--- a/test/cpp/client/channel_arguments_test.cc
+++ b/test/cpp/common/channel_arguments_test.cc
@@ -115,6 +115,22 @@ TEST_F(ChannelArgumentsTest, SetString) {
}
}
+TEST_F(ChannelArgumentsTest, SetPointer) {
+ grpc_channel_args args;
+ ChannelArguments channel_args;
+ // Empty arguments.
+ SetChannelArgs(channel_args, &args);
+ EXPECT_EQ(static_cast<size_t>(0), args.num_args);
+
+ grpc::string key("key0");
+ channel_args.SetPointer(key, &key);
+ SetChannelArgs(channel_args, &args);
+ EXPECT_EQ(static_cast<size_t>(1), args.num_args);
+ EXPECT_EQ(GRPC_ARG_POINTER, args.args[0].type);
+ EXPECT_STREQ("key0", args.args[0].key);
+ EXPECT_EQ(&key, args.args[0].value.pointer.p);
+}
+
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 74290c36d2..279423a8cb 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -179,6 +179,17 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<bool> {
void SetUp() GRPC_OVERRIDE {
int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port;
+
+ // It is currently unsupported to mix sync and async services
+ // in the same server, so first test that (for coverage)
+ ServerBuilder build_bad;
+ build_bad.AddListeningPort(server_address_.str(),
+ grpc::InsecureServerCredentials());
+ build_bad.RegisterAsyncService(&service_);
+ grpc::cpp::test::util::TestService::Service sync_service;
+ build_bad.RegisterService(&sync_service);
+ GPR_ASSERT(build_bad.BuildAndStart() == nullptr);
+
// Setup server
ServerBuilder builder;
builder.AddListeningPort(server_address_.str(),
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 6da933302c..bbeac7a30b 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -119,10 +119,13 @@ class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin {
bool IsBlocking() const GRPC_OVERRIDE { return is_blocking_; }
- Status GetMetadata(grpc::string_ref service_url,
+ Status GetMetadata(grpc::string_ref service_url, grpc::string_ref method_name,
+ const grpc::AuthContext& channel_auth_context,
std::multimap<grpc::string, grpc::string>* metadata)
GRPC_OVERRIDE {
EXPECT_GT(service_url.length(), 0UL);
+ EXPECT_GT(method_name.length(), 0UL);
+ EXPECT_TRUE(channel_auth_context.IsPeerAuthenticated());
EXPECT_TRUE(metadata != nullptr);
if (is_successful_) {
metadata->insert(std::make_pair(kMetadataKey, metadata_value_));
@@ -540,6 +543,7 @@ TEST_P(End2endTest, BidiStream) {
stream->WritesDone();
EXPECT_FALSE(stream->Read(&response));
+ EXPECT_FALSE(stream->Read(&response));
Status s = stream->Finish();
EXPECT_TRUE(s.ok());
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index 082119d6d5..6ecf7eb2fe 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -102,6 +102,10 @@ class GenericEnd2endTest : public ::testing::Test {
builder.AddListeningPort(server_address_.str(),
InsecureServerCredentials());
builder.RegisterAsyncGenericService(&generic_service_);
+ // Include a second call to RegisterAsyncGenericService to make sure that
+ // we get an error in the log, since it is not allowed to have 2 async
+ // generic services
+ builder.RegisterAsyncGenericService(&generic_service_);
srv_cq_ = builder.AddCompletionQueue();
server_ = builder.BuildAndStart();
}
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index 6340007fa4..05ef0c8d9d 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -80,6 +80,24 @@ CompressionType GetInteropCompressionTypeFromCompressionAlgorithm(
GPR_ASSERT(false);
}
}
+
+void NoopChecks(const InteropClientContextInspector& inspector,
+ const SimpleRequest* request, const SimpleResponse* response) {}
+
+void CompressionChecks(const InteropClientContextInspector& inspector,
+ const SimpleRequest* request,
+ const SimpleResponse* response) {
+ GPR_ASSERT(request->response_compression() ==
+ GetInteropCompressionTypeFromCompressionAlgorithm(
+ inspector.GetCallCompressionAlgorithm()));
+ if (request->response_compression() == NONE) {
+ GPR_ASSERT(!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS));
+ } else if (request->response_type() == PayloadType::COMPRESSABLE) {
+ // requested compression and compressable response => results should always
+ // be compressed.
+ GPR_ASSERT(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS);
+ }
+}
} // namespace
InteropClient::ServiceStub::ServiceStub(std::shared_ptr<Channel> channel,
@@ -145,9 +163,14 @@ void InteropClient::DoEmpty() {
gpr_log(GPR_INFO, "Empty rpc done.");
}
-// Shared code to set large payload, make rpc and check response payload.
void InteropClient::PerformLargeUnary(SimpleRequest* request,
SimpleResponse* response) {
+ PerformLargeUnary(request, response, NoopChecks);
+}
+
+void InteropClient::PerformLargeUnary(SimpleRequest* request,
+ SimpleResponse* response,
+ CheckerFn custom_checks_fn) {
ClientContext context;
InteropClientContextInspector inspector(context);
// If the request doesn't already specify the response type, default to
@@ -157,21 +180,10 @@ void InteropClient::PerformLargeUnary(SimpleRequest* request,
request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
Status s = serviceStub_.Get()->UnaryCall(&context, *request, response);
-
- // Compression related checks.
- GPR_ASSERT(request->response_compression() ==
- GetInteropCompressionTypeFromCompressionAlgorithm(
- inspector.GetCallCompressionAlgorithm()));
- if (request->response_compression() == NONE) {
- GPR_ASSERT(!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS));
- } else if (request->response_type() == PayloadType::COMPRESSABLE) {
- // requested compression and compressable response => results should always
- // be compressed.
- GPR_ASSERT(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS);
- }
-
AssertOkOrPrintErrorStatus(s);
+ custom_checks_fn(inspector, request, response);
+
// Payload related checks.
if (request->response_type() != PayloadType::RANDOM) {
GPR_ASSERT(response->payload().type() == request->response_type());
@@ -293,7 +305,7 @@ void InteropClient::DoLargeCompressedUnary() {
SimpleResponse response;
request.set_response_type(payload_types[i]);
request.set_response_compression(compression_types[j]);
- PerformLargeUnary(&request, &response);
+ PerformLargeUnary(&request, &response, CompressionChecks);
gpr_log(GPR_INFO, "Large compressed unary done %s.", log_suffix);
gpr_free(log_suffix);
}
diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h
index 1bfb49d514..97a6fd77cf 100644
--- a/test/cpp/interop/interop_client.h
+++ b/test/cpp/interop/interop_client.h
@@ -44,6 +44,11 @@
namespace grpc {
namespace testing {
+// Function pointer for custom checks.
+using CheckerFn =
+ std::function<void(const InteropClientContextInspector&,
+ const SimpleRequest*, const SimpleResponse*)>;
+
class InteropClient {
public:
explicit InteropClient(std::shared_ptr<Channel> channel);
@@ -100,6 +105,10 @@ class InteropClient {
};
void PerformLargeUnary(SimpleRequest* request, SimpleResponse* response);
+
+ /// Run \a custom_check_fn as an additional check.
+ void PerformLargeUnary(SimpleRequest* request, SimpleResponse* response,
+ CheckerFn custom_checks_fn);
void AssertOkOrPrintErrorStatus(const Status& s);
ServiceStub serviceStub_;
};
diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc
index 1bd2a2fd78..2865c855a2 100644
--- a/test/cpp/interop/metrics_client.cc
+++ b/test/cpp/interop/metrics_client.cc
@@ -50,7 +50,7 @@ using grpc::testing::GaugeResponse;
using grpc::testing::MetricsService;
using grpc::testing::MetricsServiceImpl;
-void PrintMetrics(grpc::string& server_address) {
+void PrintMetrics(const grpc::string& server_address) {
gpr_log(GPR_INFO, "creating a channel to %s", server_address.c_str());
std::shared_ptr<grpc::Channel> channel(
grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials()));