aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/core/end2end/fixtures
diff options
context:
space:
mode:
Diffstat (limited to 'test/core/end2end/fixtures')
-rw-r--r--test/core/end2end/fixtures/chttp2_fake_security.c25
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack.c4
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack_compression.c13
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c4
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack_uds_posix_with_poll.c124
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack_with_poll.c4
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack_with_proxy.c132
-rw-r--r--test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c26
-rw-r--r--test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c26
-rw-r--r--test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c217
-rw-r--r--test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c68
-rw-r--r--test/core/end2end/fixtures/chttp2_socket_pair.c2
-rw-r--r--test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c2
-rw-r--r--test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c7
-rw-r--r--test/core/end2end/fixtures/proxy.c430
-rw-r--r--test/core/end2end/fixtures/proxy.h55
16 files changed, 1120 insertions, 19 deletions
diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c
index f879b43f79..78b692a45d 100644
--- a/test/core/end2end/fixtures/chttp2_fake_security.c
+++ b/test/core/end2end/fixtures/chttp2_fake_security.c
@@ -65,6 +65,14 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
return f;
}
+static void process_auth_failure(void *state, grpc_auth_context *ctx,
+ const grpc_metadata *md, size_t md_count,
+ grpc_process_auth_metadata_done_cb cb,
+ void *user_data) {
+ GPR_ASSERT(state == NULL);
+ cb(user_data, NULL, 0, 0);
+}
+
static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args,
grpc_credentials *creds) {
@@ -102,10 +110,27 @@ static void chttp2_init_client_fake_secure_fullstack(
chttp2_init_client_secure_fullstack(f, client_args, fake_ts_creds);
}
+static int fail_server_auth_check(grpc_channel_args *server_args) {
+ size_t i;
+ if (server_args == NULL) return 0;
+ for (i = 0; i < server_args->num_args; i++) {
+ if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
+ 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void chttp2_init_server_fake_secure_fullstack(
grpc_end2end_test_fixture *f, grpc_channel_args *server_args) {
grpc_server_credentials *fake_ts_creds =
grpc_fake_transport_security_server_credentials_create();
+ if (fail_server_auth_check(server_args)) {
+ grpc_auth_metadata_processor processor = {process_auth_failure, NULL};
+ grpc_server_credentials_set_auth_metadata_processor(fake_ts_creds,
+ processor);
+ }
chttp2_init_server_secure_fullstack(f, server_args, fake_ts_creds);
}
diff --git a/test/core/end2end/fixtures/chttp2_fullstack.c b/test/core/end2end/fixtures/chttp2_fullstack.c
index 8a1530e63b..53a6f0d7a5 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack.c
@@ -72,7 +72,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
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_channel_create(ffd->localaddr, client_args);
+ f->client = grpc_insecure_channel_create(ffd->localaddr, client_args);
GPR_ASSERT(f->client);
}
@@ -84,7 +84,7 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
}
f->server = grpc_server_create(server_args);
grpc_server_register_completion_queue(f->server, f->cq);
- GPR_ASSERT(grpc_server_add_http2_port(f->server, ffd->localaddr));
+ GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server);
}
diff --git a/test/core/end2end/fixtures/chttp2_fullstack_compression.c b/test/core/end2end/fixtures/chttp2_fullstack_compression.c
index 0a9a312296..a75075d1d4 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack_compression.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack_compression.c
@@ -53,8 +53,8 @@
typedef struct fullstack_compression_fixture_data {
char *localaddr;
- grpc_channel_args* client_args_compression;
- grpc_channel_args* server_args_compression;
+ grpc_channel_args *client_args_compression;
+ grpc_channel_args *server_args_compression;
} fullstack_compression_fixture_data;
static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_compression(
@@ -75,18 +75,19 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_compression(
}
void chttp2_init_client_fullstack_compression(grpc_end2end_test_fixture *f,
- grpc_channel_args *client_args) {
+ grpc_channel_args *client_args) {
fullstack_compression_fixture_data *ffd = f->fixture_data;
if (ffd->client_args_compression != NULL) {
grpc_channel_args_destroy(ffd->client_args_compression);
}
ffd->client_args_compression = grpc_channel_args_set_compression_algorithm(
client_args, GRPC_COMPRESS_GZIP);
- f->client = grpc_channel_create(ffd->localaddr, ffd->client_args_compression);
+ f->client = grpc_insecure_channel_create(ffd->localaddr,
+ ffd->client_args_compression);
}
void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture *f,
- grpc_channel_args *server_args) {
+ grpc_channel_args *server_args) {
fullstack_compression_fixture_data *ffd = f->fixture_data;
if (ffd->server_args_compression != NULL) {
grpc_channel_args_destroy(ffd->server_args_compression);
@@ -98,7 +99,7 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture *f,
}
f->server = grpc_server_create(ffd->server_args_compression);
grpc_server_register_completion_queue(f->server, f->cq);
- GPR_ASSERT(grpc_server_add_http2_port(f->server, ffd->localaddr));
+ GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server);
}
diff --git a/test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c b/test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c
index 351e1c5459..20afdb868e 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c
@@ -78,7 +78,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
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_channel_create(ffd->localaddr, client_args);
+ f->client = grpc_insecure_channel_create(ffd->localaddr, client_args);
}
void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
@@ -89,7 +89,7 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
}
f->server = grpc_server_create(server_args);
grpc_server_register_completion_queue(f->server, f->cq);
- GPR_ASSERT(grpc_server_add_http2_port(f->server, ffd->localaddr));
+ GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server);
}
diff --git a/test/core/end2end/fixtures/chttp2_fullstack_uds_posix_with_poll.c b/test/core/end2end/fixtures/chttp2_fullstack_uds_posix_with_poll.c
new file mode 100644
index 0000000000..8491ea6970
--- /dev/null
+++ b/test/core/end2end/fixtures/chttp2_fullstack_uds_posix_with_poll.c
@@ -0,0 +1,124 @@
+/*
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <unistd.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/support/string.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/string_util.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 int unique = 1;
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
+ grpc_channel_args *client_args, grpc_channel_args *server_args) {
+ grpc_end2end_test_fixture f;
+ fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data));
+ memset(&f, 0, sizeof(f));
+
+ gpr_asprintf(&ffd->localaddr, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(),
+ unique++);
+
+ f.fixture_data = ffd;
+ f.cq = grpc_completion_queue_create();
+
+ 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);
+}
+
+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);
+ grpc_server_register_completion_queue(f->server, f->cq);
+ 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_uds", 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_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/chttp2_fullstack_with_poll.c b/test/core/end2end/fixtures/chttp2_fullstack_with_poll.c
index 69860d04d5..2a4835add1 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack_with_poll.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack_with_poll.c
@@ -72,7 +72,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
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_channel_create(ffd->localaddr, client_args);
+ f->client = grpc_insecure_channel_create(ffd->localaddr, client_args);
}
void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
@@ -83,7 +83,7 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
}
f->server = grpc_server_create(server_args);
grpc_server_register_completion_queue(f->server, f->cq);
- GPR_ASSERT(grpc_server_add_http2_port(f->server, ffd->localaddr));
+ GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server);
}
diff --git a/test/core/end2end/fixtures/chttp2_fullstack_with_proxy.c b/test/core/end2end/fixtures/chttp2_fullstack_with_proxy.c
new file mode 100644
index 0000000000..248cc7d6e7
--- /dev/null
+++ b/test/core/end2end/fixtures/chttp2_fullstack_with_proxy.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/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/end2end/fixtures/proxy.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+typedef struct fullstack_fixture_data {
+ grpc_end2end_proxy *proxy;
+} fullstack_fixture_data;
+
+static grpc_server *create_proxy_server(const char *port) {
+ grpc_server *s = grpc_server_create(NULL);
+ GPR_ASSERT(grpc_server_add_insecure_http2_port(s, port));
+ return s;
+}
+
+static grpc_channel *create_proxy_client(const char *target) {
+ return grpc_insecure_channel_create(target, NULL);
+}
+
+static const grpc_end2end_proxy_def proxy_def = {create_proxy_server,
+ create_proxy_client};
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
+ grpc_channel_args *client_args, grpc_channel_args *server_args) {
+ grpc_end2end_test_fixture f;
+ fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data));
+ memset(&f, 0, sizeof(f));
+
+ ffd->proxy = grpc_end2end_proxy_create(&proxy_def);
+
+ f.fixture_data = ffd;
+ f.cq = grpc_completion_queue_create();
+
+ 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(
+ grpc_end2end_proxy_get_client_target(ffd->proxy), 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;
+ if (f->server) {
+ grpc_server_destroy(f->server);
+ }
+ f->server = grpc_server_create(server_args);
+ grpc_server_register_completion_queue(f->server, f->cq);
+ GPR_ASSERT(grpc_server_add_insecure_http2_port(
+ f->server, grpc_end2end_proxy_get_server_port(ffd->proxy)));
+ grpc_server_start(f->server);
+}
+
+void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) {
+ fullstack_fixture_data *ffd = f->fixture_data;
+ grpc_end2end_proxy_destroy(ffd->proxy);
+ gpr_free(ffd);
+}
+
+/* All test configurations */
+static grpc_end2end_test_config configs[] = {
+ {"chttp2/fullstack+proxy", 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/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
index 73a36116fb..9850aac69b 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
@@ -68,6 +68,14 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
return f;
}
+static void process_auth_failure(void *state, grpc_auth_context *ctx,
+ const grpc_metadata *md, size_t md_count,
+ grpc_process_auth_metadata_done_cb cb,
+ void *user_data) {
+ GPR_ASSERT(state == NULL);
+ cb(user_data, NULL, 0, 0);
+}
+
static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args,
grpc_credentials *creds) {
@@ -110,12 +118,28 @@ static void chttp2_init_client_simple_ssl_secure_fullstack(
grpc_channel_args_destroy(new_client_args);
}
+static int fail_server_auth_check(grpc_channel_args *server_args) {
+ size_t i;
+ if (server_args == NULL) return 0;
+ for (i = 0; i < server_args->num_args; i++) {
+ if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
+ 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void chttp2_init_server_simple_ssl_secure_fullstack(
grpc_end2end_test_fixture *f, grpc_channel_args *server_args) {
grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
test_server1_cert};
grpc_server_credentials *ssl_creds =
- grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1);
+ grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0);
+ if (fail_server_auth_check(server_args)) {
+ grpc_auth_metadata_processor processor = {process_auth_failure, NULL};
+ grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
+ }
chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
}
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c
index b1ac3e535f..3df2acd296 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c
@@ -68,6 +68,14 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
return f;
}
+static void process_auth_failure(void *state, grpc_auth_context *ctx,
+ const grpc_metadata *md, size_t md_count,
+ grpc_process_auth_metadata_done_cb cb,
+ void *user_data) {
+ GPR_ASSERT(state == NULL);
+ cb(user_data, NULL, 0, 0);
+}
+
static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args,
grpc_credentials *creds) {
@@ -110,12 +118,28 @@ static void chttp2_init_client_simple_ssl_secure_fullstack(
grpc_channel_args_destroy(new_client_args);
}
+static int fail_server_auth_check(grpc_channel_args *server_args) {
+ size_t i;
+ if (server_args == NULL) return 0;
+ for (i = 0; i < server_args->num_args; i++) {
+ if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
+ 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void chttp2_init_server_simple_ssl_secure_fullstack(
grpc_end2end_test_fixture *f, grpc_channel_args *server_args) {
grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
test_server1_cert};
grpc_server_credentials *ssl_creds =
- grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1);
+ grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0);
+ if (fail_server_auth_check(server_args)) {
+ grpc_auth_metadata_processor processor = {process_auth_failure, NULL};
+ grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
+ }
chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
}
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c
new file mode 100644
index 0000000000..4d77039cac
--- /dev/null
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c
@@ -0,0 +1,217 @@
+/*
+ *
+ * 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/channel/channel_args.h"
+#include "src/core/security/credentials.h"
+#include "src/core/support/env.h"
+#include "src/core/support/file.h"
+#include "src/core/support/string.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include "test/core/end2end/data/ssl_test_data.h"
+#include "test/core/end2end/fixtures/proxy.h"
+#include "test/core/util/test_config.h"
+#include "test/core/util/port.h"
+
+typedef struct fullstack_secure_fixture_data {
+ grpc_end2end_proxy *proxy;
+} fullstack_secure_fixture_data;
+
+static grpc_server *create_proxy_server(const char *port) {
+ grpc_server *s = grpc_server_create(NULL);
+ grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
+ test_server1_cert};
+ grpc_server_credentials *ssl_creds =
+ grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0);
+ GPR_ASSERT(grpc_server_add_secure_http2_port(s, port, ssl_creds));
+ grpc_server_credentials_release(ssl_creds);
+ return s;
+}
+
+static grpc_channel *create_proxy_client(const char *target) {
+ grpc_channel *channel;
+ grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL);
+ grpc_arg ssl_name_override = {GRPC_ARG_STRING,
+ GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
+ {"foo.test.google.fr"}};
+ grpc_channel_args client_args;
+ client_args.num_args = 1;
+ client_args.args = &ssl_name_override;
+ channel = grpc_secure_channel_create(ssl_creds, target, &client_args);
+ grpc_credentials_release(ssl_creds);
+ return channel;
+}
+
+static const grpc_end2end_proxy_def proxy_def = {create_proxy_server,
+ create_proxy_client};
+
+static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
+ grpc_channel_args *client_args, grpc_channel_args *server_args) {
+ grpc_end2end_test_fixture f;
+ fullstack_secure_fixture_data *ffd =
+ gpr_malloc(sizeof(fullstack_secure_fixture_data));
+ memset(&f, 0, sizeof(f));
+
+ ffd->proxy = grpc_end2end_proxy_create(&proxy_def);
+
+ f.fixture_data = ffd;
+ f.cq = grpc_completion_queue_create();
+
+ return f;
+}
+
+static void process_auth_failure(void *state, grpc_auth_context *ctx,
+ const grpc_metadata *md, size_t md_count,
+ grpc_process_auth_metadata_done_cb cb,
+ void *user_data) {
+ GPR_ASSERT(state == NULL);
+ cb(user_data, NULL, 0, 0);
+}
+
+static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
+ grpc_channel_args *client_args,
+ grpc_credentials *creds) {
+ fullstack_secure_fixture_data *ffd = f->fixture_data;
+ f->client = grpc_secure_channel_create(
+ creds, grpc_end2end_proxy_get_client_target(ffd->proxy), client_args);
+ GPR_ASSERT(f->client != NULL);
+ grpc_credentials_release(creds);
+}
+
+static void chttp2_init_server_secure_fullstack(
+ grpc_end2end_test_fixture *f, grpc_channel_args *server_args,
+ grpc_server_credentials *server_creds) {
+ fullstack_secure_fixture_data *ffd = f->fixture_data;
+ if (f->server) {
+ grpc_server_destroy(f->server);
+ }
+ f->server = grpc_server_create(server_args);
+ grpc_server_register_completion_queue(f->server, f->cq);
+ GPR_ASSERT(grpc_server_add_secure_http2_port(
+ f->server, grpc_end2end_proxy_get_server_port(ffd->proxy), server_creds));
+ grpc_server_credentials_release(server_creds);
+ grpc_server_start(f->server);
+}
+
+void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) {
+ fullstack_secure_fixture_data *ffd = f->fixture_data;
+ grpc_end2end_proxy_destroy(ffd->proxy);
+ gpr_free(ffd);
+}
+
+static void chttp2_init_client_simple_ssl_secure_fullstack(
+ grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
+ grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL);
+ grpc_arg ssl_name_override = {GRPC_ARG_STRING,
+ GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
+ {"foo.test.google.fr"}};
+ grpc_channel_args *new_client_args =
+ grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
+ chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
+ grpc_channel_args_destroy(new_client_args);
+}
+
+static int fail_server_auth_check(grpc_channel_args *server_args) {
+ size_t i;
+ if (server_args == NULL) return 0;
+ for (i = 0; i < server_args->num_args; i++) {
+ if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
+ 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void chttp2_init_server_simple_ssl_secure_fullstack(
+ grpc_end2end_test_fixture *f, grpc_channel_args *server_args) {
+ grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
+ test_server1_cert};
+ grpc_server_credentials *ssl_creds =
+ grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0);
+ if (fail_server_auth_check(server_args)) {
+ grpc_auth_metadata_processor processor = {process_auth_failure, NULL};
+ grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
+ }
+ chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
+}
+
+/* All test configurations */
+
+static grpc_end2end_test_config configs[] = {
+ {"chttp2/simple_ssl_fullstack",
+ FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+ FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION |
+ FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
+ chttp2_create_fixture_secure_fullstack,
+ chttp2_init_client_simple_ssl_secure_fullstack,
+ chttp2_init_server_simple_ssl_secure_fullstack,
+ chttp2_tear_down_secure_fullstack},
+};
+
+int main(int argc, char **argv) {
+ size_t i;
+ FILE *roots_file;
+ size_t roots_size = strlen(test_root_cert);
+ char *roots_filename;
+
+ grpc_test_init(argc, argv);
+
+ /* Set the SSL roots env var. */
+ roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename);
+ GPR_ASSERT(roots_filename != NULL);
+ GPR_ASSERT(roots_file != NULL);
+ GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
+ fclose(roots_file);
+ gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
+
+ grpc_init();
+
+ for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+ grpc_end2end_tests(configs[i]);
+ }
+
+ grpc_shutdown();
+
+ /* Cleanup. */
+ remove(roots_filename);
+ gpr_free(roots_filename);
+
+ return 0;
+}
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
index de418bf7ee..284d5f07ae 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
@@ -46,10 +46,54 @@
#include "test/core/util/port.h"
#include "test/core/end2end/data/ssl_test_data.h"
+static const char oauth2_md[] = "Bearer aaslkfjs424535asdf";
+static const char *client_identity_property_name = "smurf_name";
+static const char *client_identity = "Brainy Smurf";
+
typedef struct fullstack_secure_fixture_data {
char *localaddr;
} fullstack_secure_fixture_data;
+static const grpc_metadata *find_metadata(const grpc_metadata *md,
+ size_t md_count,
+ const char *key,
+ const char *value) {
+ size_t i;
+ for (i = 0; i < md_count; i++) {
+ if (strcmp(key, md[i].key) == 0 && strlen(value) == md[i].value_length &&
+ memcmp(md[i].value, value, md[i].value_length) == 0) {
+ return &md[i];
+ }
+ }
+ return NULL;
+}
+
+static void process_oauth2_success(void *state, grpc_auth_context *ctx,
+ const grpc_metadata *md, size_t md_count,
+ grpc_process_auth_metadata_done_cb cb,
+ void *user_data) {
+ const grpc_metadata *oauth2 =
+ find_metadata(md, md_count, "Authorization", oauth2_md);
+ GPR_ASSERT(state == NULL);
+ GPR_ASSERT(oauth2 != NULL);
+ grpc_auth_context_add_cstring_property(ctx, client_identity_property_name,
+ client_identity);
+ GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
+ ctx, client_identity_property_name) == 1);
+ cb(user_data, oauth2, 1, 1);
+}
+
+static void process_oauth2_failure(void *state, grpc_auth_context *ctx,
+ const grpc_metadata *md, size_t md_count,
+ grpc_process_auth_metadata_done_cb cb,
+ void *user_data) {
+ const grpc_metadata *oauth2 =
+ find_metadata(md, md_count, "Authorization", oauth2_md);
+ GPR_ASSERT(state == NULL);
+ GPR_ASSERT(oauth2 != NULL);
+ cb(user_data, oauth2, 1, 0);
+}
+
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
grpc_channel_args *client_args, grpc_channel_args *server_args) {
grpc_end2end_test_fixture f;
@@ -101,7 +145,7 @@ static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack(
grpc_credentials *ssl_creds =
grpc_ssl_credentials_create(test_root_cert, NULL);
grpc_credentials *oauth2_creds =
- grpc_fake_oauth2_credentials_create("Bearer aaslkfjs424535asdf", 1);
+ grpc_md_only_test_credentials_create("Authorization", oauth2_md, 1);
grpc_credentials *ssl_oauth2_creds =
grpc_composite_credentials_create(ssl_creds, oauth2_creds);
grpc_arg ssl_name_override = {GRPC_ARG_STRING,
@@ -115,12 +159,32 @@ static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack(
grpc_credentials_release(oauth2_creds);
}
+static int fail_server_auth_check(grpc_channel_args *server_args) {
+ size_t i;
+ if (server_args == NULL) return 0;
+ for (i = 0; i < server_args->num_args; i++) {
+ if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
+ 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void chttp2_init_server_simple_ssl_secure_fullstack(
grpc_end2end_test_fixture *f, grpc_channel_args *server_args) {
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key,
test_server1_cert};
grpc_server_credentials *ssl_creds =
- grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1);
+ grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0);
+ grpc_auth_metadata_processor processor;
+ processor.state = NULL;
+ if (fail_server_auth_check(server_args)) {
+ processor.process = process_oauth2_failure;
+ } else {
+ processor.process = process_oauth2_success;
+ }
+ grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
}
diff --git a/test/core/end2end/fixtures/chttp2_socket_pair.c b/test/core/end2end/fixtures/chttp2_socket_pair.c
index 37b61cf37f..807fc8e7bc 100644
--- a/test/core/end2end/fixtures/chttp2_socket_pair.c
+++ b/test/core/end2end/fixtures/chttp2_socket_pair.c
@@ -80,7 +80,7 @@ static void client_setup_transport(void *ts, grpc_transport *transport,
&grpc_connected_channel_filter};
size_t nfilters = sizeof(filters) / sizeof(*filters);
grpc_channel *channel = grpc_channel_create_from_filters(
- filters, nfilters, cs->client_args, mdctx, 1);
+ "socketpair-target", filters, nfilters, cs->client_args, mdctx, 1);
cs->f->client = channel;
diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c
index 2ec2697288..21d4404237 100644
--- a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c
+++ b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c
@@ -80,7 +80,7 @@ static void client_setup_transport(void *ts, grpc_transport *transport,
&grpc_connected_channel_filter};
size_t nfilters = sizeof(filters) / sizeof(*filters);
grpc_channel *channel = grpc_channel_create_from_filters(
- filters, nfilters, cs->client_args, mdctx, 1);
+ "socketpair-target", filters, nfilters, cs->client_args, mdctx, 1);
cs->f->client = channel;
diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c b/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c
index 3aa364c5e0..9d798ad1d2 100644
--- a/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c
+++ b/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c
@@ -81,7 +81,7 @@ static void client_setup_transport(void *ts, grpc_transport *transport,
&grpc_connected_channel_filter};
size_t nfilters = sizeof(filters) / sizeof(*filters);
grpc_channel *channel = grpc_channel_create_from_filters(
- filters, nfilters, cs->client_args, mdctx, 1);
+ "socketpair-target", filters, nfilters, cs->client_args, mdctx, 1);
cs->f->client = channel;
@@ -148,6 +148,11 @@ int main(int argc, char **argv) {
/* force tracing on, with a value to force many
code paths in trace.c to be taken */
gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all");
+#ifdef GPR_POSIX_SOCKET
+ g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10.0 : 1.0;
+#else
+ g_fixture_slowdown_factor = 10.0;
+#endif
grpc_test_init(argc, argv);
grpc_init();
diff --git a/test/core/end2end/fixtures/proxy.c b/test/core/end2end/fixtures/proxy.c
new file mode 100644
index 0000000000..e4f6263334
--- /dev/null
+++ b/test/core/end2end/fixtures/proxy.c
@@ -0,0 +1,430 @@
+/*
+ *
+ * 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/fixtures/proxy.h"
+
+#include <string.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"
+
+struct grpc_end2end_proxy {
+ gpr_thd_id thd;
+ char *proxy_port;
+ char *server_port;
+ grpc_completion_queue *cq;
+ grpc_server *server;
+ grpc_channel *client;
+
+ int shutdown;
+
+ /* requested call */
+ grpc_call *new_call;
+ grpc_call_details new_call_details;
+ grpc_metadata_array new_call_metadata;
+};
+
+typedef struct {
+ void (*func)(void *arg, int success);
+ void *arg;
+} closure;
+
+typedef struct {
+ gpr_refcount refs;
+ grpc_end2end_proxy *proxy;
+
+ grpc_call *c2p;
+ grpc_call *p2s;
+
+ grpc_metadata_array c2p_initial_metadata;
+ grpc_metadata_array p2s_initial_metadata;
+
+ grpc_byte_buffer *c2p_msg;
+ grpc_byte_buffer *p2s_msg;
+
+ grpc_metadata_array p2s_trailing_metadata;
+ grpc_status_code p2s_status;
+ char *p2s_status_details;
+ size_t p2s_status_details_capacity;
+
+ int c2p_server_cancelled;
+} proxy_call;
+
+static void thread_main(void *arg);
+static void request_call(grpc_end2end_proxy *proxy);
+
+grpc_end2end_proxy *grpc_end2end_proxy_create(
+ const grpc_end2end_proxy_def *def) {
+ gpr_thd_options opt = gpr_thd_options_default();
+ int proxy_port = grpc_pick_unused_port_or_die();
+ int server_port = grpc_pick_unused_port_or_die();
+
+ grpc_end2end_proxy *proxy = gpr_malloc(sizeof(*proxy));
+ memset(proxy, 0, sizeof(*proxy));
+
+ gpr_join_host_port(&proxy->proxy_port, "localhost", proxy_port);
+ gpr_join_host_port(&proxy->server_port, "localhost", server_port);
+ proxy->cq = grpc_completion_queue_create();
+ proxy->server = def->create_server(proxy->proxy_port);
+ proxy->client = def->create_client(proxy->server_port);
+
+ grpc_server_register_completion_queue(proxy->server, proxy->cq);
+ grpc_server_start(proxy->server);
+
+ gpr_thd_options_set_joinable(&opt);
+ GPR_ASSERT(gpr_thd_new(&proxy->thd, thread_main, proxy, &opt));
+
+ request_call(proxy);
+
+ return proxy;
+}
+
+static closure *new_closure(void (*func)(void *arg, int success), void *arg) {
+ closure *cl = gpr_malloc(sizeof(*cl));
+ cl->func = func;
+ cl->arg = arg;
+ return cl;
+}
+
+static void shutdown_complete(void *arg, int success) {
+ grpc_end2end_proxy *proxy = arg;
+ proxy->shutdown = 1;
+ grpc_completion_queue_shutdown(proxy->cq);
+}
+
+void grpc_end2end_proxy_destroy(grpc_end2end_proxy *proxy) {
+ grpc_server_shutdown_and_notify(proxy->server, proxy->cq,
+ new_closure(shutdown_complete, proxy));
+ gpr_thd_join(proxy->thd);
+ gpr_free(proxy->proxy_port);
+ gpr_free(proxy->server_port);
+ grpc_server_destroy(proxy->server);
+ grpc_channel_destroy(proxy->client);
+ grpc_completion_queue_destroy(proxy->cq);
+ grpc_call_details_destroy(&proxy->new_call_details);
+ gpr_free(proxy);
+}
+
+static void unrefpc(proxy_call *pc, const char *reason) {
+ gpr_log(GPR_DEBUG, "unref %p: %s %d -> %d", pc, reason, pc->refs.count,
+ pc->refs.count - 1);
+ if (gpr_unref(&pc->refs)) {
+ grpc_call_destroy(pc->c2p);
+ grpc_call_destroy(pc->p2s);
+ grpc_metadata_array_destroy(&pc->c2p_initial_metadata);
+ grpc_metadata_array_destroy(&pc->p2s_initial_metadata);
+ grpc_metadata_array_destroy(&pc->p2s_trailing_metadata);
+ gpr_free(pc->p2s_status_details);
+ gpr_free(pc);
+ }
+}
+
+static void refpc(proxy_call *pc, const char *reason) {
+ gpr_log(GPR_DEBUG, "ref %p: %s %d -> %d", pc, reason, pc->refs.count,
+ pc->refs.count + 1);
+ gpr_ref(&pc->refs);
+}
+
+static void on_c2p_sent_initial_metadata(void *arg, int success) {
+ proxy_call *pc = arg;
+ unrefpc(pc, "on_c2p_sent_initial_metadata");
+}
+
+static void on_p2s_recv_initial_metadata(void *arg, int success) {
+ proxy_call *pc = arg;
+ grpc_op op;
+ grpc_call_error err;
+
+ if (!pc->proxy->shutdown) {
+ op.op = GRPC_OP_SEND_INITIAL_METADATA;
+ op.flags = 0;
+ op.data.send_initial_metadata.count = pc->p2s_initial_metadata.count;
+ op.data.send_initial_metadata.metadata = pc->p2s_initial_metadata.metadata;
+ refpc(pc, "on_c2p_sent_initial_metadata");
+ err = grpc_call_start_batch(pc->c2p, &op, 1,
+ new_closure(on_c2p_sent_initial_metadata, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+ }
+
+ unrefpc(pc, "on_p2s_recv_initial_metadata");
+}
+
+static void on_p2s_sent_initial_metadata(void *arg, int success) {
+ proxy_call *pc = arg;
+ unrefpc(pc, "on_p2s_sent_initial_metadata");
+}
+
+static void on_c2p_recv_msg(void *arg, int success);
+
+static void on_p2s_sent_message(void *arg, int success) {
+ proxy_call *pc = arg;
+ grpc_op op;
+ grpc_call_error err;
+
+ grpc_byte_buffer_destroy(pc->c2p_msg);
+ if (!pc->proxy->shutdown && success) {
+ op.op = GRPC_OP_RECV_MESSAGE;
+ op.flags = 0;
+ op.data.recv_message = &pc->c2p_msg;
+ refpc(pc, "on_c2p_recv_msg");
+ err = grpc_call_start_batch(pc->c2p, &op, 1,
+ new_closure(on_c2p_recv_msg, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+ }
+
+ unrefpc(pc, "on_p2s_sent_message");
+}
+
+static void on_p2s_sent_close(void *arg, int success) {
+ proxy_call *pc = arg;
+ unrefpc(pc, "on_p2s_sent_close");
+}
+
+static void on_c2p_recv_msg(void *arg, int success) {
+ proxy_call *pc = arg;
+ grpc_op op;
+ grpc_call_error err;
+
+ if (!pc->proxy->shutdown && success) {
+ if (pc->c2p_msg != NULL) {
+ op.op = GRPC_OP_SEND_MESSAGE;
+ op.flags = 0;
+ op.data.send_message = pc->c2p_msg;
+ refpc(pc, "on_p2s_sent_message");
+ err = grpc_call_start_batch(pc->p2s, &op, 1,
+ new_closure(on_p2s_sent_message, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+ } else {
+ op.op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op.flags = 0;
+ refpc(pc, "on_p2s_sent_close");
+ err = grpc_call_start_batch(pc->p2s, &op, 1,
+ new_closure(on_p2s_sent_close, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+ }
+ }
+
+ unrefpc(pc, "on_c2p_recv_msg");
+}
+
+static void on_p2s_recv_msg(void *arg, int success);
+
+static void on_c2p_sent_message(void *arg, int success) {
+ proxy_call *pc = arg;
+ grpc_op op;
+ grpc_call_error err;
+
+ grpc_byte_buffer_destroy(pc->p2s_msg);
+ if (!pc->proxy->shutdown && success) {
+ op.op = GRPC_OP_RECV_MESSAGE;
+ op.flags = 0;
+ op.data.recv_message = &pc->p2s_msg;
+ refpc(pc, "on_p2s_recv_msg");
+ err = grpc_call_start_batch(pc->p2s, &op, 1,
+ new_closure(on_p2s_recv_msg, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+ }
+
+ unrefpc(pc, "on_c2p_sent_message");
+}
+
+static void on_p2s_recv_msg(void *arg, int success) {
+ proxy_call *pc = arg;
+ grpc_op op;
+ grpc_call_error err;
+
+ if (!pc->proxy->shutdown && success && pc->p2s_msg) {
+ op.op = GRPC_OP_SEND_MESSAGE;
+ op.flags = 0;
+ op.data.send_message = pc->p2s_msg;
+ refpc(pc, "on_c2p_sent_message");
+ err = grpc_call_start_batch(pc->c2p, &op, 1,
+ new_closure(on_c2p_sent_message, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+ }
+ unrefpc(pc, "on_p2s_recv_msg");
+}
+
+static void on_c2p_sent_status(void *arg, int success) {
+ proxy_call *pc = arg;
+ unrefpc(pc, "on_c2p_sent_status");
+}
+
+static void on_p2s_status(void *arg, int success) {
+ proxy_call *pc = arg;
+ grpc_op op;
+ grpc_call_error err;
+
+ if (!pc->proxy->shutdown) {
+ GPR_ASSERT(success);
+ op.op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op.flags = 0;
+ op.data.send_status_from_server.trailing_metadata_count =
+ pc->p2s_trailing_metadata.count;
+ op.data.send_status_from_server.trailing_metadata =
+ pc->p2s_trailing_metadata.metadata;
+ op.data.send_status_from_server.status = pc->p2s_status;
+ op.data.send_status_from_server.status_details = pc->p2s_status_details;
+ refpc(pc, "on_c2p_sent_status");
+ err = grpc_call_start_batch(pc->c2p, &op, 1,
+ new_closure(on_c2p_sent_status, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+ }
+
+ unrefpc(pc, "on_p2s_status");
+}
+
+static void on_c2p_closed(void *arg, int success) {
+ proxy_call *pc = arg;
+ unrefpc(pc, "on_c2p_closed");
+}
+
+static void on_new_call(void *arg, int success) {
+ grpc_end2end_proxy *proxy = arg;
+ grpc_call_error err;
+
+ if (success) {
+ grpc_op op;
+ proxy_call *pc = gpr_malloc(sizeof(*pc));
+ memset(pc, 0, sizeof(*pc));
+ pc->proxy = proxy;
+ GPR_SWAP(grpc_metadata_array, pc->c2p_initial_metadata,
+ proxy->new_call_metadata);
+ pc->c2p = proxy->new_call;
+ pc->p2s = grpc_channel_create_call(
+ proxy->client, pc->c2p, GRPC_PROPAGATE_DEFAULTS, proxy->cq,
+ proxy->new_call_details.method, proxy->new_call_details.host,
+ proxy->new_call_details.deadline);
+ gpr_ref_init(&pc->refs, 1);
+
+ op.flags = 0;
+
+ op.op = GRPC_OP_RECV_INITIAL_METADATA;
+ op.data.recv_initial_metadata = &pc->p2s_initial_metadata;
+ refpc(pc, "on_p2s_recv_initial_metadata");
+ err = grpc_call_start_batch(pc->p2s, &op, 1,
+ new_closure(on_p2s_recv_initial_metadata, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+
+ op.op = GRPC_OP_SEND_INITIAL_METADATA;
+ op.data.send_initial_metadata.count = pc->c2p_initial_metadata.count;
+ op.data.send_initial_metadata.metadata = pc->c2p_initial_metadata.metadata;
+ refpc(pc, "on_p2s_sent_initial_metadata");
+ err = grpc_call_start_batch(pc->p2s, &op, 1,
+ new_closure(on_p2s_sent_initial_metadata, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+
+ op.op = GRPC_OP_RECV_MESSAGE;
+ op.data.recv_message = &pc->c2p_msg;
+ refpc(pc, "on_c2p_recv_msg");
+ err = grpc_call_start_batch(pc->c2p, &op, 1,
+ new_closure(on_c2p_recv_msg, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+
+ op.op = GRPC_OP_RECV_MESSAGE;
+ op.data.recv_message = &pc->p2s_msg;
+ refpc(pc, "on_p2s_recv_msg");
+ err = grpc_call_start_batch(pc->p2s, &op, 1,
+ new_closure(on_p2s_recv_msg, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+
+ op.op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op.data.recv_status_on_client.trailing_metadata =
+ &pc->p2s_trailing_metadata;
+ op.data.recv_status_on_client.status = &pc->p2s_status;
+ op.data.recv_status_on_client.status_details = &pc->p2s_status_details;
+ op.data.recv_status_on_client.status_details_capacity =
+ &pc->p2s_status_details_capacity;
+ refpc(pc, "on_p2s_status");
+ err =
+ grpc_call_start_batch(pc->p2s, &op, 1, new_closure(on_p2s_status, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+
+ op.op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op.data.recv_close_on_server.cancelled = &pc->c2p_server_cancelled;
+ refpc(pc, "on_c2p_closed");
+ err =
+ grpc_call_start_batch(pc->c2p, &op, 1, new_closure(on_c2p_closed, pc));
+ GPR_ASSERT(err == GRPC_CALL_OK);
+
+ request_call(proxy);
+
+ unrefpc(pc, "init");
+ } else {
+ GPR_ASSERT(proxy->new_call == NULL);
+ }
+}
+
+static void request_call(grpc_end2end_proxy *proxy) {
+ proxy->new_call = NULL;
+ GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
+ proxy->server, &proxy->new_call,
+ &proxy->new_call_details,
+ &proxy->new_call_metadata, proxy->cq,
+ proxy->cq, new_closure(on_new_call, proxy)));
+}
+
+static void thread_main(void *arg) {
+ grpc_end2end_proxy *proxy = arg;
+ closure *cl;
+ for (;;) {
+ grpc_event ev = grpc_completion_queue_next(
+ proxy->cq, gpr_inf_future(GPR_CLOCK_MONOTONIC));
+ switch (ev.type) {
+ case GRPC_QUEUE_TIMEOUT:
+ gpr_log(GPR_ERROR, "Should never reach here");
+ abort();
+ case GRPC_QUEUE_SHUTDOWN:
+ return;
+ case GRPC_OP_COMPLETE:
+ cl = ev.tag;
+ cl->func(cl->arg, ev.success);
+ gpr_free(cl);
+ break;
+ }
+ }
+}
+
+const char *grpc_end2end_proxy_get_client_target(grpc_end2end_proxy *proxy) {
+ return proxy->proxy_port;
+}
+
+const char *grpc_end2end_proxy_get_server_port(grpc_end2end_proxy *proxy) {
+ return proxy->server_port;
+}
diff --git a/test/core/end2end/fixtures/proxy.h b/test/core/end2end/fixtures/proxy.h
new file mode 100644
index 0000000000..c1cf01d39a
--- /dev/null
+++ b/test/core/end2end/fixtures/proxy.h
@@ -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.
+ *
+ */
+
+#ifndef GRPC_TEST_CORE_END2END_FIXTURES_PROXY_H
+#define GRPC_TEST_CORE_END2END_FIXTURES_PROXY_H
+
+#include <grpc/grpc.h>
+
+/* proxy service for _with_proxy fixtures */
+
+typedef struct grpc_end2end_proxy grpc_end2end_proxy;
+
+typedef struct grpc_end2end_proxy_def {
+ grpc_server *(*create_server)(const char *port);
+ grpc_channel *(*create_client)(const char *target);
+} grpc_end2end_proxy_def;
+
+grpc_end2end_proxy *grpc_end2end_proxy_create(
+ const grpc_end2end_proxy_def *def);
+void grpc_end2end_proxy_destroy(grpc_end2end_proxy *proxy);
+
+const char *grpc_end2end_proxy_get_client_target(grpc_end2end_proxy *proxy);
+const char *grpc_end2end_proxy_get_server_port(grpc_end2end_proxy *proxy);
+
+#endif /* GRPC_TEST_CORE_END2END_FIXTURES_PROXY_H */