aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-06-15 09:41:33 -0700
committerGravatar Craig Tiller <ctiller@google.com>2016-06-15 09:41:33 -0700
commit13c0940f662e79bed94c28a9fc351ec87a634d6d (patch)
treebfebb81c2e22c3ad32063cfbd36771c77be4e7e0 /test
parent8df99f2ac5bd92463d4cb676abbcde0fe2f4beae (diff)
parent52f231212f0385bae40dd6e45ed1c4bf823bf3c2 (diff)
Merge branch 'idempotent_endpoint_shutdown' into handshake_timeout
Diffstat (limited to 'test')
-rw-r--r--test/core/client_config/lb_policies_test.c13
-rw-r--r--test/core/client_config/set_initial_connect_string_test.c6
-rw-r--r--test/core/compression/message_compress_test.c15
-rw-r--r--test/core/end2end/tests/cancel_with_status.c2
-rw-r--r--test/core/end2end/tests/negative_deadline.c2
-rw-r--r--test/core/iomgr/endpoint_tests.c47
-rw-r--r--test/core/iomgr/fd_posix_test.c2
-rw-r--r--test/core/iomgr/tcp_posix_test.c26
-rw-r--r--test/core/support/slice_test.c4
-rw-r--r--test/core/support/string_test.c35
-rw-r--r--test/core/surface/completion_queue_test.c4
-rw-r--r--test/core/transport/chttp2/bin_decoder_test.c144
-rw-r--r--test/core/transport/chttp2/bin_encoder_test.c3
-rw-r--r--test/core/transport/metadata_test.c5
-rw-r--r--test/cpp/end2end/async_end2end_test.cc7
-rw-r--r--test/cpp/end2end/proto_server_reflection_test.cc166
-rw-r--r--test/cpp/end2end/zookeeper_test.cc2
-rw-r--r--test/cpp/interop/client.cc5
-rw-r--r--test/cpp/interop/interop_client.cc10
-rw-r--r--test/cpp/interop/metrics_client.cc2
-rw-r--r--test/cpp/qps/driver.cc8
-rw-r--r--test/cpp/qps/parse_json.cc2
-rw-r--r--test/cpp/util/proto_reflection_descriptor_database.cc316
-rw-r--r--test/cpp/util/proto_reflection_descriptor_database.h131
-rwxr-xr-xtest/distrib/cpp/run_distrib_test.sh52
25 files changed, 952 insertions, 57 deletions
diff --git a/test/core/client_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c
index 1534360dea..3160312db6 100644
--- a/test/core/client_config/lb_policies_test.c
+++ b/test/core/client_config/lb_policies_test.c
@@ -135,7 +135,7 @@ static void drain_cq(grpc_completion_queue *cq) {
}
static void kill_server(const servers_fixture *f, size_t i) {
- gpr_log(GPR_INFO, "KILLING SERVER %d", i);
+ gpr_log(GPR_INFO, "KILLING SERVER %" PRIuPTR, i);
GPR_ASSERT(f->servers[i] != NULL);
grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000));
GPR_ASSERT(
@@ -157,7 +157,7 @@ typedef struct request_data {
static void revive_server(const servers_fixture *f, request_data *rdata,
size_t i) {
int got_port;
- gpr_log(GPR_INFO, "RAISE AGAIN SERVER %d", i);
+ gpr_log(GPR_INFO, "RAISE AGAIN SERVER %" PRIuPTR, i);
GPR_ASSERT(f->servers[i] == NULL);
gpr_log(GPR_DEBUG, "revive: %s", f->servers_hostports[i]);
@@ -311,7 +311,7 @@ static int *perform_request(servers_fixture *f, grpc_channel *client,
.type != GRPC_QUEUE_TIMEOUT) {
GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
read_tag = ((int)(intptr_t)ev.tag);
- gpr_log(GPR_DEBUG, "EVENT: success:%d, type:%d, tag:%d iter:%d",
+ gpr_log(GPR_DEBUG, "EVENT: success:%d, type:%d, tag:%d iter:%" PRIuPTR,
ev.success, ev.type, read_tag, iter_num);
if (ev.success && read_tag >= 1000) {
GPR_ASSERT(s_idx == -1); /* only one server must reply */
@@ -643,7 +643,8 @@ static void print_failed_expectations(const int *expected_connection_sequence,
const size_t num_iters) {
size_t i;
for (i = 0; i < num_iters; i++) {
- gpr_log(GPR_ERROR, "FAILURE: Iter (expected, actual): %d (%d, %d)", i,
+ gpr_log(GPR_ERROR,
+ "FAILURE: Iter (expected, actual): %" PRIuPTR " (%d, %d)", i,
expected_connection_sequence[i % expected_seq_length],
actual_connection_sequence[i]);
}
@@ -726,8 +727,8 @@ static void verify_total_carnage_round_robin(
const int actual = actual_connection_sequence[i];
const int expected = -1;
if (actual != expected) {
- gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d", expected,
- actual, i);
+ gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %" PRIuPTR,
+ expected, actual, i);
abort();
}
}
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 0a0da92ce2..1b51424f7e 100644
--- a/test/core/client_config/set_initial_connect_string_test.c
+++ b/test/core/client_config/set_initial_connect_string_test.c
@@ -69,7 +69,7 @@ static void handle_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
GPR_ASSERT(error == GRPC_ERROR_NONE);
gpr_slice_buffer_move_into(&state.temp_incoming_buffer,
&state.incoming_buffer);
- gpr_log(GPR_DEBUG, "got %d bytes, magic is %d bytes",
+ gpr_log(GPR_DEBUG, "got %" PRIuPTR " bytes, magic is %" PRIuPTR " bytes",
state.incoming_buffer.length, strlen(magic_connect_string));
if (state.incoming_buffer.length > strlen(magic_connect_string)) {
gpr_atm_rel_store(&state.done_atm, 1);
@@ -173,8 +173,8 @@ static void actually_poll_server(void *arg) {
bool done = gpr_atm_acq_load(&state.done_atm) != 0;
gpr_timespec time_left =
gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME));
- gpr_log(GPR_DEBUG, "done=%d, time_left=%d.%09d", done, time_left.tv_sec,
- time_left.tv_nsec);
+ gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09" PRId32, done,
+ time_left.tv_sec, time_left.tv_nsec);
if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) {
break;
}
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index 1a93903346..47ecf72e08 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -66,13 +66,14 @@ static void assert_passthrough(gpr_slice value,
char *algorithm_name;
GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algorithm_name) != 0);
- gpr_log(GPR_INFO,
- "assert_passthrough: value_length=%d value_hash=0x%08x "
- "algorithm='%s' uncompressed_split='%s' compressed_split='%s'",
- GPR_SLICE_LENGTH(value), gpr_murmur_hash3(GPR_SLICE_START_PTR(value),
- GPR_SLICE_LENGTH(value), 0),
- algorithm_name, grpc_slice_split_mode_name(uncompressed_split_mode),
- grpc_slice_split_mode_name(compressed_split_mode));
+ gpr_log(
+ GPR_INFO, "assert_passthrough: value_length=%" PRIuPTR
+ " value_hash=0x%08x "
+ "algorithm='%s' uncompressed_split='%s' compressed_split='%s'",
+ GPR_SLICE_LENGTH(value),
+ gpr_murmur_hash3(GPR_SLICE_START_PTR(value), GPR_SLICE_LENGTH(value), 0),
+ algorithm_name, grpc_slice_split_mode_name(uncompressed_split_mode),
+ grpc_slice_split_mode_name(compressed_split_mode));
gpr_slice_buffer_init(&input);
gpr_slice_buffer_init(&compressed_raw);
diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c
index 83629a9a02..673c7051ad 100644
--- a/test/core/end2end/tests/cancel_with_status.c
+++ b/test/core/end2end/tests/cancel_with_status.c
@@ -112,7 +112,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, size_t num_ops) {
char *details = NULL;
size_t details_capacity = 0;
- gpr_log(GPR_DEBUG, "test with %d ops", num_ops);
+ gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
"/foo", "foo.test.google.fr:1234", deadline,
diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c
index fd56c8b4ff..dff7992f63 100644
--- a/test/core/end2end/tests/negative_deadline.c
+++ b/test/core/end2end/tests/negative_deadline.c
@@ -112,7 +112,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, size_t num_ops) {
char *details = NULL;
size_t details_capacity = 0;
- gpr_log(GPR_DEBUG, "test with %d ops", num_ops);
+ gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
"/foo", "foo.test.google.fr:1234", deadline,
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 55e79189cb..40807242db 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -189,13 +189,15 @@ static void read_and_write_test(grpc_endpoint_test_config config,
grpc_endpoint_test_fixture f =
begin_test(config, "read_and_write_test", slice_size);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- gpr_log(GPR_DEBUG, "num_bytes=%d write_size=%d slice_size=%d shutdown=%d",
+ gpr_log(GPR_DEBUG, "num_bytes=%" PRIuPTR " write_size=%" PRIuPTR
+ " slice_size=%" PRIuPTR " shutdown=%d",
num_bytes, write_size, slice_size, shutdown);
if (shutdown) {
gpr_log(GPR_INFO, "Start read and write shutdown test");
} else {
- gpr_log(GPR_INFO, "Start read and write test with %d bytes, slice size %d",
+ gpr_log(GPR_INFO, "Start read and write test with %" PRIuPTR
+ " bytes, slice size %" PRIuPTR,
num_bytes, slice_size);
}
@@ -254,11 +256,52 @@ static void read_and_write_test(grpc_endpoint_test_config config,
grpc_exec_ctx_finish(&exec_ctx);
}
+static void inc_on_failure(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ *(int *)arg += (error != GRPC_ERROR_NONE);
+}
+
+static void multiple_shutdown_test(grpc_endpoint_test_config config) {
+ grpc_endpoint_test_fixture f =
+ begin_test(config, "multiple_shutdown_test", 128);
+ int fail_count = 0;
+
+ gpr_slice_buffer slice_buffer;
+ gpr_slice_buffer_init(&slice_buffer);
+
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_endpoint_read(&exec_ctx, f.client_ep, &slice_buffer,
+ grpc_closure_create(inc_on_failure, &fail_count));
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(fail_count == 0);
+ grpc_endpoint_shutdown(&exec_ctx, f.client_ep);
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(fail_count == 1);
+ grpc_endpoint_read(&exec_ctx, f.client_ep, &slice_buffer,
+ grpc_closure_create(inc_on_failure, &fail_count));
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(fail_count == 2);
+ grpc_endpoint_write(&exec_ctx, f.client_ep, &slice_buffer,
+ grpc_closure_create(inc_on_failure, &fail_count));
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(fail_count == 3);
+ grpc_endpoint_shutdown(&exec_ctx, f.client_ep);
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(fail_count == 3);
+
+ gpr_slice_buffer_destroy(&slice_buffer);
+
+ grpc_endpoint_destroy(&exec_ctx, f.client_ep);
+ grpc_endpoint_destroy(&exec_ctx, f.server_ep);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
void grpc_endpoint_tests(grpc_endpoint_test_config config,
grpc_pollset *pollset, gpr_mu *mu) {
size_t i;
g_pollset = pollset;
g_mu = mu;
+ multiple_shutdown_test(config);
read_and_write_test(config, 10000000, 100000, 8192, false);
read_and_write_test(config, 1000000, 100000, 1, false);
read_and_write_test(config, 100000000, 100000, 1, true);
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 7bb80f3050..62dc24d85a 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -404,7 +404,7 @@ static void test_grpc_fd(void) {
client_wait_and_shutdown(&cl);
server_wait_and_shutdown(&sv);
GPR_ASSERT(sv.read_bytes_total == cl.write_bytes_total);
- gpr_log(GPR_INFO, "Total read bytes %d", sv.read_bytes_total);
+ gpr_log(GPR_INFO, "Total read bytes %" PRIdPTR, sv.read_bytes_total);
}
typedef struct fd_change_data {
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 0a351f7422..42614567ca 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -152,7 +152,7 @@ static void read_cb(grpc_exec_ctx *exec_ctx, void *user_data,
read_bytes = count_slices(state->incoming.slices, state->incoming.count,
&current_data);
state->read_bytes += read_bytes;
- gpr_log(GPR_INFO, "Read %d bytes of %d", read_bytes,
+ gpr_log(GPR_INFO, "Read %" PRIuPTR " bytes of %" PRIuPTR, read_bytes,
state->target_read_bytes);
if (state->read_bytes >= state->target_read_bytes) {
gpr_mu_unlock(g_mu);
@@ -171,8 +171,8 @@ static void read_test(size_t num_bytes, size_t slice_size) {
gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- gpr_log(GPR_INFO, "Read test of size %d, slice size %d", num_bytes,
- slice_size);
+ gpr_log(GPR_INFO, "Read test of size %" PRIuPTR ", slice size %" PRIuPTR,
+ num_bytes, slice_size);
create_sockets(sv);
@@ -180,7 +180,7 @@ static void read_test(size_t num_bytes, size_t slice_size) {
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);
+ gpr_log(GPR_INFO, "Wrote %" PRIuPTR " bytes", written_bytes);
state.ep = ep;
state.read_bytes = 0;
@@ -219,7 +219,7 @@ static void large_read_test(size_t slice_size) {
gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- gpr_log(GPR_INFO, "Start large read test, slice size %d", slice_size);
+ gpr_log(GPR_INFO, "Start large read test, slice size %" PRIuPTR, slice_size);
create_sockets(sv);
@@ -228,7 +228,7 @@ static void large_read_test(size_t slice_size) {
grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
written_bytes = fill_socket(sv[0]);
- gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
+ gpr_log(GPR_INFO, "Wrote %" PRIuPTR " bytes", written_bytes);
state.ep = ep;
state.read_bytes = 0;
@@ -353,8 +353,9 @@ static void write_test(size_t num_bytes, size_t slice_size) {
gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- gpr_log(GPR_INFO, "Start write test with %d bytes, slice size %d", num_bytes,
- slice_size);
+ gpr_log(GPR_INFO,
+ "Start write test with %" PRIuPTR " bytes, slice size %" PRIuPTR,
+ num_bytes, slice_size);
create_sockets(sv);
@@ -416,8 +417,9 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
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);
+ gpr_log(GPR_INFO,
+ "Release fd read_test of size %" PRIuPTR ", slice size %" PRIuPTR,
+ num_bytes, slice_size);
create_sockets(sv);
@@ -426,7 +428,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
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);
+ gpr_log(GPR_INFO, "Wrote %" PRIuPTR " bytes", written_bytes);
state.ep = ep;
state.read_bytes = 0;
@@ -532,8 +534,8 @@ int main(int argc, char **argv) {
grpc_init();
g_pollset = gpr_malloc(grpc_pollset_size());
grpc_pollset_init(g_pollset, &g_mu);
- run_tests();
grpc_endpoint_tests(configs[0], g_pollset, g_mu);
+ run_tests();
grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/support/slice_test.c b/test/core/support/slice_test.c
index 2df38376a9..0da483a321 100644
--- a/test/core/support/slice_test.c
+++ b/test/core/support/slice_test.c
@@ -164,7 +164,7 @@ static void test_slice_split_head_works(size_t length) {
size_t i;
LOG_TEST_NAME("test_slice_split_head_works");
- gpr_log(GPR_INFO, "length=%d", length);
+ gpr_log(GPR_INFO, "length=%" PRIuPTR, length);
/* Create a slice in which each byte is equal to the distance from it to the
beginning of the slice. */
@@ -192,7 +192,7 @@ static void test_slice_split_tail_works(size_t length) {
size_t i;
LOG_TEST_NAME("test_slice_split_tail_works");
- gpr_log(GPR_INFO, "length=%d", length);
+ gpr_log(GPR_INFO, "length=%" PRIuPTR, length);
/* Create a slice in which each byte is equal to the distance from it to the
beginning of the slice. */
diff --git a/test/core/support/string_test.c b/test/core/support/string_test.c
index d5f8107f21..553a824b3f 100644
--- a/test/core/support/string_test.c
+++ b/test/core/support/string_test.c
@@ -156,7 +156,7 @@ static void test_asprintf(void) {
LOG_TEST_NAME("test_asprintf");
/* Print an empty string. */
- GPR_ASSERT(gpr_asprintf(&buf, "") == 0);
+ GPR_ASSERT(gpr_asprintf(&buf, "%s", "") == 0);
GPR_ASSERT(buf[0] == '\0');
gpr_free(buf);
@@ -334,6 +334,38 @@ static void test_int64toa() {
GPR_ASSERT(0 == strcmp("-9223372036854775808", buf));
}
+static void test_leftpad() {
+ char *padded;
+
+ padded = gpr_leftpad("foo", ' ', 5);
+ GPR_ASSERT(0 == strcmp(" foo", padded));
+ gpr_free(padded);
+
+ padded = gpr_leftpad("foo", ' ', 4);
+ GPR_ASSERT(0 == strcmp(" foo", padded));
+ gpr_free(padded);
+
+ padded = gpr_leftpad("foo", ' ', 3);
+ GPR_ASSERT(0 == strcmp("foo", padded));
+ gpr_free(padded);
+
+ padded = gpr_leftpad("foo", ' ', 2);
+ GPR_ASSERT(0 == strcmp("foo", padded));
+ gpr_free(padded);
+
+ padded = gpr_leftpad("foo", ' ', 1);
+ GPR_ASSERT(0 == strcmp("foo", padded));
+ gpr_free(padded);
+
+ padded = gpr_leftpad("foo", ' ', 0);
+ GPR_ASSERT(0 == strcmp("foo", padded));
+ gpr_free(padded);
+
+ padded = gpr_leftpad("foo", '0', 5);
+ GPR_ASSERT(0 == strcmp("00foo", padded));
+ gpr_free(padded);
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_strdup();
@@ -346,5 +378,6 @@ int main(int argc, char **argv) {
test_strsplit();
test_ltoa();
test_int64toa();
+ test_leftpad();
return 0;
}
diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c
index ab74c65b9e..1486d2508f 100644
--- a/test/core/surface/completion_queue_test.c
+++ b/test/core/surface/completion_queue_test.c
@@ -349,8 +349,8 @@ static void test_threading(size_t producers, size_t consumers) {
size_t total_consumed = 0;
static int optid = 101;
- gpr_log(GPR_INFO, "%s: %d producers, %d consumers", "test_threading",
- producers, consumers);
+ gpr_log(GPR_INFO, "%s: %" PRIuPTR " producers, %" PRIuPTR " consumers",
+ "test_threading", producers, consumers);
/* start all threads: they will wait for phase1 */
for (i = 0; i < producers + consumers; i++) {
diff --git a/test/core/transport/chttp2/bin_decoder_test.c b/test/core/transport/chttp2/bin_decoder_test.c
new file mode 100644
index 0000000000..c4e6cd332f
--- /dev/null
+++ b/test/core/transport/chttp2/bin_decoder_test.c
@@ -0,0 +1,144 @@
+/*
+ *
+ * Copyright 2016, 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/ext/transport/chttp2/transport/bin_decoder.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
+#include "src/core/lib/support/string.h"
+
+static int all_ok = 1;
+
+static void expect_slice_eq(gpr_slice expected, gpr_slice slice, char *debug,
+ int line) {
+ if (0 != gpr_slice_cmp(slice, expected)) {
+ char *hs = gpr_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ char *he = gpr_dump_slice(expected, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_ERROR, "FAILED:%d: %s\ngot: %s\nwant: %s", line, debug, hs,
+ he);
+ gpr_free(hs);
+ gpr_free(he);
+ all_ok = 0;
+ }
+ gpr_slice_unref(expected);
+ gpr_slice_unref(slice);
+}
+
+static gpr_slice base64_encode(const char *s) {
+ gpr_slice ss = gpr_slice_from_copied_string(s);
+ gpr_slice out = grpc_chttp2_base64_encode(ss);
+ gpr_slice_unref(ss);
+ return out;
+}
+
+static gpr_slice base64_decode(const char *s) {
+ gpr_slice ss = gpr_slice_from_copied_string(s);
+ gpr_slice out = grpc_chttp2_base64_decode(ss);
+ gpr_slice_unref(ss);
+ return out;
+}
+
+static gpr_slice base64_decode_with_length(const char *s,
+ size_t output_length) {
+ gpr_slice ss = gpr_slice_from_copied_string(s);
+ gpr_slice out = grpc_chttp2_base64_decode_with_length(ss, output_length);
+ gpr_slice_unref(ss);
+ return out;
+}
+
+#define EXPECT_SLICE_EQ(expected, slice) \
+ expect_slice_eq( \
+ gpr_slice_from_copied_buffer(expected, sizeof(expected) - 1), slice, \
+ #slice, __LINE__);
+
+#define ENCODE_AND_DECODE(s) \
+ EXPECT_SLICE_EQ( \
+ s, grpc_chttp2_base64_decode_with_length(base64_encode(s), strlen(s)));
+
+int main(int argc, char **argv) {
+ /* ENCODE_AND_DECODE tests grpc_chttp2_base64_decode_with_length(), which
+ takes encoded base64 strings without pad chars, but output length is
+ required. */
+ /* Base64 test vectors from RFC 4648 */
+ ENCODE_AND_DECODE("");
+ ENCODE_AND_DECODE("f");
+ ENCODE_AND_DECODE("foo");
+ ENCODE_AND_DECODE("fo");
+ ENCODE_AND_DECODE("foob");
+ ENCODE_AND_DECODE("fooba");
+ ENCODE_AND_DECODE("foobar");
+
+ ENCODE_AND_DECODE("\xc0\xc1\xc2\xc3\xc4\xc5");
+
+ /* Base64 test vectors from RFC 4648, with pad chars */
+ /* BASE64("") = "" */
+ EXPECT_SLICE_EQ("", base64_decode(""));
+ /* BASE64("f") = "Zg==" */
+ EXPECT_SLICE_EQ("f", base64_decode("Zg=="));
+ /* BASE64("fo") = "Zm8=" */
+ EXPECT_SLICE_EQ("fo", base64_decode("Zm8="));
+ /* BASE64("foo") = "Zm9v" */
+ EXPECT_SLICE_EQ("foo", base64_decode("Zm9v"));
+ /* BASE64("foob") = "Zm9vYg==" */
+ EXPECT_SLICE_EQ("foob", base64_decode("Zm9vYg=="));
+ /* BASE64("fooba") = "Zm9vYmE=" */
+ EXPECT_SLICE_EQ("fooba", base64_decode("Zm9vYmE="));
+ /* BASE64("foobar") = "Zm9vYmFy" */
+ EXPECT_SLICE_EQ("foobar", base64_decode("Zm9vYmFy"));
+
+ EXPECT_SLICE_EQ("\xc0\xc1\xc2\xc3\xc4\xc5", base64_decode("wMHCw8TF"));
+
+ // Test illegal input length in grpc_chttp2_base64_decode
+ EXPECT_SLICE_EQ("", base64_decode("a"));
+ EXPECT_SLICE_EQ("", base64_decode("ab"));
+ EXPECT_SLICE_EQ("", base64_decode("abc"));
+
+ // Test illegal charactors in grpc_chttp2_base64_decode
+ EXPECT_SLICE_EQ("", base64_decode("Zm:v"));
+ EXPECT_SLICE_EQ("", base64_decode("Zm=v"));
+
+ // Test output_length longer than max possible output length in
+ // grpc_chttp2_base64_decode_with_length
+ EXPECT_SLICE_EQ("", base64_decode_with_length("Zg", 2));
+ EXPECT_SLICE_EQ("", base64_decode_with_length("Zm8", 3));
+ EXPECT_SLICE_EQ("", base64_decode_with_length("Zm9v", 4));
+
+ // Test illegal charactors in grpc_chttp2_base64_decode_with_length
+ EXPECT_SLICE_EQ("", base64_decode_with_length("Zm:v", 3));
+ EXPECT_SLICE_EQ("", base64_decode_with_length("Zm=v", 3));
+
+ return all_ok ? 0 : 1;
+}
diff --git a/test/core/transport/chttp2/bin_encoder_test.c b/test/core/transport/chttp2/bin_encoder_test.c
index 095861e974..08d10735a5 100644
--- a/test/core/transport/chttp2/bin_encoder_test.c
+++ b/test/core/transport/chttp2/bin_encoder_test.c
@@ -88,7 +88,8 @@ static void expect_combined_equiv(const char *s, size_t len, int line) {
char *t = gpr_dump_slice(input, GPR_DUMP_HEX | GPR_DUMP_ASCII);
char *e = gpr_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII);
char *g = gpr_dump_slice(got, GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_ERROR, "FAILED:%d:\ntest: %s\ngot: %s\nwant: %s", t, g, e);
+ gpr_log(GPR_ERROR, "FAILED:%d:\ntest: %s\ngot: %s\nwant: %s", line, t, g,
+ e);
gpr_free(t);
gpr_free(e);
gpr_free(g);
diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c
index a4e9694a93..007892930c 100644
--- a/test/core/transport/metadata_test.c
+++ b/test/core/transport/metadata_test.c
@@ -166,7 +166,7 @@ static void test_things_stick_around(void) {
grpc_init();
for (i = 0; i < nstrs; i++) {
- gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", i);
+ gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%" PRIuPTR "x", i);
strs[i] = grpc_mdstr_from_string(buffer);
shuf[i] = i;
gpr_free(buffer);
@@ -188,7 +188,8 @@ static void test_things_stick_around(void) {
for (i = 0; i < nstrs; i++) {
GRPC_MDSTR_UNREF(strs[shuf[i]]);
for (j = i + 1; j < nstrs; j++) {
- gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", shuf[j]);
+ gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%" PRIuPTR "x",
+ shuf[j]);
test = grpc_mdstr_from_string(buffer);
GPR_ASSERT(test == strs[shuf[j]]);
GRPC_MDSTR_UNREF(test);
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index b839801500..8229bda6bf 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -229,9 +229,10 @@ class TestScenario {
credentials_type(creds_type),
message_content(content) {}
void Log() const {
- gpr_log(GPR_INFO,
- "Scenario: disable_blocking %d, credentials %s, message size %d",
- disable_blocking, credentials_type.c_str(), message_content.size());
+ gpr_log(
+ GPR_INFO,
+ "Scenario: disable_blocking %d, credentials %s, message size %" PRIuPTR,
+ disable_blocking, credentials_type.c_str(), message_content.size());
}
bool disable_blocking;
const grpc::string credentials_type;
diff --git a/test/cpp/end2end/proto_server_reflection_test.cc b/test/cpp/end2end/proto_server_reflection_test.cc
new file mode 100644
index 0000000000..f8fc39b553
--- /dev/null
+++ b/test/cpp/end2end/proto_server_reflection_test.cc
@@ -0,0 +1,166 @@
+/*
+ *
+ * Copyright 2016, 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 <google/protobuf/descriptor.h>
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/ext/proto_server_reflection_plugin.h>
+#include <grpc++/security/credentials.h>
+#include <grpc++/security/server_credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc/grpc.h>
+#include <gtest/gtest.h>
+
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "test/cpp/end2end/test_service_impl.h"
+#include "test/cpp/util/proto_reflection_descriptor_database.h"
+
+namespace grpc {
+namespace testing {
+
+class ProtoServerReflectionTest : public ::testing::Test {
+ public:
+ ProtoServerReflectionTest() {}
+
+ void SetUp() GRPC_OVERRIDE {
+ port_ = grpc_pick_unused_port_or_die();
+ ref_desc_pool_ = google::protobuf::DescriptorPool::generated_pool();
+
+ ServerBuilder builder;
+ grpc::string server_address = "localhost:" + to_string(port_);
+ builder.AddListeningPort(server_address, InsecureServerCredentials());
+ server_ = builder.BuildAndStart();
+ }
+
+ void ResetStub() {
+ string target = "dns:localhost:" + to_string(port_);
+ std::shared_ptr<Channel> channel =
+ CreateChannel(target, InsecureChannelCredentials());
+ stub_ = grpc::testing::EchoTestService::NewStub(channel);
+ desc_db_.reset(new ProtoReflectionDescriptorDatabase(channel));
+ desc_pool_.reset(new google::protobuf::DescriptorPool(desc_db_.get()));
+ }
+
+ string to_string(const int number) {
+ std::stringstream strs;
+ strs << number;
+ return strs.str();
+ }
+
+ void CompareService(const grpc::string& service) {
+ const google::protobuf::ServiceDescriptor* service_desc =
+ desc_pool_->FindServiceByName(service);
+ const google::protobuf::ServiceDescriptor* ref_service_desc =
+ ref_desc_pool_->FindServiceByName(service);
+ EXPECT_TRUE(service_desc != nullptr);
+ EXPECT_TRUE(ref_service_desc != nullptr);
+ EXPECT_EQ(service_desc->DebugString(), ref_service_desc->DebugString());
+
+ const google::protobuf::FileDescriptor* file_desc = service_desc->file();
+ if (known_files_.find(file_desc->package() + "/" + file_desc->name()) !=
+ known_files_.end()) {
+ EXPECT_EQ(file_desc->DebugString(),
+ ref_service_desc->file()->DebugString());
+ known_files_.insert(file_desc->package() + "/" + file_desc->name());
+ }
+
+ for (int i = 0; i < service_desc->method_count(); ++i) {
+ CompareMethod(service_desc->method(i)->full_name());
+ }
+ }
+
+ void CompareMethod(const grpc::string& method) {
+ const google::protobuf::MethodDescriptor* method_desc =
+ desc_pool_->FindMethodByName(method);
+ const google::protobuf::MethodDescriptor* ref_method_desc =
+ ref_desc_pool_->FindMethodByName(method);
+ EXPECT_TRUE(method_desc != nullptr);
+ EXPECT_TRUE(ref_method_desc != nullptr);
+ EXPECT_EQ(method_desc->DebugString(), ref_method_desc->DebugString());
+
+ CompareType(method_desc->input_type()->full_name());
+ CompareType(method_desc->output_type()->full_name());
+ }
+
+ void CompareType(const grpc::string& type) {
+ if (known_types_.find(type) != known_types_.end()) {
+ return;
+ }
+
+ const google::protobuf::Descriptor* desc =
+ desc_pool_->FindMessageTypeByName(type);
+ const google::protobuf::Descriptor* ref_desc =
+ ref_desc_pool_->FindMessageTypeByName(type);
+ EXPECT_TRUE(desc != nullptr);
+ EXPECT_TRUE(ref_desc != nullptr);
+ EXPECT_EQ(desc->DebugString(), ref_desc->DebugString());
+ }
+
+ protected:
+ std::unique_ptr<Server> server_;
+ std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
+ std::unique_ptr<ProtoReflectionDescriptorDatabase> desc_db_;
+ std::unique_ptr<google::protobuf::DescriptorPool> desc_pool_;
+ std::unordered_set<string> known_files_;
+ std::unordered_set<string> known_types_;
+ const google::protobuf::DescriptorPool* ref_desc_pool_;
+ int port_;
+ reflection::ProtoServerReflectionPlugin plugin_;
+};
+
+TEST_F(ProtoServerReflectionTest, CheckResponseWithLocalDescriptorPool) {
+ ResetStub();
+
+ std::vector<std::string> services;
+ desc_db_->GetServices(&services);
+ // The service list has at least one service (reflection servcie).
+ EXPECT_TRUE(services.size() > 0);
+
+ for (auto it = services.begin(); it != services.end(); ++it) {
+ CompareService(*it);
+ }
+}
+
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/end2end/zookeeper_test.cc b/test/cpp/end2end/zookeeper_test.cc
index 12853a1b98..fdc500e535 100644
--- a/test/cpp/end2end/zookeeper_test.cc
+++ b/test/cpp/end2end/zookeeper_test.cc
@@ -101,7 +101,7 @@ class ZookeeperTest : public ::testing::Test {
zookeeper_address_ = addr_str;
gpr_free(addr);
}
- gpr_log(GPR_DEBUG, zookeeper_address_.c_str());
+ gpr_log(GPR_DEBUG, "%s", zookeeper_address_.c_str());
// Connects to zookeeper server
zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 7727824979..addaf174f2 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -171,8 +171,9 @@ int main(int argc, char** argv) {
"large_unary|large_compressed_unary|client_streaming|server_streaming|"
"server_compressed_streaming|half_duplex|ping_pong|cancel_after_begin|"
"cancel_after_first_response|timeout_on_sleeping_server|empty_stream|"
- "compute_engine_creds|jwt_token_creds|oauth2_auth_token|per_rpc_creds",
- "status_code_and_message|custom_metadata", FLAGS_test_case.c_str());
+ "compute_engine_creds|jwt_token_creds|oauth2_auth_token|per_rpc_creds|"
+ "status_code_and_message|custom_metadata",
+ FLAGS_test_case.c_str());
ret = 1;
}
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index a0479e8f68..0bf1fd6f73 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -433,7 +433,7 @@ bool InteropClient::DoResponseStreaming() {
// most likely due to connection failure.
gpr_log(GPR_ERROR,
"DoResponseStreaming(): Read fewer streams (%d) than "
- "response_stream_sizes.size() (%d)",
+ "response_stream_sizes.size() (%" PRIuPTR ")",
i, response_stream_sizes.size());
return TransientFailureOrAbort();
}
@@ -517,9 +517,11 @@ bool InteropClient::DoResponseCompressedStreaming() {
// stream->Read() failed before reading all the expected messages. This
// is most likely due to a connection failure.
gpr_log(GPR_ERROR,
- "DoResponseCompressedStreaming(): Responses read (k=%d) is "
+ "DoResponseCompressedStreaming(): Responses read (k=%" PRIuPTR
+ ") is "
"less than the expected messages (i.e "
- "response_stream_sizes.size() (%d)). (i=%d, j=%d)",
+ "response_stream_sizes.size() (%" PRIuPTR ")). (i=%" PRIuPTR
+ ", j=%" PRIuPTR ")",
k, response_stream_sizes.size(), i, j);
return TransientFailureOrAbort();
}
@@ -608,7 +610,7 @@ bool InteropClient::DoHalfDuplex() {
// most likely due to a connection failure
gpr_log(GPR_ERROR,
"DoHalfDuplex(): Responses read (i=%d) are less than the expected "
- "number of messages response_stream_sizes.size() (%d)",
+ "number of messages response_stream_sizes.size() (%" PRIuPTR ")",
i, response_stream_sizes.size());
return TransientFailureOrAbort();
}
diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc
index c8c2215fab..7a0cb994df 100644
--- a/test/cpp/interop/metrics_client.cc
+++ b/test/cpp/interop/metrics_client.cc
@@ -76,7 +76,7 @@ bool PrintMetrics(std::unique_ptr<MetricsService::Stub> stub, bool total_only,
while (reader->Read(&gauge_response)) {
if (gauge_response.value_case() == GaugeResponse::kLongValue) {
if (!total_only) {
- gpr_log(GPR_INFO, "%s: %ld", gauge_response.name().c_str(),
+ gpr_log(GPR_INFO, "%s: %lld", gauge_response.name().c_str(),
gauge_response.long_value());
}
overall_qps += gauge_response.long_value();
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 57d8c22a95..83dbdc3e59 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -244,8 +244,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
// where class contained in std::vector must have a copy constructor
auto* servers = new ServerData[num_servers];
for (size_t i = 0; i < num_servers; i++) {
- gpr_log(GPR_INFO, "Starting server on %s (worker #%d)", workers[i].c_str(),
- i);
+ gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")",
+ workers[i].c_str(), i);
servers[i].stub = WorkerService::NewStub(
CreateChannel(workers[i], InsecureChannelCredentials()));
@@ -307,8 +307,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
auto* clients = new ClientData[num_clients];
for (size_t i = 0; i < num_clients; i++) {
const auto& worker = workers[i + num_servers];
- gpr_log(GPR_INFO, "Starting client on %s (worker #%d)", worker.c_str(),
- i + num_servers);
+ gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")",
+ worker.c_str(), i + num_servers);
clients[i].stub = WorkerService::NewStub(
CreateChannel(worker, InsecureChannelCredentials()));
ClientConfig per_client_config = client_config;
diff --git a/test/cpp/qps/parse_json.cc b/test/cpp/qps/parse_json.cc
index be804281f8..e4fc35fa41 100644
--- a/test/cpp/qps/parse_json.cc
+++ b/test/cpp/qps/parse_json.cc
@@ -55,7 +55,7 @@ void ParseJson(const grpc::string& json, const grpc::string& type,
grpc::string errmsg(status.error_message());
gpr_log(GPR_ERROR, "Failed to convert json to binary: errcode=%d msg=%s",
status.error_code(), errmsg.c_str());
- gpr_log(GPR_ERROR, "JSON: ", json.c_str());
+ gpr_log(GPR_ERROR, "JSON: %s", json.c_str());
abort();
}
GPR_ASSERT(msg->ParseFromString(binary));
diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc
new file mode 100644
index 0000000000..6907d97bd5
--- /dev/null
+++ b/test/cpp/util/proto_reflection_descriptor_database.cc
@@ -0,0 +1,316 @@
+/*
+ *
+ * Copyright 2016, 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/cpp/util/proto_reflection_descriptor_database.h"
+
+#include <vector>
+
+#include <grpc/support/log.h>
+
+using grpc::reflection::v1alpha::ServerReflection;
+using grpc::reflection::v1alpha::ServerReflectionRequest;
+using grpc::reflection::v1alpha::ServerReflectionResponse;
+using grpc::reflection::v1alpha::ListServiceResponse;
+using grpc::reflection::v1alpha::ErrorResponse;
+
+namespace grpc {
+
+ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase(
+ std::unique_ptr<ServerReflection::Stub> stub)
+ : stub_(std::move(stub)) {}
+
+ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase(
+ std::shared_ptr<grpc::Channel> channel)
+ : stub_(ServerReflection::NewStub(channel)) {}
+
+ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() {}
+
+bool ProtoReflectionDescriptorDatabase::FindFileByName(
+ const string& filename, google::protobuf::FileDescriptorProto* output) {
+ if (cached_db_.FindFileByName(filename, output)) {
+ return true;
+ }
+
+ if (known_files_.find(filename) != known_files_.end()) {
+ return false;
+ }
+
+ ServerReflectionRequest request;
+ request.set_file_by_filename(filename);
+ ServerReflectionResponse response;
+
+ DoOneRequest(request, response);
+
+ if (response.message_response_case() ==
+ ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) {
+ AddFileFromResponse(response.file_descriptor_response());
+ } else if (response.message_response_case() ==
+ ServerReflectionResponse::MessageResponseCase::kErrorResponse) {
+ const ErrorResponse error = response.error_response();
+ if (error.error_code() == StatusCode::NOT_FOUND) {
+ gpr_log(GPR_INFO, "NOT_FOUND from server for FindFileByName(%s)",
+ filename.c_str());
+ } else {
+ gpr_log(GPR_INFO,
+ "Error on FindFileByName(%s)\n\tError code: %d\n"
+ "\tError Message: %s",
+ filename.c_str(), error.error_code(),
+ error.error_message().c_str());
+ }
+ } else {
+ gpr_log(
+ GPR_INFO,
+ "Error on FindFileByName(%s) response type\n"
+ "\tExpecting: %d\n\tReceived: %d",
+ filename.c_str(),
+ ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse,
+ response.message_response_case());
+ }
+
+ return cached_db_.FindFileByName(filename, output);
+}
+
+bool ProtoReflectionDescriptorDatabase::FindFileContainingSymbol(
+ const string& symbol_name, google::protobuf::FileDescriptorProto* output) {
+ if (cached_db_.FindFileContainingSymbol(symbol_name, output)) {
+ return true;
+ }
+
+ if (missing_symbols_.find(symbol_name) != missing_symbols_.end()) {
+ return false;
+ }
+
+ ServerReflectionRequest request;
+ request.set_file_containing_symbol(symbol_name);
+ ServerReflectionResponse response;
+
+ DoOneRequest(request, response);
+
+ if (response.message_response_case() ==
+ ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) {
+ AddFileFromResponse(response.file_descriptor_response());
+ } else if (response.message_response_case() ==
+ ServerReflectionResponse::MessageResponseCase::kErrorResponse) {
+ const ErrorResponse error = response.error_response();
+ if (error.error_code() == StatusCode::NOT_FOUND) {
+ missing_symbols_.insert(symbol_name);
+ gpr_log(GPR_INFO,
+ "NOT_FOUND from server for FindFileContainingSymbol(%s)",
+ symbol_name.c_str());
+ } else {
+ gpr_log(GPR_INFO,
+ "Error on FindFileContainingSymbol(%s)\n"
+ "\tError code: %d\n\tError Message: %s",
+ symbol_name.c_str(), error.error_code(),
+ error.error_message().c_str());
+ }
+ } else {
+ gpr_log(
+ GPR_INFO,
+ "Error on FindFileContainingSymbol(%s) response type\n"
+ "\tExpecting: %d\n\tReceived: %d",
+ symbol_name.c_str(),
+ ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse,
+ response.message_response_case());
+ }
+ return cached_db_.FindFileContainingSymbol(symbol_name, output);
+}
+
+bool ProtoReflectionDescriptorDatabase::FindFileContainingExtension(
+ const string& containing_type, int field_number,
+ google::protobuf::FileDescriptorProto* output) {
+ if (cached_db_.FindFileContainingExtension(containing_type, field_number,
+ output)) {
+ return true;
+ }
+
+ if (missing_extensions_.find(containing_type) != missing_extensions_.end() &&
+ missing_extensions_[containing_type].find(field_number) !=
+ missing_extensions_[containing_type].end()) {
+ gpr_log(GPR_INFO, "nested map.");
+ return false;
+ }
+
+ ServerReflectionRequest request;
+ request.mutable_file_containing_extension()->set_containing_type(
+ containing_type);
+ request.mutable_file_containing_extension()->set_extension_number(
+ field_number);
+ ServerReflectionResponse response;
+
+ DoOneRequest(request, response);
+
+ if (response.message_response_case() ==
+ ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) {
+ AddFileFromResponse(response.file_descriptor_response());
+ } else if (response.message_response_case() ==
+ ServerReflectionResponse::MessageResponseCase::kErrorResponse) {
+ const ErrorResponse error = response.error_response();
+ if (error.error_code() == StatusCode::NOT_FOUND) {
+ if (missing_extensions_.find(containing_type) ==
+ missing_extensions_.end()) {
+ missing_extensions_[containing_type] = {};
+ }
+ missing_extensions_[containing_type].insert(field_number);
+ gpr_log(GPR_INFO,
+ "NOT_FOUND from server for FindFileContainingExtension(%s, %d)",
+ containing_type.c_str(), field_number);
+ } else {
+ gpr_log(GPR_INFO,
+ "Error on FindFileContainingExtension(%s, %d)\n"
+ "\tError code: %d\n\tError Message: %s",
+ containing_type.c_str(), field_number, error.error_code(),
+ error.error_message().c_str());
+ }
+ } else {
+ gpr_log(
+ GPR_INFO,
+ "Error on FindFileContainingExtension(%s, %d) response type\n"
+ "\tExpecting: %d\n\tReceived: %d",
+ containing_type.c_str(), field_number,
+ ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse,
+ response.message_response_case());
+ }
+
+ return cached_db_.FindFileContainingExtension(containing_type, field_number,
+ output);
+}
+
+bool ProtoReflectionDescriptorDatabase::FindAllExtensionNumbers(
+ const string& extendee_type, std::vector<int>* output) {
+ if (cached_extension_numbers_.find(extendee_type) !=
+ cached_extension_numbers_.end()) {
+ *output = cached_extension_numbers_[extendee_type];
+ return true;
+ }
+
+ ServerReflectionRequest request;
+ request.set_all_extension_numbers_of_type(extendee_type);
+ ServerReflectionResponse response;
+
+ DoOneRequest(request, response);
+
+ if (response.message_response_case() ==
+ ServerReflectionResponse::MessageResponseCase::
+ kAllExtensionNumbersResponse) {
+ auto number = response.all_extension_numbers_response().extension_number();
+ *output = std::vector<int>(number.begin(), number.end());
+ cached_extension_numbers_[extendee_type] = *output;
+ return true;
+ } else if (response.message_response_case() ==
+ ServerReflectionResponse::MessageResponseCase::kErrorResponse) {
+ const ErrorResponse error = response.error_response();
+ if (error.error_code() == StatusCode::NOT_FOUND) {
+ gpr_log(GPR_INFO, "NOT_FOUND from server for FindAllExtensionNumbers(%s)",
+ extendee_type.c_str());
+ } else {
+ gpr_log(GPR_INFO,
+ "Error on FindAllExtensionNumbersExtension(%s)\n"
+ "\tError code: %d\n\tError Message: %s",
+ extendee_type.c_str(), error.error_code(),
+ error.error_message().c_str());
+ }
+ }
+ return false;
+}
+
+bool ProtoReflectionDescriptorDatabase::GetServices(
+ std::vector<std::string>* output) {
+ ServerReflectionRequest request;
+ request.set_list_services("");
+ ServerReflectionResponse response;
+
+ DoOneRequest(request, response);
+
+ if (response.message_response_case() ==
+ ServerReflectionResponse::MessageResponseCase::kListServicesResponse) {
+ const ListServiceResponse ls_response = response.list_services_response();
+ for (int i = 0; i < ls_response.service_size(); ++i) {
+ (*output).push_back(ls_response.service(i).name());
+ }
+ return true;
+ } else if (response.message_response_case() ==
+ ServerReflectionResponse::MessageResponseCase::kErrorResponse) {
+ const ErrorResponse error = response.error_response();
+ gpr_log(GPR_INFO,
+ "Error on GetServices()\n\tError code: %d\n"
+ "\tError Message: %s",
+ error.error_code(), error.error_message().c_str());
+ } else {
+ gpr_log(
+ GPR_INFO,
+ "Error on GetServices() response type\n\tExpecting: %d\n\tReceived: %d",
+ ServerReflectionResponse::MessageResponseCase::kListServicesResponse,
+ response.message_response_case());
+ }
+ return false;
+}
+
+const google::protobuf::FileDescriptorProto
+ProtoReflectionDescriptorDatabase::ParseFileDescriptorProtoResponse(
+ const std::string& byte_fd_proto) {
+ google::protobuf::FileDescriptorProto file_desc_proto;
+ file_desc_proto.ParseFromString(byte_fd_proto);
+ return file_desc_proto;
+}
+
+void ProtoReflectionDescriptorDatabase::AddFileFromResponse(
+ const grpc::reflection::v1alpha::FileDescriptorResponse& response) {
+ for (int i = 0; i < response.file_descriptor_proto_size(); ++i) {
+ const google::protobuf::FileDescriptorProto file_proto =
+ ParseFileDescriptorProtoResponse(response.file_descriptor_proto(i));
+ if (known_files_.find(file_proto.name()) == known_files_.end()) {
+ known_files_.insert(file_proto.name());
+ cached_db_.Add(file_proto);
+ }
+ }
+}
+
+const std::shared_ptr<ProtoReflectionDescriptorDatabase::ClientStream>
+ProtoReflectionDescriptorDatabase::GetStream() {
+ if (stream_ == nullptr) {
+ stream_ = stub_->ServerReflectionInfo(&ctx_);
+ }
+ return stream_;
+}
+
+void ProtoReflectionDescriptorDatabase::DoOneRequest(
+ const ServerReflectionRequest& request,
+ ServerReflectionResponse& response) {
+ stream_mutex_.lock();
+ GetStream()->Write(request);
+ GetStream()->Read(&response);
+ stream_mutex_.unlock();
+}
+
+} // namespace grpc
diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h
new file mode 100644
index 0000000000..99c00675bb
--- /dev/null
+++ b/test/cpp/util/proto_reflection_descriptor_database.h
@@ -0,0 +1,131 @@
+/*
+ *
+ * Copyright 2016, 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_CPP_PROTO_SERVER_REFLECTION_DATABSE_H
+#define GRPC_TEST_CPP_PROTO_SERVER_REFLECTION_DATABSE_H
+
+#include <mutex>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor_database.h>
+#include <grpc++/ext/reflection.grpc.pb.h>
+#include <grpc++/grpc++.h>
+
+namespace grpc {
+
+// ProtoReflectionDescriptorDatabase takes a stub of ServerReflection and
+// provides the methods defined by DescriptorDatabase interfaces. It can be used
+// to feed a DescriptorPool instance.
+class ProtoReflectionDescriptorDatabase
+ : public google::protobuf::DescriptorDatabase {
+ public:
+ explicit ProtoReflectionDescriptorDatabase(
+ std::unique_ptr<reflection::v1alpha::ServerReflection::Stub> stub);
+
+ explicit ProtoReflectionDescriptorDatabase(
+ std::shared_ptr<grpc::Channel> channel);
+
+ virtual ~ProtoReflectionDescriptorDatabase();
+
+ // The following four methods implement DescriptorDatabase interfaces.
+ //
+ // Find a file by file name. Fills in in *output and returns true if found.
+ // Otherwise, returns false, leaving the contents of *output undefined.
+ bool FindFileByName(const string& filename,
+ google::protobuf::FileDescriptorProto* output)
+ GRPC_OVERRIDE;
+
+ // Find the file that declares the given fully-qualified symbol name.
+ // If found, fills in *output and returns true, otherwise returns false
+ // and leaves *output undefined.
+ bool FindFileContainingSymbol(const string& symbol_name,
+ google::protobuf::FileDescriptorProto* output)
+ GRPC_OVERRIDE;
+
+ // Find the file which defines an extension extending the given message type
+ // with the given field number. If found, fills in *output and returns true,
+ // otherwise returns false and leaves *output undefined. containing_type
+ // must be a fully-qualified type name.
+ bool FindFileContainingExtension(
+ const string& containing_type, int field_number,
+ google::protobuf::FileDescriptorProto* output) GRPC_OVERRIDE;
+
+ // Finds the tag numbers used by all known extensions of
+ // extendee_type, and appends them to output in an undefined
+ // order. This method is best-effort: it's not guaranteed that the
+ // database will find all extensions, and it's not guaranteed that
+ // FindFileContainingExtension will return true on all of the found
+ // numbers. Returns true if the search was successful, otherwise
+ // returns false and leaves output unchanged.
+ bool FindAllExtensionNumbers(const string& extendee_type,
+ std::vector<int>* output) GRPC_OVERRIDE;
+
+ // Provide a list of full names of registered services
+ bool GetServices(std::vector<std::string>* output);
+
+ private:
+ typedef ClientReaderWriter<
+ grpc::reflection::v1alpha::ServerReflectionRequest,
+ grpc::reflection::v1alpha::ServerReflectionResponse>
+ ClientStream;
+
+ const google::protobuf::FileDescriptorProto ParseFileDescriptorProtoResponse(
+ const std::string& byte_fd_proto);
+
+ void AddFileFromResponse(
+ const grpc::reflection::v1alpha::FileDescriptorResponse& response);
+
+ const std::shared_ptr<ClientStream> GetStream();
+
+ void DoOneRequest(
+ const grpc::reflection::v1alpha::ServerReflectionRequest& request,
+ grpc::reflection::v1alpha::ServerReflectionResponse& response);
+
+ std::shared_ptr<ClientStream> stream_;
+ grpc::ClientContext ctx_;
+ std::unique_ptr<grpc::reflection::v1alpha::ServerReflection::Stub> stub_;
+ std::unordered_set<string> known_files_;
+ std::unordered_set<string> missing_symbols_;
+ std::unordered_map<string, std::unordered_set<int>> missing_extensions_;
+ std::unordered_map<string, std::vector<int>> cached_extension_numbers_;
+ std::mutex stream_mutex_;
+
+ google::protobuf::SimpleDescriptorDatabase cached_db_;
+};
+
+} // namespace grpc
+
+#endif // GRPC_TEST_CPP_METRICS_SERVER_H
diff --git a/test/distrib/cpp/run_distrib_test.sh b/test/distrib/cpp/run_distrib_test.sh
new file mode 100755
index 0000000000..bc84b84b8f
--- /dev/null
+++ b/test/distrib/cpp/run_distrib_test.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# Copyright 2016, 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.
+
+set -ex
+
+git clone --recursive $EXTERNAL_GIT_ROOT
+cd grpc
+
+cd third_party/protobuf && ./autogen.sh && \
+./configure && make -j4 && make check && make install && ldconfig
+
+cd ../.. && make -j4 && make install
+
+cd examples/cpp/helloworld
+
+make
+
+make clean
+
+cd ../../../examples/cpp/route_guide
+
+make
+
+make clean
+