From 2f2175c207fab465db52184eb9a9c492026ac471 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Tue, 3 Oct 2017 14:25:08 -0700 Subject: [PATCH 01/35] Counter for number of failed trylocks in cq --- src/core/lib/debug/stats_data.c | 3 +++ src/core/lib/debug/stats_data.h | 4 ++++ src/core/lib/debug/stats_data.yaml | 4 ++++ src/core/lib/debug/stats_data_bq_schema.sql | 3 ++- src/core/lib/surface/completion_queue.c | 4 ++++ tools/run_tests/performance/massage_qps_stats.py | 1 + .../run_tests/performance/scenario_result_schema.json | 10 ++++++++++ 7 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/core/lib/debug/stats_data.c b/src/core/lib/debug/stats_data.c index c0aec63c1d3..41d9e95e294 100644 --- a/src/core/lib/debug/stats_data.c +++ b/src/core/lib/debug/stats_data.c @@ -111,6 +111,7 @@ const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT] = { "executor_push_retries", "server_requested_calls", "server_slowpath_requests_queued", + "cq_failed_queue_trylocks", }; const char *grpc_stats_counter_doc[GRPC_STATS_COUNTER_COUNT] = { "Number of client side calls created by this process", @@ -220,6 +221,8 @@ const char *grpc_stats_counter_doc[GRPC_STATS_COUNTER_COUNT] = { "How many calls were requested (not necessarily received) by the server", "How many times was the server slow path taken (indicates too few " "outstanding requests)", + "Number of lock (trylock) acquisition failures on completion queue event " + "queue. High value here indicates high contention on completion queues", }; const char *grpc_stats_histogram_name[GRPC_STATS_HISTOGRAM_COUNT] = { "call_initial_size", diff --git a/src/core/lib/debug/stats_data.h b/src/core/lib/debug/stats_data.h index 28dab00117b..0a2b323bdfa 100644 --- a/src/core/lib/debug/stats_data.h +++ b/src/core/lib/debug/stats_data.h @@ -113,6 +113,7 @@ typedef enum { GRPC_STATS_COUNTER_EXECUTOR_PUSH_RETRIES, GRPC_STATS_COUNTER_SERVER_REQUESTED_CALLS, GRPC_STATS_COUNTER_SERVER_SLOWPATH_REQUESTS_QUEUED, + GRPC_STATS_COUNTER_CQ_FAILED_QUEUE_TRYLOCKS, GRPC_STATS_COUNTER_COUNT } grpc_stats_counters; extern const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT]; @@ -417,6 +418,9 @@ typedef enum { #define GRPC_STATS_INC_SERVER_SLOWPATH_REQUESTS_QUEUED(exec_ctx) \ GRPC_STATS_INC_COUNTER((exec_ctx), \ GRPC_STATS_COUNTER_SERVER_SLOWPATH_REQUESTS_QUEUED) +#define GRPC_STATS_INC_CQ_FAILED_QUEUE_TRYLOCKS(exec_ctx) \ + GRPC_STATS_INC_COUNTER((exec_ctx), \ + GRPC_STATS_COUNTER_CQ_FAILED_QUEUE_TRYLOCKS) #define GRPC_STATS_INC_CALL_INITIAL_SIZE(exec_ctx, value) \ grpc_stats_inc_call_initial_size((exec_ctx), (int)(value)) void grpc_stats_inc_call_initial_size(grpc_exec_ctx *exec_ctx, int x); diff --git a/src/core/lib/debug/stats_data.yaml b/src/core/lib/debug/stats_data.yaml index b5c15ff55c0..5efe3532000 100644 --- a/src/core/lib/debug/stats_data.yaml +++ b/src/core/lib/debug/stats_data.yaml @@ -270,3 +270,7 @@ - counter: server_slowpath_requests_queued doc: How many times was the server slow path taken (indicates too few outstanding requests) +# cq +- counter: cq_failed_queue_trylocks + doc: Number of lock (trylock) acquisition failures on completion queue event + queue. High value here indicates high contention on completion queues diff --git a/src/core/lib/debug/stats_data_bq_schema.sql b/src/core/lib/debug/stats_data_bq_schema.sql index f96e40c00ef..6ad58e2530d 100644 --- a/src/core/lib/debug/stats_data_bq_schema.sql +++ b/src/core/lib/debug/stats_data_bq_schema.sql @@ -85,4 +85,5 @@ executor_wakeup_initiated_per_iteration:FLOAT, executor_queue_drained_per_iteration:FLOAT, executor_push_retries_per_iteration:FLOAT, server_requested_calls_per_iteration:FLOAT, -server_slowpath_requests_queued_per_iteration:FLOAT +server_slowpath_requests_queued_per_iteration:FLOAT, +cq_failed_queue_trylocks_per_iteration:FLOAT diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index fed66e3a209..037b10e8486 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -378,6 +378,10 @@ static grpc_cq_completion *cq_event_queue_pop(grpc_cq_event_queue *q) { if (gpr_spinlock_trylock(&q->queue_lock)) { c = (grpc_cq_completion *)gpr_mpscq_pop(&q->queue); gpr_spinlock_unlock(&q->queue_lock); + } else { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GRPC_STATS_INC_CQ_FAILED_QUEUE_TRYLOCKS(&exec_ctx); + grpc_exec_ctx_finish(&exec_ctx); } if (c) { diff --git a/tools/run_tests/performance/massage_qps_stats.py b/tools/run_tests/performance/massage_qps_stats.py index 9b9355308a3..49d165d94f6 100644 --- a/tools/run_tests/performance/massage_qps_stats.py +++ b/tools/run_tests/performance/massage_qps_stats.py @@ -108,6 +108,7 @@ def massage_qps_stats(scenario_result): stats["core_executor_push_retries"] = massage_qps_stats_helpers.counter(core_stats, "executor_push_retries") stats["core_server_requested_calls"] = massage_qps_stats_helpers.counter(core_stats, "server_requested_calls") stats["core_server_slowpath_requests_queued"] = massage_qps_stats_helpers.counter(core_stats, "server_slowpath_requests_queued") + stats["core_cq_failed_queue_trylocks"] = massage_qps_stats_helpers.counter(core_stats, "cq_failed_queue_trylocks") h = massage_qps_stats_helpers.histogram(core_stats, "call_initial_size") stats["core_call_initial_size"] = ",".join("%f" % x for x in h.buckets) stats["core_call_initial_size_bkts"] = ",".join("%f" % x for x in h.boundaries) diff --git a/tools/run_tests/performance/scenario_result_schema.json b/tools/run_tests/performance/scenario_result_schema.json index 2f0fd916d4f..11d8dba5d3f 100644 --- a/tools/run_tests/performance/scenario_result_schema.json +++ b/tools/run_tests/performance/scenario_result_schema.json @@ -550,6 +550,11 @@ "name": "core_server_slowpath_requests_queued", "type": "INTEGER" }, + { + "mode": "NULLABLE", + "name": "core_cq_failed_queue_trylocks", + "type": "INTEGER" + }, { "mode": "NULLABLE", "name": "core_call_initial_size", @@ -1342,6 +1347,11 @@ "name": "core_server_slowpath_requests_queued", "type": "INTEGER" }, + { + "mode": "NULLABLE", + "name": "core_cq_failed_queue_trylocks", + "type": "INTEGER" + }, { "mode": "NULLABLE", "name": "core_call_initial_size", From 0d0fa06488e09bb404511af15523f2e75a2e86c8 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Tue, 3 Oct 2017 16:04:42 -0700 Subject: [PATCH 02/35] Add more counters in cq --- src/core/lib/debug/stats_data.c | 8 ++++++- src/core/lib/debug/stats_data.h | 16 +++++++++---- src/core/lib/debug/stats_data.yaml | 8 ++++++- src/core/lib/debug/stats_data_bq_schema.sql | 4 +++- src/core/lib/surface/completion_queue.c | 17 +++++++++---- .../performance/massage_qps_stats.py | 4 +++- .../performance/scenario_result_schema.json | 24 +++++++++++++++++-- 7 files changed, 67 insertions(+), 14 deletions(-) diff --git a/src/core/lib/debug/stats_data.c b/src/core/lib/debug/stats_data.c index 41d9e95e294..a9ffaecfb9e 100644 --- a/src/core/lib/debug/stats_data.c +++ b/src/core/lib/debug/stats_data.c @@ -111,7 +111,9 @@ const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT] = { "executor_push_retries", "server_requested_calls", "server_slowpath_requests_queued", - "cq_failed_queue_trylocks", + "cq_ev_queue_trylock_failures", + "cq_ev_queue_trylock_successes", + "cq_ev_queue_transient_pop_failures", }; const char *grpc_stats_counter_doc[GRPC_STATS_COUNTER_COUNT] = { "Number of client side calls created by this process", @@ -223,6 +225,10 @@ const char *grpc_stats_counter_doc[GRPC_STATS_COUNTER_COUNT] = { "outstanding requests)", "Number of lock (trylock) acquisition failures on completion queue event " "queue. High value here indicates high contention on completion queues", + "Number of lock (trylock) acquisition successes on completion queue event " + "queue.", + "Number of times NULL was popped out of completion queue's event queue " + "even though the event queue was not empty", }; const char *grpc_stats_histogram_name[GRPC_STATS_HISTOGRAM_COUNT] = { "call_initial_size", diff --git a/src/core/lib/debug/stats_data.h b/src/core/lib/debug/stats_data.h index 0a2b323bdfa..86696cc438b 100644 --- a/src/core/lib/debug/stats_data.h +++ b/src/core/lib/debug/stats_data.h @@ -113,7 +113,9 @@ typedef enum { GRPC_STATS_COUNTER_EXECUTOR_PUSH_RETRIES, GRPC_STATS_COUNTER_SERVER_REQUESTED_CALLS, GRPC_STATS_COUNTER_SERVER_SLOWPATH_REQUESTS_QUEUED, - GRPC_STATS_COUNTER_CQ_FAILED_QUEUE_TRYLOCKS, + GRPC_STATS_COUNTER_CQ_EV_QUEUE_TRYLOCK_FAILURES, + GRPC_STATS_COUNTER_CQ_EV_QUEUE_TRYLOCK_SUCCESSES, + GRPC_STATS_COUNTER_CQ_EV_QUEUE_TRANSIENT_POP_FAILURES, GRPC_STATS_COUNTER_COUNT } grpc_stats_counters; extern const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT]; @@ -418,9 +420,15 @@ typedef enum { #define GRPC_STATS_INC_SERVER_SLOWPATH_REQUESTS_QUEUED(exec_ctx) \ GRPC_STATS_INC_COUNTER((exec_ctx), \ GRPC_STATS_COUNTER_SERVER_SLOWPATH_REQUESTS_QUEUED) -#define GRPC_STATS_INC_CQ_FAILED_QUEUE_TRYLOCKS(exec_ctx) \ - GRPC_STATS_INC_COUNTER((exec_ctx), \ - GRPC_STATS_COUNTER_CQ_FAILED_QUEUE_TRYLOCKS) +#define GRPC_STATS_INC_CQ_EV_QUEUE_TRYLOCK_FAILURES(exec_ctx) \ + GRPC_STATS_INC_COUNTER((exec_ctx), \ + GRPC_STATS_COUNTER_CQ_EV_QUEUE_TRYLOCK_FAILURES) +#define GRPC_STATS_INC_CQ_EV_QUEUE_TRYLOCK_SUCCESSES(exec_ctx) \ + GRPC_STATS_INC_COUNTER((exec_ctx), \ + GRPC_STATS_COUNTER_CQ_EV_QUEUE_TRYLOCK_SUCCESSES) +#define GRPC_STATS_INC_CQ_EV_QUEUE_TRANSIENT_POP_FAILURES(exec_ctx) \ + GRPC_STATS_INC_COUNTER( \ + (exec_ctx), GRPC_STATS_COUNTER_CQ_EV_QUEUE_TRANSIENT_POP_FAILURES) #define GRPC_STATS_INC_CALL_INITIAL_SIZE(exec_ctx, value) \ grpc_stats_inc_call_initial_size((exec_ctx), (int)(value)) void grpc_stats_inc_call_initial_size(grpc_exec_ctx *exec_ctx, int x); diff --git a/src/core/lib/debug/stats_data.yaml b/src/core/lib/debug/stats_data.yaml index 5efe3532000..e6602e13968 100644 --- a/src/core/lib/debug/stats_data.yaml +++ b/src/core/lib/debug/stats_data.yaml @@ -271,6 +271,12 @@ doc: How many times was the server slow path taken (indicates too few outstanding requests) # cq -- counter: cq_failed_queue_trylocks +- counter: cq_ev_queue_trylock_failures doc: Number of lock (trylock) acquisition failures on completion queue event queue. High value here indicates high contention on completion queues +- counter: cq_ev_queue_trylock_successes + doc: Number of lock (trylock) acquisition successes on completion queue event + queue. +- counter: cq_ev_queue_transient_pop_failures + doc: Number of times NULL was popped out of completion queue's event queue + even though the event queue was not empty diff --git a/src/core/lib/debug/stats_data_bq_schema.sql b/src/core/lib/debug/stats_data_bq_schema.sql index 6ad58e2530d..0f70a52a6cf 100644 --- a/src/core/lib/debug/stats_data_bq_schema.sql +++ b/src/core/lib/debug/stats_data_bq_schema.sql @@ -86,4 +86,6 @@ executor_queue_drained_per_iteration:FLOAT, executor_push_retries_per_iteration:FLOAT, server_requested_calls_per_iteration:FLOAT, server_slowpath_requests_queued_per_iteration:FLOAT, -cq_failed_queue_trylocks_per_iteration:FLOAT +cq_ev_queue_trylock_failures_per_iteration:FLOAT, +cq_ev_queue_trylock_successes_per_iteration:FLOAT, +cq_ev_queue_transient_pop_failures_per_iteration:FLOAT diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 037b10e8486..689b51cfbe5 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -375,15 +375,24 @@ static bool cq_event_queue_push(grpc_cq_event_queue *q, grpc_cq_completion *c) { static grpc_cq_completion *cq_event_queue_pop(grpc_cq_event_queue *q) { grpc_cq_completion *c = NULL; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + if (gpr_spinlock_trylock(&q->queue_lock)) { - c = (grpc_cq_completion *)gpr_mpscq_pop(&q->queue); + GRPC_STATS_INC_CQ_EV_QUEUE_TRYLOCK_SUCCESSES(&exec_ctx); + + bool is_empty = false; + c = (grpc_cq_completion *)gpr_mpscq_pop_and_check_end(&q->queue, &is_empty); gpr_spinlock_unlock(&q->queue_lock); + + if (c == NULL && !is_empty) { + GRPC_STATS_INC_CQ_EV_QUEUE_TRANSIENT_POP_FAILURES(&exec_ctx); + } } else { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - GRPC_STATS_INC_CQ_FAILED_QUEUE_TRYLOCKS(&exec_ctx); - grpc_exec_ctx_finish(&exec_ctx); + GRPC_STATS_INC_CQ_EV_QUEUE_TRYLOCK_FAILURES(&exec_ctx); } + grpc_exec_ctx_finish(&exec_ctx); + if (c) { gpr_atm_no_barrier_fetch_add(&q->num_queue_items, -1); } diff --git a/tools/run_tests/performance/massage_qps_stats.py b/tools/run_tests/performance/massage_qps_stats.py index 49d165d94f6..ad8585c27e5 100644 --- a/tools/run_tests/performance/massage_qps_stats.py +++ b/tools/run_tests/performance/massage_qps_stats.py @@ -108,7 +108,9 @@ def massage_qps_stats(scenario_result): stats["core_executor_push_retries"] = massage_qps_stats_helpers.counter(core_stats, "executor_push_retries") stats["core_server_requested_calls"] = massage_qps_stats_helpers.counter(core_stats, "server_requested_calls") stats["core_server_slowpath_requests_queued"] = massage_qps_stats_helpers.counter(core_stats, "server_slowpath_requests_queued") - stats["core_cq_failed_queue_trylocks"] = massage_qps_stats_helpers.counter(core_stats, "cq_failed_queue_trylocks") + stats["core_cq_ev_queue_trylock_failures"] = massage_qps_stats_helpers.counter(core_stats, "cq_ev_queue_trylock_failures") + stats["core_cq_ev_queue_trylock_successes"] = massage_qps_stats_helpers.counter(core_stats, "cq_ev_queue_trylock_successes") + stats["core_cq_ev_queue_transient_pop_failures"] = massage_qps_stats_helpers.counter(core_stats, "cq_ev_queue_transient_pop_failures") h = massage_qps_stats_helpers.histogram(core_stats, "call_initial_size") stats["core_call_initial_size"] = ",".join("%f" % x for x in h.buckets) stats["core_call_initial_size_bkts"] = ",".join("%f" % x for x in h.boundaries) diff --git a/tools/run_tests/performance/scenario_result_schema.json b/tools/run_tests/performance/scenario_result_schema.json index 11d8dba5d3f..099048c2975 100644 --- a/tools/run_tests/performance/scenario_result_schema.json +++ b/tools/run_tests/performance/scenario_result_schema.json @@ -552,7 +552,17 @@ }, { "mode": "NULLABLE", - "name": "core_cq_failed_queue_trylocks", + "name": "core_cq_ev_queue_trylock_failures", + "type": "INTEGER" + }, + { + "mode": "NULLABLE", + "name": "core_cq_ev_queue_trylock_successes", + "type": "INTEGER" + }, + { + "mode": "NULLABLE", + "name": "core_cq_ev_queue_transient_pop_failures", "type": "INTEGER" }, { @@ -1349,7 +1359,17 @@ }, { "mode": "NULLABLE", - "name": "core_cq_failed_queue_trylocks", + "name": "core_cq_ev_queue_trylock_failures", + "type": "INTEGER" + }, + { + "mode": "NULLABLE", + "name": "core_cq_ev_queue_trylock_successes", + "type": "INTEGER" + }, + { + "mode": "NULLABLE", + "name": "core_cq_ev_queue_transient_pop_failures", "type": "INTEGER" }, { From db78c2fa3b753f84940ff4fea0e7627b8779413e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 6 Oct 2017 10:09:09 -0700 Subject: [PATCH 03/35] Set gpr_mpscq_test to not use polling, make that bit work again --- build.yaml | 1 + .../run_tests/generated/tests.json.template | 3 +- tools/run_tests/generated/tests.json | 603 ++++++++++++------ 3 files changed, 405 insertions(+), 202 deletions(-) diff --git a/build.yaml b/build.yaml index 7033d52542d..ffaafd8bad7 100644 --- a/build.yaml +++ b/build.yaml @@ -2269,6 +2269,7 @@ targets: deps: - gpr_test_util - gpr + uses_polling: false - name: gpr_spinlock_test cpu_cost: 3 build: test diff --git a/templates/tools/run_tests/generated/tests.json.template b/templates/tools/run_tests/generated/tests.json.template index 10ab2e445a4..0c9f0a14c47 100644 --- a/templates/tools/run_tests/generated/tests.json.template +++ b/templates/tools/run_tests/generated/tests.json.template @@ -13,7 +13,8 @@ "exclude_iomgrs": tgt.get("exclude_iomgrs", []), "args": tgt.get("args", []), "flaky": tgt.flaky, - "cpu_cost": tgt.get("cpu_cost", 1.0)} + "cpu_cost": tgt.get("cpu_cost", 1.0), + "uses_polling": tgt.get("uses_polling", True)} timeout_seconds = tgt.get("timeout_seconds", None) if timeout_seconds: out['timeout_seconds'] = timeout_seconds diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 1fefb52f07d..860f324d8af 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -21,7 +21,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -43,7 +44,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -65,7 +67,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -87,7 +90,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -109,7 +113,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -133,7 +138,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -155,7 +161,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -177,7 +184,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -199,7 +207,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -221,7 +230,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -243,7 +253,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -265,7 +276,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -287,7 +299,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -309,7 +322,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -331,7 +345,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -353,7 +368,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -375,7 +391,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -397,7 +414,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -419,7 +437,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -441,7 +460,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -465,7 +485,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -487,7 +508,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -511,7 +533,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -533,7 +556,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -555,7 +579,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -579,7 +604,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -601,7 +627,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -619,7 +646,8 @@ "name": "ev_epollsig_linux_test", "platforms": [ "linux" - ] + ], + "uses_polling": true }, { "args": [], @@ -641,7 +669,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -661,7 +690,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -683,7 +713,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -705,7 +736,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -725,7 +757,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -745,7 +778,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -767,7 +801,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -789,7 +824,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -811,7 +847,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -833,7 +870,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -855,7 +893,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -877,7 +916,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -899,7 +939,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -921,7 +962,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -943,7 +985,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -965,7 +1008,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": false }, { "args": [], @@ -987,7 +1031,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1009,7 +1054,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1031,7 +1077,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1053,7 +1100,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1075,7 +1123,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1097,7 +1146,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1119,7 +1169,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1141,7 +1192,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1163,7 +1215,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1185,7 +1238,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1207,7 +1261,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1229,7 +1284,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1251,7 +1307,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1273,7 +1330,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1295,7 +1353,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1319,7 +1378,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1341,7 +1401,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1363,7 +1424,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1383,7 +1445,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -1405,7 +1468,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1427,7 +1491,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1445,7 +1510,8 @@ "name": "handshake_client", "platforms": [ "linux" - ] + ], + "uses_polling": true }, { "args": [], @@ -1463,7 +1529,8 @@ "name": "handshake_server", "platforms": [ "linux" - ] + ], + "uses_polling": true }, { "args": [], @@ -1485,7 +1552,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1507,7 +1575,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1529,7 +1598,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1551,7 +1621,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1571,7 +1642,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -1587,7 +1659,8 @@ "name": "httpscli_test", "platforms": [ "linux" - ] + ], + "uses_polling": true }, { "args": [], @@ -1609,7 +1682,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1631,7 +1705,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1653,7 +1728,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1675,7 +1751,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1697,7 +1774,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1719,7 +1797,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1741,7 +1820,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1761,7 +1841,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -1783,7 +1864,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1805,7 +1887,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1827,7 +1910,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1849,7 +1933,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1871,7 +1956,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1893,7 +1979,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1917,7 +2004,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1939,7 +2027,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1961,7 +2050,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -1979,7 +2069,8 @@ "name": "pollset_set_test", "platforms": [ "linux" - ] + ], + "uses_polling": true }, { "args": [], @@ -2001,7 +2092,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -2023,7 +2115,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2045,7 +2138,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2067,7 +2161,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2091,7 +2186,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2115,7 +2211,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2137,7 +2234,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2159,7 +2257,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2181,7 +2280,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2203,7 +2303,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2225,7 +2326,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2247,7 +2349,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2269,7 +2372,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2291,7 +2395,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2313,7 +2418,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -2333,7 +2439,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -2355,7 +2462,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2377,7 +2485,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2399,7 +2508,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2421,7 +2531,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -2445,7 +2556,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2467,7 +2579,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -2489,7 +2602,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -2513,7 +2627,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2535,7 +2650,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2557,7 +2673,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2581,7 +2698,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2605,7 +2723,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2627,7 +2746,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2649,7 +2769,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2671,7 +2792,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2691,7 +2813,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -2713,7 +2836,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -2735,7 +2859,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2757,7 +2882,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -2779,7 +2905,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2801,7 +2928,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -2823,7 +2951,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [ @@ -2845,7 +2974,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -2867,7 +2997,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -2889,7 +3020,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -2911,7 +3043,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -2933,7 +3066,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -2955,7 +3089,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -2977,7 +3112,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -2999,7 +3135,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -3026,7 +3163,8 @@ "mac", "posix" ], - "timeout_seconds": 1200 + "timeout_seconds": 1200, + "uses_polling": true }, { "args": [ @@ -3053,7 +3191,8 @@ "mac", "posix" ], - "timeout_seconds": 1200 + "timeout_seconds": 1200, + "uses_polling": true }, { "args": [ @@ -3080,7 +3219,8 @@ "mac", "posix" ], - "timeout_seconds": 1200 + "timeout_seconds": 1200, + "uses_polling": true }, { "args": [ @@ -3107,7 +3247,8 @@ "mac", "posix" ], - "timeout_seconds": 1200 + "timeout_seconds": 1200, + "uses_polling": true }, { "args": [ @@ -3129,7 +3270,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -3151,7 +3293,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -3173,7 +3316,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3195,7 +3339,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3217,7 +3362,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3237,7 +3383,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -3263,7 +3410,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3285,7 +3433,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3307,7 +3456,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3329,7 +3479,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3351,7 +3502,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3373,7 +3525,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3395,7 +3548,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3417,7 +3571,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3439,7 +3594,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3461,7 +3617,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3483,7 +3640,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3505,7 +3663,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [ @@ -3529,7 +3688,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3551,7 +3711,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3573,7 +3734,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3599,7 +3761,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3625,7 +3788,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3647,7 +3811,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3669,7 +3834,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3689,7 +3855,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -3711,7 +3878,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3733,7 +3901,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3755,7 +3924,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3777,7 +3947,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3799,7 +3970,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3819,7 +3991,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -3841,7 +4014,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3861,7 +4035,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -3883,7 +4058,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3905,7 +4081,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3927,7 +4104,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3947,7 +4125,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -3969,7 +4148,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -3991,7 +4171,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4013,7 +4194,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4035,7 +4217,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4055,7 +4238,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -4077,7 +4261,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4100,7 +4285,8 @@ "posix", "windows" ], - "timeout_seconds": 1200 + "timeout_seconds": 1200, + "uses_polling": true }, { "args": [], @@ -4120,7 +4306,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [], @@ -4142,7 +4329,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4166,7 +4354,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4190,7 +4379,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4214,7 +4404,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4238,7 +4429,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4262,7 +4454,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4286,7 +4479,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4310,7 +4504,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4334,7 +4529,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4358,7 +4554,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4382,7 +4579,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], @@ -4402,7 +4600,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -4425,7 +4624,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ @@ -4448,7 +4648,8 @@ "linux", "mac", "posix" - ] + ], + "uses_polling": true }, { "args": [ From 83a2cc0c4452beb70b5cb17a45c2433459b46a20 Mon Sep 17 00:00:00 2001 From: Guilherme Oliveira Date: Mon, 9 Oct 2017 11:53:27 +0200 Subject: [PATCH 04/35] php return the right classes --- src/php/lib/Grpc/BaseStub.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php index b62c2c2fa96..67378a34a8a 100644 --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -218,7 +218,7 @@ class BaseStub * (optional) * @param array $options An array of options (optional) * - * @return SimpleSurfaceActiveCall The active call object + * @return UnaryCall The active call object */ protected function _simpleRequest($method, $argument, @@ -253,7 +253,7 @@ class BaseStub * (optional) * @param array $options An array of options (optional) * - * @return ClientStreamingSurfaceActiveCall The active call object + * @return ClientStreamingCall The active call object */ protected function _clientStreamRequest($method, $deserialize, @@ -288,7 +288,7 @@ class BaseStub * (optional) * @param array $options An array of options (optional) * - * @return ServerStreamingSurfaceActiveCall The active call object + * @return ServerStreamingCall The active call object */ protected function _serverStreamRequest($method, $argument, @@ -322,7 +322,7 @@ class BaseStub * (optional) * @param array $options An array of options (optional) * - * @return BidiStreamingSurfaceActiveCall The active call object + * @return BidiStreamingCall The active call object */ protected function _bidiRequest($method, $deserialize, From 97b6e5db9f91f974a9655cbd591046d8c3b61a07 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 9 Oct 2017 08:31:41 -0700 Subject: [PATCH 05/35] Process updates immediately instead of waiting for a previous one to complete. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 55 +++---------------- 1 file changed, 7 insertions(+), 48 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 53fa0fff049..ffd58129c6e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -345,9 +345,6 @@ typedef struct glb_lb_policy { /** are we currently updating lb_call? */ bool updating_lb_call; - /** are we currently updating lb_channel? */ - bool updating_lb_channel; - /** are we already watching the LB channel's connectivity? */ bool watching_lb_channel; @@ -360,9 +357,6 @@ typedef struct glb_lb_policy { /** called upon changes to the LB channel's connectivity. */ grpc_closure lb_channel_on_connectivity_changed; - /** args from the latest update received while already updating, or NULL */ - grpc_lb_policy_args *pending_update_args; - /************************************************************/ /* client data associated with the LB server communication */ /************************************************************/ @@ -982,10 +976,6 @@ static void glb_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { } grpc_fake_resolver_response_generator_unref(glb_policy->response_generator); grpc_subchannel_index_unref(); - if (glb_policy->pending_update_args != NULL) { - grpc_channel_args_destroy(exec_ctx, glb_policy->pending_update_args->args); - gpr_free(glb_policy->pending_update_args); - } gpr_free(glb_policy); } @@ -1752,45 +1742,22 @@ static void glb_update_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, } const grpc_lb_addresses *addresses = (const grpc_lb_addresses *)arg->value.pointer.p; - + // If a non-empty serverlist hasn't been received from the balancer, + // propagate the update to fallback_backend_addresses. if (glb_policy->serverlist == NULL) { - // If a non-empty serverlist hasn't been received from the balancer, - // propagate the update to fallback_backend_addresses. fallback_update_locked(exec_ctx, glb_policy, addresses); - } else if (glb_policy->updating_lb_channel) { - // If we have recieved serverlist from the balancer, we need to defer update - // when there is an in-progress one. - if (GRPC_TRACER_ON(grpc_lb_glb_trace)) { - gpr_log(GPR_INFO, - "Update already in progress for grpclb %p. Deferring update.", - (void *)glb_policy); - } - if (glb_policy->pending_update_args != NULL) { - grpc_channel_args_destroy(exec_ctx, - glb_policy->pending_update_args->args); - gpr_free(glb_policy->pending_update_args); - } - glb_policy->pending_update_args = (grpc_lb_policy_args *)gpr_zalloc( - sizeof(*glb_policy->pending_update_args)); - glb_policy->pending_update_args->client_channel_factory = - args->client_channel_factory; - glb_policy->pending_update_args->args = grpc_channel_args_copy(args->args); - glb_policy->pending_update_args->combiner = args->combiner; - return; } - - glb_policy->updating_lb_channel = true; GPR_ASSERT(glb_policy->lb_channel != NULL); + // Propagate updates to the LB channel (pick_first) through the fake + // resolver. grpc_channel_args *lb_channel_args = build_lb_channel_args( exec_ctx, addresses, glb_policy->response_generator, args->args); - /* Propagate updates to the LB channel (pick first) through the fake resolver - */ grpc_fake_resolver_response_generator_set_response( exec_ctx, glb_policy->response_generator, lb_channel_args); grpc_channel_args_destroy(exec_ctx, lb_channel_args); - + // Start watching the LB channel connectivity for connection, if not + // already doing so. if (!glb_policy->watching_lb_channel) { - // Watch the LB channel connectivity for connection. glb_policy->lb_channel_connectivity = grpc_channel_check_connectivity_state( glb_policy->lb_channel, true /* try to connect */); grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element( @@ -1842,18 +1809,10 @@ static void glb_lb_channel_on_connectivity_changed_cb(grpc_exec_ctx *exec_ctx, /* fallthrough */ case GRPC_CHANNEL_READY: if (glb_policy->lb_call != NULL) { - glb_policy->updating_lb_channel = false; glb_policy->updating_lb_call = true; grpc_call_cancel(glb_policy->lb_call, NULL); - // lb_on_server_status_received will pick up the cancel and reinit + // lb_on_server_status_received() will pick up the cancel and reinit // lb_call. - if (glb_policy->pending_update_args != NULL) { - grpc_lb_policy_args *args = glb_policy->pending_update_args; - glb_policy->pending_update_args = NULL; - glb_update_locked(exec_ctx, &glb_policy->base, args); - grpc_channel_args_destroy(exec_ctx, args->args); - gpr_free(args); - } } else if (glb_policy->started_picking && !glb_policy->shutting_down) { if (glb_policy->retry_timer_active) { grpc_timer_cancel(exec_ctx, &glb_policy->lb_call_retry_timer); From a5ba0f991b81aefcaa976c4ec2cf6fa3e58160b2 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 9 Oct 2017 19:30:44 +0200 Subject: [PATCH 06/35] improve windows build instructions --- INSTALL.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index ea613f321de..15725bd188e 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -94,6 +94,7 @@ on experience with the tools involved. ### Building using CMake (RECOMMENDED) Builds gRPC C and C++ with boringssl. +- Install Visual Studio 2015 or 2017 (Visual C++ compiler will be used). - Install [CMake](https://cmake.org/download/). - Install [Active State Perl](https://www.activestate.com/activeperl/) (`choco install activeperl`) - Install [Ninja](https://ninja-build.org/) (`choco install ninja`) @@ -101,7 +102,9 @@ Builds gRPC C and C++ with boringssl. - Install [yasm](http://yasm.tortall.net/) and add it to `PATH` (`choco install yasm`) - Run these commands in the repo root directory -Using Ninja (faster build, supports boringssl's assembly optimizations) +#### cmake: Using Ninja (faster build, supports boringssl's assembly optimizations). +Please note that when using Ninja, you'll still need Visual C++ (part of Visual Studio) +installed to be able to compile the C/C++ sources. ``` > md .build > cd .build @@ -110,7 +113,12 @@ Using Ninja (faster build, supports boringssl's assembly optimizations) > cmake --build . ``` -Using Visual Studio 2015 (can only build with OPENSSL_NO_ASM) +#### cmake: Using Visual Studio 2015 (can only build with OPENSSL_NO_ASM). +When using the "Visual Studio" generator, +cmake will generate a solution (`grpc.sln`) that contains a VS project for +every target defined in `CMakeLists.txt` (+ few extra convenience projects +added automatically by cmake). After opening the solution with Visual Studio +you will be able to browse and build the code as usual. ``` > md .build > cd .build From 9f02a27ceb0777951f84b8470a1409b20c9f2d28 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 10 Oct 2017 12:57:01 -0700 Subject: [PATCH 07/35] Update load-balancing.md --- doc/load-balancing.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/load-balancing.md b/doc/load-balancing.md index 88ff35496f3..401900af883 100644 --- a/doc/load-balancing.md +++ b/doc/load-balancing.md @@ -129,10 +129,9 @@ works: by the resolver. It asks the balancer for the server addresses to use for the server name originally requested by the client (i.e., the same one originally passed to the name resolver). - - Note: The `grpclb` policy currently ignores any non-balancer - addresses returned by the resolver. However, in the future, it - may be changed to use these addresses as a fallback in case no - balancers can be contacted. + - Note: In `grpclb` policy, the non-balancer addresses returned by + the resolver are used as a fallback in case no balancers can be + contacted. 2. The gRPC servers to which the load balancer is directing the client may report load to the load balancers, if that information is needed by the load balancer's configuration. From 9f10a587a9f92ed5750334ad98b00eafc1ae97de Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 10 Oct 2017 11:31:29 -0700 Subject: [PATCH 08/35] Make short deadlines actually expire --- test/cpp/end2end/test_service_impl.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 4fa98c24f57..156ff8308ef 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -73,6 +73,10 @@ void CheckServerAuthContext( Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) { + // A bit of sleep to make sure that short deadline tests fail + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis(2, GPR_TIMESPAN))); + if (request->has_param() && request->param().server_die()) { gpr_log(GPR_ERROR, "The request should not reach application handler."); GPR_ASSERT(0); From 1e91362498f0213e7b7b0065ff1390ec2f9be2c4 Mon Sep 17 00:00:00 2001 From: Anna Sapek Date: Tue, 10 Oct 2017 15:23:09 -0700 Subject: [PATCH 09/35] Fix param annotation for AddListeningPort() --- include/grpc++/server_builder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h index bbf45b3e74c..a948abedb58 100644 --- a/include/grpc++/server_builder.h +++ b/include/grpc++/server_builder.h @@ -140,7 +140,7 @@ class ServerBuilder { /// please use IPv6 any, i.e., [::]:, which also accepts IPv4 /// connections. Valid values include dns:///localhost:1234, / /// 192.168.1.1:31416, dns:///[::1]:27182, etc.). - /// \params creds The credentials associated with the server. + /// \param creds The credentials associated with the server. /// \param selected_port[out] If not `nullptr`, gets populated with the port /// number bound to the \a grpc::Server for the corresponding endpoint after /// it is successfully bound, 0 otherwise. From a6294056c869eb1557f9c5230cd510cad9a3e12e Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 10 Oct 2017 20:47:54 -0700 Subject: [PATCH 10/35] Run ProxyEnd2End tests (without proxy) for inproc transport --- test/cpp/end2end/end2end_test.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 810ee303f2c..9c2be4d57e6 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1407,6 +1407,10 @@ TEST_P(ProxyEnd2endTest, HugeResponse) { } TEST_P(ProxyEnd2endTest, Peer) { + // Peer is not meaningful for inproc + if (GetParam().inproc) { + return; + } ResetStub(); EchoRequest request; EchoResponse response; @@ -1775,11 +1779,10 @@ std::vector CreateTestScenarios(bool use_proxy, credentials_types.push_back(kInsecureCredentialsType); } GPR_ASSERT(!credentials_types.empty()); - for (auto it = credentials_types.begin(); it != credentials_types.end(); - ++it) { - scenarios.emplace_back(false, false, *it); + for (const auto& cred : credentials_types) { + scenarios.emplace_back(false, false, cred); if (use_proxy) { - scenarios.emplace_back(true, false, *it); + scenarios.emplace_back(true, false, cred); } } if (test_inproc && insec_ok()) { @@ -1798,7 +1801,7 @@ INSTANTIATE_TEST_CASE_P(End2endServerTryCancel, End2endServerTryCancelTest, INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest, ::testing::ValuesIn(CreateTestScenarios(true, true, - true, false))); + true, true))); INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest, ::testing::ValuesIn(CreateTestScenarios(false, false, From 07165cbaf26a2e81710c3f4c0d3cf11bf91c9abb Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 10 Oct 2017 21:00:31 -0700 Subject: [PATCH 11/35] Only put server to sleep when explicitly requested --- src/proto/grpc/testing/echo_messages.proto | 1 + test/cpp/end2end/end2end_test.cc | 2 ++ test/cpp/end2end/test_service_impl.cc | 8 ++++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/proto/grpc/testing/echo_messages.proto b/src/proto/grpc/testing/echo_messages.proto index c5c5fdb3fc4..5396a2fd39a 100644 --- a/src/proto/grpc/testing/echo_messages.proto +++ b/src/proto/grpc/testing/echo_messages.proto @@ -45,6 +45,7 @@ message RequestParams { bool server_die = 12; // Server should not see a request with this set. string binary_error_details = 13; ErrorStatus expected_error = 14; + int32 server_sleep_us = 15; // Amount to sleep when invoking server } message EchoRequest { diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 810ee303f2c..3131faa196c 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1280,6 +1280,8 @@ TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) { EchoResponse response; request.set_message("Hello"); request.mutable_param()->set_skip_cancelled_check(true); + // Let server sleep for 2 ms first to guarantee expiry + request.mutable_param()->set_server_sleep_us(2 * 1000); ClientContext context; std::chrono::system_clock::time_point deadline = diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 156ff8308ef..e4f7c08f252 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -74,8 +74,12 @@ void CheckServerAuthContext( Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) { // A bit of sleep to make sure that short deadline tests fail - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis(2, GPR_TIMESPAN))); + if (request->has_param() && request->param().server_sleep_us() > 0) { + gpr_sleep_until( + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_micros(request->param().server_sleep_us(), + GPR_TIMESPAN))); + } if (request->has_param() && request->param().server_die()) { gpr_log(GPR_ERROR, "The request should not reach application handler."); From fed13916b0f62198992220eefa742e8b3e02cc99 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 11 Oct 2017 00:07:00 -0700 Subject: [PATCH 12/35] Move h2_ssl_cert_test out of end2end fixtures, use gtest --- CMakeLists.txt | 71 +- Makefile | 82 +- build.yaml | 16 + test/core/end2end/gen_build_yaml.py | 1 - test/core/end2end/generate_tests.bzl | 1 - .../h2_ssl_cert.c => h2_ssl_cert_test.cc} | 85 +- .../generated/sources_and_headers.json | 40 +- tools/run_tests/generated/tests.json | 1360 +---------------- 8 files changed, 199 insertions(+), 1457 deletions(-) rename test/core/end2end/{fixtures/h2_ssl_cert.c => h2_ssl_cert_test.cc} (89%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 139d1bd46cb..33e613c42fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -592,7 +592,6 @@ add_dependencies(buildtests_c h2_sockpair_test) add_dependencies(buildtests_c h2_sockpair+trace_test) add_dependencies(buildtests_c h2_sockpair_1byte_test) add_dependencies(buildtests_c h2_ssl_test) -add_dependencies(buildtests_c h2_ssl_cert_test) add_dependencies(buildtests_c h2_ssl_proxy_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c h2_uds_test) @@ -704,6 +703,7 @@ add_dependencies(buildtests_cxx grpc_tool_test) add_dependencies(buildtests_cxx grpclb_api_test) add_dependencies(buildtests_cxx grpclb_end2end_test) add_dependencies(buildtests_cxx grpclb_test) +add_dependencies(buildtests_cxx h2_ssl_cert_test) add_dependencies(buildtests_cxx health_service_end2end_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx http2_client) @@ -11163,6 +11163,45 @@ target_link_libraries(grpclb_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(h2_ssl_cert_test + test/core/end2end/h2_ssl_cert_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(h2_ssl_cert_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CARES_INCLUDE_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(h2_ssl_cert_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc++ + grpc + gpr_test_util + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(health_service_end2end_test test/cpp/end2end/health_service_end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc @@ -13585,36 +13624,6 @@ target_link_libraries(h2_ssl_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -add_executable(h2_ssl_cert_test - test/core/end2end/fixtures/h2_ssl_cert.c -) - - -target_include_directories(h2_ssl_cert_test - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include - PRIVATE ${BORINGSSL_ROOT_DIR}/include - PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${BENCHMARK_ROOT_DIR}/include - PRIVATE ${ZLIB_ROOT_DIR} - PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib - PRIVATE ${CARES_INCLUDE_DIR} - PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares - PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include -) - -target_link_libraries(h2_ssl_cert_test - ${_gRPC_ALLTARGETS_LIBRARIES} - end2end_tests - grpc_test_util - grpc - gpr_test_util - gpr -) - -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - add_executable(h2_ssl_proxy_test test/core/end2end/fixtures/h2_ssl_proxy.c ) diff --git a/Makefile b/Makefile index 382956dc44e..0357f7baac6 100644 --- a/Makefile +++ b/Makefile @@ -1145,6 +1145,7 @@ grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test grpclb_end2end_test: $(BINDIR)/$(CONFIG)/grpclb_end2end_test grpclb_test: $(BINDIR)/$(CONFIG)/grpclb_test +h2_ssl_cert_test: $(BINDIR)/$(CONFIG)/h2_ssl_cert_test health_service_end2end_test: $(BINDIR)/$(CONFIG)/health_service_end2end_test http2_client: $(BINDIR)/$(CONFIG)/http2_client hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test @@ -1247,7 +1248,6 @@ h2_sockpair_test: $(BINDIR)/$(CONFIG)/h2_sockpair_test h2_sockpair+trace_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test h2_sockpair_1byte_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test h2_ssl_test: $(BINDIR)/$(CONFIG)/h2_ssl_test -h2_ssl_cert_test: $(BINDIR)/$(CONFIG)/h2_ssl_cert_test h2_ssl_proxy_test: $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test h2_uds_test: $(BINDIR)/$(CONFIG)/h2_uds_test inproc_test: $(BINDIR)/$(CONFIG)/inproc_test @@ -1507,7 +1507,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test \ $(BINDIR)/$(CONFIG)/h2_ssl_test \ - $(BINDIR)/$(CONFIG)/h2_ssl_cert_test \ $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test \ $(BINDIR)/$(CONFIG)/h2_uds_test \ $(BINDIR)/$(CONFIG)/inproc_test \ @@ -1583,6 +1582,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ $(BINDIR)/$(CONFIG)/grpclb_end2end_test \ $(BINDIR)/$(CONFIG)/grpclb_test \ + $(BINDIR)/$(CONFIG)/h2_ssl_cert_test \ $(BINDIR)/$(CONFIG)/health_service_end2end_test \ $(BINDIR)/$(CONFIG)/http2_client \ $(BINDIR)/$(CONFIG)/hybrid_end2end_test \ @@ -1703,6 +1703,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ $(BINDIR)/$(CONFIG)/grpclb_end2end_test \ $(BINDIR)/$(CONFIG)/grpclb_test \ + $(BINDIR)/$(CONFIG)/h2_ssl_cert_test \ $(BINDIR)/$(CONFIG)/health_service_end2end_test \ $(BINDIR)/$(CONFIG)/http2_client \ $(BINDIR)/$(CONFIG)/hybrid_end2end_test \ @@ -2109,6 +2110,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/grpclb_end2end_test || ( echo test grpclb_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing grpclb_test" $(Q) $(BINDIR)/$(CONFIG)/grpclb_test || ( echo test grpclb_test failed ; exit 1 ) + $(E) "[RUN] Testing h2_ssl_cert_test" + $(Q) $(BINDIR)/$(CONFIG)/h2_ssl_cert_test || ( echo test h2_ssl_cert_test failed ; exit 1 ) $(E) "[RUN] Testing health_service_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/health_service_end2end_test || ( echo test health_service_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing interop_test" @@ -15653,6 +15656,49 @@ endif $(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc +H2_SSL_CERT_TEST_SRC = \ + test/core/end2end/h2_ssl_cert_test.cc \ + +H2_SSL_CERT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SSL_CERT_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: $(PROTOBUF_DEP) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/h2_ssl_cert_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_cert_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_ssl_cert_test: $(H2_SSL_CERT_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_SSL_CERT_TEST_OBJS:.o=.dep) +endif +endif + + HEALTH_SERVICE_END2END_TEST_SRC = \ test/cpp/end2end/health_service_end2end_test.cc \ @@ -19100,38 +19146,6 @@ endif endif -H2_SSL_CERT_TEST_SRC = \ - test/core/end2end/fixtures/h2_ssl_cert.c \ - -H2_SSL_CERT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SSL_CERT_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_cert_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_cert.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_h2_ssl_cert_test: $(H2_SSL_CERT_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(H2_SSL_CERT_TEST_OBJS:.o=.dep) -endif -endif - - H2_SSL_PROXY_TEST_SRC = \ test/core/end2end/fixtures/h2_ssl_proxy.c \ diff --git a/build.yaml b/build.yaml index d23716af2af..25c5760e5e5 100644 --- a/build.yaml +++ b/build.yaml @@ -4158,6 +4158,22 @@ targets: excluded_poll_engines: - poll - poll-cv +- name: h2_ssl_cert_test + gtest: true + build: test + language: c++ + headers: + - test/core/end2end/end2end_tests.h + src: + - test/core/end2end/h2_ssl_cert_test.cc + deps: + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr + uses: + - grpc++_test - name: health_service_end2end_test gtest: true build: test diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 33fd97f3bd0..e1dc69994c4 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -60,7 +60,6 @@ END2END_FIXTURES = { 'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace( ci_mac=False, tracing=True, large_writes=False, exclude_iomgrs=['uv']), 'h2_ssl': default_secure_fixture_options, - 'h2_ssl_cert': default_secure_fixture_options, 'h2_ssl_proxy': default_secure_fixture_options._replace( includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']), 'h2_uds': uds_fixture_options, diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 9bbba26108c..d48ddb46064 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -56,7 +56,6 @@ END2END_FIXTURES = { 'h2_sockpair+trace': fixture_options(fullstack=False, dns_resolver=False, tracing=True), 'h2_ssl': fixture_options(secure=True), - 'h2_ssl_cert': fixture_options(secure=True), 'h2_ssl_proxy': fixture_options(includes_proxy=True, secure=True), 'h2_uds': fixture_options(dns_resolver=False, platforms=['linux', 'mac', 'posix']), diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/h2_ssl_cert_test.cc similarity index 89% rename from test/core/end2end/fixtures/h2_ssl_cert.c rename to test/core/end2end/h2_ssl_cert_test.cc index f0a2ee5430e..6da5e8396ef 100644 --- a/test/core/end2end/fixtures/h2_ssl_cert.c +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -16,7 +16,9 @@ * */ +extern "C" { #include "test/core/end2end/end2end_tests.h" +} #include #include @@ -25,6 +27,7 @@ #include #include +extern "C" { #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/support/env.h" @@ -34,8 +37,12 @@ #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" +} -extern void simple_request(grpc_end2end_test_config config); +#include + +namespace grpc { +namespace testing { typedef struct fullstack_secure_fixture_data { char *localaddr; @@ -46,7 +53,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data *ffd = - gpr_malloc(sizeof(fullstack_secure_fixture_data)); + static_cast( + gpr_malloc(sizeof(fullstack_secure_fixture_data))); memset(&f, 0, sizeof(f)); gpr_join_host_port(&ffd->localaddr, "localhost", port); @@ -69,7 +77,8 @@ static void process_auth_failure(void *state, grpc_auth_context *ctx, static void chttp2_init_client_secure_fullstack( grpc_end2end_test_fixture *f, grpc_channel_args *client_args, grpc_channel_credentials *creds) { - fullstack_secure_fixture_data *ffd = f->fixture_data; + fullstack_secure_fixture_data *ffd = + static_cast(f->fixture_data); f->client = grpc_secure_channel_create(creds, ffd->localaddr, client_args, NULL); GPR_ASSERT(f->client != NULL); @@ -79,7 +88,8 @@ static void chttp2_init_client_secure_fullstack( 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; + fullstack_secure_fixture_data *ffd = + static_cast(f->fixture_data); if (f->server) { grpc_server_destroy(f->server); } @@ -92,7 +102,8 @@ static void chttp2_init_server_secure_fullstack( } void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { - fullstack_secure_fixture_data *ffd = f->fixture_data; + fullstack_secure_fixture_data *ffd = + static_cast(f->fixture_data); gpr_free(ffd->localaddr); gpr_free(ffd); } @@ -166,9 +177,10 @@ typedef enum { NONE, SELF_SIGNED, SIGNED, BAD_CERT_PAIR } certtype; } \ ssl_creds = \ grpc_ssl_credentials_create(test_root_cert, key_cert_pair, NULL); \ - grpc_arg ssl_name_override = {GRPC_ARG_STRING, \ - GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, \ - {"foo.test.google.fr"}}; \ + grpc_arg ssl_name_override = { \ + GRPC_ARG_STRING, \ + const_cast(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), \ + {const_cast("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); \ @@ -248,18 +260,6 @@ static grpc_end2end_test_config_wrapper configs[] = { static void *tag(intptr_t t) { return (void *)t; } -static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, - const char *test_name, - grpc_channel_args *client_args, - grpc_channel_args *server_args) { - grpc_end2end_test_fixture f; - gpr_log(GPR_INFO, "%s/%s", test_name, config.name); - f = config.create_fixture(client_args, server_args); - config.init_server(&f, server_args); - config.init_client(&f, client_args); - return f; -} - static gpr_timespec n_seconds_time(int n) { return grpc_timeout_seconds_to_deadline(n); } @@ -332,15 +332,40 @@ static void simple_request_body(grpc_end2end_test_fixture f, cq_verifier_destroy(cqv); } +class H2SslCertTest + : public ::testing::TestWithParam { + protected: + H2SslCertTest() { + gpr_log(GPR_INFO, "SSL_CERT_tests/%s", GetParam().config.name); + } + void SetUp() override { + fixture_ = GetParam().config.create_fixture(nullptr, nullptr); + GetParam().config.init_server(&fixture_, nullptr); + GetParam().config.init_client(&fixture_, nullptr); + } + void TearDown() override { + end_test(&fixture_); + GetParam().config.tear_down_data(&fixture_); + } + + grpc_end2end_test_fixture fixture_; +}; + +TEST_P(H2SslCertTest, SimpleRequestBody) { + simple_request_body(fixture_, GetParam().result); +} + +INSTANTIATE_TEST_CASE_P(H2SslCert, H2SslCertTest, ::testing::ValuesIn(configs)); + +} // namespace testing +} // namespace grpc + 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); - grpc_end2end_tests_pre_init(); - /* Set the SSL roots env var. */ roots_file = gpr_tmpfile("chttp2_simple_ssl_cert_fullstack_test", &roots_filename); @@ -351,21 +376,13 @@ int main(int argc, char **argv) { 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_test_fixture f = - begin_test(configs[i].config, "SSL_CERT_tests", NULL, NULL); - - simple_request_body(f, configs[i].result); - end_test(&f); - configs[i].config.tear_down_data(&f); - } - + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); grpc_shutdown(); /* Cleanup. */ remove(roots_filename); gpr_free(roots_filename); - return 0; + return ret; } diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index babdfeb6858..21b3bef691a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3489,6 +3489,28 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test", + "grpc_test_util" + ], + "headers": [ + "test/core/end2end/end2end_tests.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "h2_ssl_cert_test", + "src": [ + "test/core/end2end/end2end_tests.h", + "test/core/end2end/h2_ssl_cert_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -5287,24 +5309,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "end2end_tests", - "gpr", - "gpr_test_util", - "grpc", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "h2_ssl_cert_test", - "src": [ - "test/core/end2end/fixtures/h2_ssl_cert.c" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "end2end_tests", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 83418423a20..97631f679ce 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3627,6 +3627,28 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "h2_ssl_cert_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ @@ -26393,1344 +26415,6 @@ "posix" ] }, - { - "args": [ - "authority_not_supported" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "bad_hostname" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "bad_ping" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "binary_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "call_creds" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_accept" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_client_done" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_invoke" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_round_trip" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_before_invoke" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_in_a_vacuum" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_with_status" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "compressed_payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "connectivity" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "default_host" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "disappearing_server" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": true, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "empty_batch" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_call_init_fails" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_causes_close" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_latency" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "graceful_server_shutdown" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "high_initial_seqno" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "hpack_size" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "idempotent_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "invoke_large_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "keepalive_timeout" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "large_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "load_reporting_hook" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "max_concurrent_streams" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "max_connection_age" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "max_connection_idle" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "max_message_length" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "negative_deadline" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_logging" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_op" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "ping" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "ping_pong_streaming" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "registered_call" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "request_with_flags" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "request_with_payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "resource_quota_server" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "server_finishes_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "shutdown_finishes_calls" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "shutdown_finishes_tags" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "simple_cacheable_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "simple_delayed_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "simple_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "simple_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "stream_compression_compressed_payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "stream_compression_payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "stream_compression_ping_pong_streaming" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "streaming_error_response" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "trailing_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "workaround_cronet_compression" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "write_buffering" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "write_buffering_at_end" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_cert_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "authority_not_supported" From 99fafa17a3dc7b0956f1282026d68b290d17bb22 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 11 Oct 2017 08:26:32 -0700 Subject: [PATCH 13/35] Fix compilation --- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 6f9dee78224..8ee3ae72686 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -26,14 +26,12 @@ #include #include #include -extern "C" { #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/static_metadata.h" -} #include "test/cpp/microbenchmarks/helpers.h" #include "third_party/benchmark/include/benchmark/benchmark.h" From 4048569477b71aab51821beea4ef2e4698779b93 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 11 Oct 2017 08:29:42 -0700 Subject: [PATCH 14/35] Fix compilation --- test/core/util/trickle_endpoint.h | 8 ++++++++ test/cpp/microbenchmarks/bm_fullstack_trickle.cc | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/test/core/util/trickle_endpoint.h b/test/core/util/trickle_endpoint.h index 78f1eeeda2f..ca39638ba0d 100644 --- a/test/core/util/trickle_endpoint.h +++ b/test/core/util/trickle_endpoint.h @@ -21,6 +21,10 @@ #include "src/core/lib/iomgr/endpoint.h" +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + grpc_endpoint *grpc_trickle_endpoint_create(grpc_endpoint *wrap, double bytes_per_second); @@ -30,4 +34,8 @@ size_t grpc_trickle_endpoint_trickle(grpc_exec_ctx *exec_ctx, size_t grpc_trickle_get_backlog(grpc_endpoint *endpoint); +#ifdef __cplusplus +} +#endif // __cplusplus + #endif diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc index adb5e6657f2..14eb3534cf5 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc @@ -26,12 +26,10 @@ #include "test/cpp/microbenchmarks/fullstack_context_mutators.h" #include "test/cpp/microbenchmarks/fullstack_fixtures.h" #include "test/cpp/util/test_config.h" -extern "C" { #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include "src/core/lib/iomgr/timer_manager.h" #include "test/core/util/trickle_endpoint.h" -} DEFINE_bool(log, false, "Log state to CSV files"); DEFINE_int32( From 0ca5d863e1853fd54023ac6c094eaa31e59b949c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 11 Oct 2017 08:55:30 -0700 Subject: [PATCH 15/35] Fix leak --- .../ext/transport/chttp2/transport/chttp2_transport.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index f6f9242caf5..eea7f1f609e 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -571,6 +571,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED; } + GRPC_CHTTP2_REF_TRANSPORT(t, "bdp_ping"); schedule_bdp_ping_locked(exec_ctx, t); grpc_chttp2_act_on_flowctl_action( @@ -2568,7 +2569,6 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, static void schedule_bdp_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { - GRPC_CHTTP2_REF_TRANSPORT(t, "bdp_ping"); t->flow_control.bdp_estimator->SchedulePing(); send_ping_locked(exec_ctx, t, &t->start_bdp_ping_locked, &t->finish_bdp_ping_locked); @@ -2578,7 +2578,8 @@ static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_error *error) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)tp; if (GRPC_TRACER_ON(grpc_http_trace)) { - gpr_log(GPR_DEBUG, "%s: Start BDP ping", t->peer_string); + gpr_log(GPR_DEBUG, "%s: Start BDP ping err=%s", t->peer_string, + grpc_error_string(error)); } /* Reset the keepalive ping timer */ if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING) { @@ -2591,9 +2592,10 @@ static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_error *error) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)tp; if (GRPC_TRACER_ON(grpc_http_trace)) { - gpr_log(GPR_DEBUG, "%s: Complete BDP ping", t->peer_string); + gpr_log(GPR_DEBUG, "%s: Complete BDP ping err=%s", t->peer_string, + grpc_error_string(error)); } - if (error == GRPC_ERROR_CANCELLED) { + if (error != GRPC_ERROR_NONE) { GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "bdp_ping"); return; } From e94374d0a5a3040ca71392be4c61b17f6ef99030 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 11 Oct 2017 08:55:43 -0700 Subject: [PATCH 16/35] Fix leak --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index eea7f1f609e..fbd3c328a08 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -2611,7 +2611,7 @@ static void next_bdp_ping_timer_expired_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t = (grpc_chttp2_transport *)tp; GPR_ASSERT(t->have_next_bdp_ping_timer); t->have_next_bdp_ping_timer = false; - if (error == GRPC_ERROR_CANCELLED) { + if (error != GRPC_ERROR_NONE) { GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "bdp_ping"); return; } From df7583e0b6f715ed06eeeda4a3f2bfc4b6940e22 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 11 Oct 2017 09:26:12 -0700 Subject: [PATCH 17/35] Update load-balancing.md --- doc/load-balancing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/load-balancing.md b/doc/load-balancing.md index 401900af883..8ff94075b5f 100644 --- a/doc/load-balancing.md +++ b/doc/load-balancing.md @@ -129,9 +129,9 @@ works: by the resolver. It asks the balancer for the server addresses to use for the server name originally requested by the client (i.e., the same one originally passed to the name resolver). - - Note: In `grpclb` policy, the non-balancer addresses returned by - the resolver are used as a fallback in case no balancers can be - contacted. + - Note: In the `grpclb` policy, the non-balancer addresses returned + by the resolver are used as a fallback in case no balancers can be + contacted when the LB policy is started. 2. The gRPC servers to which the load balancer is directing the client may report load to the load balancers, if that information is needed by the load balancer's configuration. From 1ba537069ca8ac3b97502f66e815f9e84a73acbc Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 11 Oct 2017 10:10:23 -0700 Subject: [PATCH 18/35] Sanity check that tests declared non-polling actually don't poll --- src/core/lib/iomgr/ev_posix.cc | 18 ++++++++++++++++++ tools/run_tests/generated/tests.json | 3 ++- tools/run_tests/run_tests.py | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index e4033fab1de..369baa621f1 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -61,12 +61,30 @@ typedef struct { event_engine_factory_fn factory; } event_engine_factory; +namespace { +extern "C" { +int dummypoll(struct pollfd fds[], nfds_t nfds, int timeout) { + gpr_log(GPR_ERROR, "Attempted to poll despite declaring non-polling."); + GPR_ASSERT(false); + return -1; +} +} // extern "C" + +const grpc_event_engine_vtable *init_non_polling(bool explicit_request) { + // return the simplest engine as a dummy but also override the poller + auto ret = grpc_init_poll_posix(explicit_request); + grpc_poll_function = dummypoll; + return ret; +} +} // namespace + static const event_engine_factory g_factories[] = { {"epoll1", grpc_init_epoll1_linux}, {"epollsig", grpc_init_epollsig_linux}, {"poll", grpc_init_poll_posix}, {"poll-cv", grpc_init_poll_cv_posix}, {"epollex", grpc_init_epollex_linux}, + {"none", init_non_polling}, }; static void add(const char *beg, const char *end, char ***ss, size_t *ns) { diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 4db823e0039..91c7d4c38e5 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3811,7 +3811,8 @@ "mac", "posix", "windows" - ] + ], + "uses_polling": true }, { "args": [], diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 7c65067857f..ea21c81875d 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -286,7 +286,7 @@ class CLanguage(object): continue polling_strategies = (_POLLING_STRATEGIES.get(self.platform, ['all']) if target.get('uses_polling', True) - else ['all']) + else ['none']) if self.args.iomgr_platform == 'uv': polling_strategies = ['all'] for polling_strategy in polling_strategies: From 10ab806d2820fe64f991a006dc60c61e8a4ce0cc Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Wed, 11 Oct 2017 11:30:56 -0700 Subject: [PATCH 19/35] record results to bq --- tools/internal_ci/linux/grpc_interop_matrix.sh | 2 +- tools/interop_matrix/run_interop_matrix_tests.py | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/internal_ci/linux/grpc_interop_matrix.sh b/tools/internal_ci/linux/grpc_interop_matrix.sh index e199d489314..6a9c38705ab 100755 --- a/tools/internal_ci/linux/grpc_interop_matrix.sh +++ b/tools/internal_ci/linux/grpc_interop_matrix.sh @@ -22,4 +22,4 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc -tools/interop_matrix/run_interop_matrix_tests.py --language=all --release=all --report_file=sponge_log.xml $@ +tools/interop_matrix/run_interop_matrix_tests.py --language=all --release=all --report_file=sponge_log.xml --bq_result_table interop_results $@ diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 48c918d25d4..cd963d0e2d9 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -36,6 +36,7 @@ sys.path.append(python_util_dir) import dockerjob import jobset import report_utils +import upload_test_results _LANGUAGES = client_matrix.LANG_RUNTIME_MATRIX.keys() # All gRPC release tags, flattened, deduped and sorted. @@ -74,6 +75,11 @@ argp.add_argument('--allow_flakes', const=True, help=('Allow flaky tests to show as passing (re-runs failed ' 'tests up to five times)')) +argp.add_argument('--bq_result_table', + default='', + type=str, + nargs='?', + help='Upload test results to a specified BQ table.') args = argp.parse_args() @@ -168,6 +174,9 @@ def run_tests_for_lang(lang, runtime, images): newline_on_success=True, add_env={'docker_image':image}, maxjobs=args.jobs) + if args.bq_result_table and resultset: + upload_test_results.upload_interop_results_to_bq( + resultset, args.bq_result_table, args) if num_failures: jobset.message('FAILED', 'Some tests failed', do_newline=True) total_num_failures += num_failures From 147a45ae8037332b15ec1e9ce9259aa8be6c915a Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 11 Oct 2017 15:19:06 -0700 Subject: [PATCH 20/35] Allow zero-duration polls in non-poller --- src/core/lib/iomgr/ev_posix.cc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 369baa621f1..3a1dd8d30b3 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -62,18 +62,31 @@ typedef struct { } event_engine_factory; namespace { + extern "C" { -int dummypoll(struct pollfd fds[], nfds_t nfds, int timeout) { - gpr_log(GPR_ERROR, "Attempted to poll despite declaring non-polling."); - GPR_ASSERT(false); - return -1; + +grpc_poll_function_type real_poll_function; + +int dummy_poll(struct pollfd fds[], nfds_t nfds, int timeout) { + if (timeout == 0) { + return real_poll_function(fds, nfds, 0); + } else { + gpr_log(GPR_ERROR, "Attempted a blocking poll when declared non-polling."); + GPR_ASSERT(false); + return -1; + } } } // extern "C" const grpc_event_engine_vtable *init_non_polling(bool explicit_request) { + if (!explicit_request) { + return nullptr; + } // return the simplest engine as a dummy but also override the poller auto ret = grpc_init_poll_posix(explicit_request); - grpc_poll_function = dummypoll; + real_poll_function = grpc_poll_function; + grpc_poll_function = dummy_poll; + return ret; } } // namespace From 1dcc10359c0ff6d3e813766217e5b41989ad01fa Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Wed, 11 Oct 2017 16:38:38 -0700 Subject: [PATCH 21/35] Make cloud_to_prod test shortname format consistent with cloud_to_cloud --- tools/run_tests/run_interop_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 192f8e76eb4..4dd982756d2 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -677,7 +677,7 @@ def cloud_to_prod_jobspec(language, test_case, server_host_name, cmdline=cmdline, cwd=cwd, environ=environ, - shortname='%s:%s:%s:%s' % (suite_name, server_host_name, language, + shortname='%s:%s:%s:%s' % (suite_name, language, server_host_name, test_case), timeout_seconds=_TEST_TIMEOUT, flake_retries=5 if args.allow_flakes else 0, From 091c3ebba8b8c85318f88efba319e357149bb8b1 Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Wed, 11 Oct 2017 16:51:06 -0700 Subject: [PATCH 22/35] Add suite name, client lang, server name to shortname for displaying on Sponge and being able to use upload_interop_results_to_bq func --- tools/interop_matrix/run_interop_matrix_tests.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index cd963d0e2d9..d037e139218 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -123,7 +123,7 @@ def find_all_images_for_lang(lang): # caches test cases (list of JobSpec) loaded from file. Keyed by lang and runtime. _loaded_testcases = {} -def find_test_cases(lang, release): +def find_test_cases(lang, release, suite_name): """Returns the list of test cases from testcase files per lang/release.""" file_tmpl = os.path.join(os.path.dirname(__file__), 'testcases/%s__%s') if not os.path.exists(file_tmpl % (lang, release)): @@ -140,8 +140,12 @@ def find_test_cases(lang, release): if line.startswith('docker run'): m = re.search('--test_case=(.*)"', line) shortname = m.group(1) if m else 'unknown_test' + m = re.search('--server_host_override=(.*).sandbox.googleapis.com', + line) + server = m.group(1) if m else 'unknown_server' spec = jobset.JobSpec(cmdline=line, - shortname=shortname, + shortname='%s:%s:%s:%s' % (suite_name, lang, + server, shortname), timeout_seconds=_TEST_TIMEOUT, shell=True, flake_retries=5 if args.allow_flakes else 0) @@ -169,7 +173,8 @@ def run_tests_for_lang(lang, runtime, images): # Download the docker image before running each test case. subprocess.check_call(['gcloud', 'docker', '--', 'pull', image]) _docker_images_cleanup.append(image) - job_spec_list = find_test_cases(lang,release) + suite_name = '%s__%s_%s' % (lang, runtime, release) + job_spec_list = find_test_cases(lang, release, suite_name) num_failures, resultset = jobset.run(job_spec_list, newline_on_success=True, add_env={'docker_image':image}, @@ -187,7 +192,7 @@ def run_tests_for_lang(lang, runtime, images): _xml_report_tree, resultset, 'grpc_interop_matrix', - '%s__%s %s'%(lang,runtime,release), + suite_name, str(uuid.uuid4())) return total_num_failures From 85516af26ae38d8f628d70a4bf30c7e7c29a99b1 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 11 Oct 2017 18:16:21 -0700 Subject: [PATCH 23/35] Fix tests --- .../chttp2/transport/chttp2_transport.cc | 54 ++++++++++++------- .../ext/transport/chttp2/transport/internal.h | 10 ++-- .../ext/transport/chttp2/transport/writing.cc | 3 +- test/core/end2end/bad_server_response_test.c | 6 +-- test/core/end2end/tests/bad_ping.c | 3 +- test/core/end2end/tests/keepalive_timeout.c | 2 +- test/core/end2end/tests/max_connection_age.c | 3 +- .../end2end/tests/shutdown_finishes_calls.c | 2 +- 8 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index fbd3c328a08..659208ccf0e 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -224,6 +224,7 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx, t->flow_control.bdp_estimator.Destroy(); + GRPC_ERROR_UNREF(t->closed_with_error); gpr_free(t->ping_acks); gpr_free(t->peer_string); gpr_free(t); @@ -571,8 +572,10 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED; } - GRPC_CHTTP2_REF_TRANSPORT(t, "bdp_ping"); - schedule_bdp_ping_locked(exec_ctx, t); + if (t->flow_control.enable_bdp_probe) { + GRPC_CHTTP2_REF_TRANSPORT(t, "bdp_ping"); + schedule_bdp_ping_locked(exec_ctx, t); + } grpc_chttp2_act_on_flowctl_action( exec_ctx, @@ -607,7 +610,9 @@ static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { static void close_transport_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error) { - if (!t->closed) { + end_all_the_calls(exec_ctx, t, GRPC_ERROR_REF(error)); + cancel_pings(exec_ctx, t, GRPC_ERROR_REF(error)); + if (t->closed_with_error == nullptr) { if (!grpc_error_has_clear_grpc_status(error)) { error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); @@ -622,10 +627,10 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx, grpc_error_add_child(t->close_transport_on_writes_finished, error); return; } - t->closed = 1; + GPR_ASSERT(error != GRPC_ERROR_NONE); + t->closed_with_error = GRPC_ERROR_REF(error); connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), "close_transport"); - grpc_endpoint_shutdown(exec_ctx, t->ep, GRPC_ERROR_REF(error)); if (t->ping_state.is_delayed_ping_timer_set) { grpc_timer_cancel(exec_ctx, &t->ping_state.delayed_ping_timer); } @@ -651,8 +656,9 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx, while (grpc_chttp2_list_pop_writable_stream(t, &s)) { GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:close"); } - end_all_the_calls(exec_ctx, t, GRPC_ERROR_REF(error)); - cancel_pings(exec_ctx, t, GRPC_ERROR_REF(error)); + if (t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE) { + grpc_endpoint_shutdown(exec_ctx, t->ep, GRPC_ERROR_REF(error)); + } } GRPC_ERROR_UNREF(error); } @@ -848,6 +854,10 @@ static void set_write_state(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->close_transport_on_writes_finished = NULL; close_transport_locked(exec_ctx, t, err); } + if (t->closed_with_error != GRPC_ERROR_NONE) { + grpc_endpoint_shutdown(exec_ctx, t->ep, + GRPC_ERROR_REF(t->closed_with_error)); + } } } @@ -955,7 +965,8 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, void grpc_chttp2_mark_stream_writable(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s)) { + if (t->closed_with_error == GRPC_ERROR_NONE && + grpc_chttp2_list_add_writable_stream(t, s)) { GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:become"); } } @@ -1008,7 +1019,7 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt, grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); grpc_chttp2_begin_write_result r; - if (t->closed) { + if (t->closed_with_error != GRPC_ERROR_NONE) { r.writing = false; } else { r = grpc_chttp2_begin_write(exec_ctx, t); @@ -1471,7 +1482,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, } if (!s->write_closed) { if (t->is_client) { - if (!t->closed) { + if (t->closed_with_error == GRPC_ERROR_NONE) { GPR_ASSERT(s->id == 0); grpc_chttp2_list_add_waiting_for_concurrency(t, s); maybe_start_some_streams(exec_ctx, t); @@ -1479,7 +1490,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, grpc_chttp2_cancel_stream( exec_ctx, t, s, grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport closed"), + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Transport closed", &t->closed_with_error, 1), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); } } else { @@ -1768,7 +1780,10 @@ void grpc_chttp2_add_ping_strike(grpc_exec_ctx *exec_ctx, GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM)); /*The transport will be closed after the write is done */ close_transport_locked( - exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many pings")); + exec_ctx, t, + grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many pings"), + GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM)); } } @@ -2496,7 +2511,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, } GPR_SWAP(grpc_error *, err, error); GRPC_ERROR_UNREF(err); - if (!t->closed) { + if (t->closed_with_error == GRPC_ERROR_NONE) { GPR_TIMER_BEGIN("reading_action.parse", 0); size_t i = 0; grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE, @@ -2536,13 +2551,14 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_BEGIN("post_reading_action_locked", 0); bool keep_reading = false; - if (error == GRPC_ERROR_NONE && t->closed) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport closed"); + if (error == GRPC_ERROR_NONE && t->closed_with_error != GRPC_ERROR_NONE) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Transport closed", &t->closed_with_error, 1); } if (error != GRPC_ERROR_NONE) { close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error)); t->endpoint_reading = 0; - } else if (!t->closed) { + } else if (t->closed_with_error == GRPC_ERROR_NONE) { keep_reading = true; GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading"); } @@ -2680,7 +2696,7 @@ static void init_keepalive_ping_locked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)arg; GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING); - if (t->destroying || t->closed) { + if (t->destroying || t->closed_with_error != GRPC_ERROR_NONE) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; } else if (error == GRPC_ERROR_NONE) { if (t->keepalive_permit_without_calls || @@ -2738,8 +2754,8 @@ static void keepalive_watchdog_fired_locked(grpc_exec_ctx *exec_ctx, void *arg, if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; - close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "keepalive watchdog timeout")); + close_transport_locked(exec_ctx, t, grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "keepalive watchdog timeout"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL)); } } else { /* The watchdog timer should have been cancelled by diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 739da497c19..703f3ba348e 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -298,7 +298,7 @@ struct grpc_chttp2_transport { /** is the transport destroying itself? */ uint8_t destroying; /** has the upper layer closed the transport? */ - uint8_t closed; + grpc_error *closed_with_error; /** is there a read request to the endpoint outstanding? */ uint8_t endpoint_reading; @@ -340,7 +340,7 @@ struct grpc_chttp2_transport { /** hpack encoding */ grpc_chttp2_hpack_compressor hpack_compressor; /** is this a client? */ - uint8_t is_client; + bool is_client; /** data to write next write */ grpc_slice_buffer qbuf; @@ -350,14 +350,14 @@ struct grpc_chttp2_transport { uint32_t write_buffer_size; /** have we seen a goaway */ - uint8_t seen_goaway; + bool seen_goaway; /** have we sent a goaway */ grpc_chttp2_sent_goaway_state sent_goaway_state; /** are the local settings dirty and need to be sent? */ - uint8_t dirtied_local_settings; + bool dirtied_local_settings; /** have local settings been sent? */ - uint8_t sent_local_settings; + bool sent_local_settings; /** bitmask of setting indexes to send out */ uint32_t force_send_settings; /** settings values */ diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 25c1a5ef056..c6fecf2ee90 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -245,7 +245,8 @@ class WriteContext { void UpdateStreamsNoLongerStalled() { grpc_chttp2_stream *s; while (grpc_chttp2_list_pop_stalled_by_transport(t_, &s)) { - if (!t_->closed && grpc_chttp2_list_add_writable_stream(t_, s)) { + if (t_->closed_with_error == GRPC_ERROR_NONE && + grpc_chttp2_list_add_writable_stream(t_, s)) { if (!stream_ref_if_not_destroyed(&s->refcount->refs)) { grpc_chttp2_list_remove_writable_stream(t_, s); } diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c index eeabc769d38..554d8aa45bd 100644 --- a/test/core/end2end/bad_server_response_test.c +++ b/test/core/end2end/bad_server_response_test.c @@ -62,8 +62,6 @@ #define HTTP2_DETAIL_MSG(STATUS_CODE) \ "Received http2 header with status: " #STATUS_CODE -#define UNPARSEABLE_DETAIL_MSG "Failed parsing HTTP/2" - #define HTTP1_DETAIL_MSG "Trying to connect an http1.x server" /* TODO(zyc) Check the content of incomming data instead of using this length */ @@ -208,8 +206,10 @@ static void start_rpc(int target_port, grpc_status_code expected_status, cq_verify(cqv); GPR_ASSERT(status == expected_status); + if (expected_detail != NULL) { GPR_ASSERT(-1 != grpc_slice_slice(details, grpc_slice_from_static_string( expected_detail))); + } grpc_metadata_array_destroy(&initial_metadata_recv); grpc_metadata_array_destroy(&trailing_metadata_recv); @@ -331,7 +331,7 @@ int main(int argc, char **argv) { /* unparseable response */ run_test(UNPARSEABLE_RESP, sizeof(UNPARSEABLE_RESP) - 1, - GRPC_STATUS_UNAVAILABLE, UNPARSEABLE_DETAIL_MSG); + GRPC_STATUS_UNKNOWN, NULL); /* http1 response */ run_test(HTTP1_RESP, sizeof(HTTP1_RESP) - 1, GRPC_STATUS_UNAVAILABLE, diff --git a/test/core/end2end/tests/bad_ping.c b/test/core/end2end/tests/bad_ping.c index d442f124807..56c76b70d06 100644 --- a/test/core/end2end/tests/bad_ping.c +++ b/test/core/end2end/tests/bad_ping.c @@ -202,8 +202,7 @@ static void test_bad_ping(grpc_end2end_test_config config) { // The connection should be closed immediately after the misbehaved pings, // the in-progress RPC should fail. - GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); - GPR_ASSERT(0 == grpc_slice_str_cmp(details, "Endpoint read failed")); + GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); validate_host_override_string("foo.test.google.fr:1234", call_details.host, config); diff --git a/test/core/end2end/tests/keepalive_timeout.c b/test/core/end2end/tests/keepalive_timeout.c index c4280149c7e..0053368eccf 100644 --- a/test/core/end2end/tests/keepalive_timeout.c +++ b/test/core/end2end/tests/keepalive_timeout.c @@ -193,7 +193,7 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { char *details_str = grpc_slice_to_c_string(details); char *method_str = grpc_slice_to_c_string(call_details.method); - GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + GPR_ASSERT(status == GRPC_STATUS_INTERNAL); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "keepalive watchdog timeout")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); validate_host_override_string("foo.test.google.fr:1234", call_details.host, diff --git a/test/core/end2end/tests/max_connection_age.c b/test/core/end2end/tests/max_connection_age.c index 41190876192..b6daa59d7b2 100644 --- a/test/core/end2end/tests/max_connection_age.c +++ b/test/core/end2end/tests/max_connection_age.c @@ -203,8 +203,7 @@ static void test_max_age_forcibly_close(grpc_end2end_test_config config) { /* The connection should be closed immediately after the max age grace period, the in-progress RPC should fail. */ - GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); - GPR_ASSERT(0 == grpc_slice_str_cmp(details, "Endpoint read failed")); + GPR_ASSERT(status == GRPC_STATUS_INTERNAL); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); validate_host_override_string("foo.test.google.fr:1234", call_details.host, config); diff --git a/test/core/end2end/tests/shutdown_finishes_calls.c b/test/core/end2end/tests/shutdown_finishes_calls.c index cef571b490a..652695cfcd4 100644 --- a/test/core/end2end/tests/shutdown_finishes_calls.c +++ b/test/core/end2end/tests/shutdown_finishes_calls.c @@ -159,7 +159,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( grpc_server_destroy(f.server); - GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + GPR_ASSERT(status == GRPC_STATUS_INTERNAL || status == GRPC_STATUS_UNAVAILABLE); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); validate_host_override_string("foo.test.google.fr:1234", call_details.host, config); From 3305e5c94b890592b77aa36115a5dd98705f5b7f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 11 Oct 2017 18:31:43 -0700 Subject: [PATCH 24/35] Add user-agent test and regex matching test to test suite --- src/objective-c/tests/GRPCClientTests.m | 41 +++++++-- .../tests/Tests.xcodeproj/project.pbxproj | 83 +++++++++++++++++-- src/objective-c/tests/version.h | 27 ++++++ .../src/objective-c/tests/version.h.template | 29 +++++++ 4 files changed, 165 insertions(+), 15 deletions(-) create mode 100644 src/objective-c/tests/version.h create mode 100644 templates/src/objective-c/tests/version.h.template diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 82ac2600fab..4d887fe970a 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -18,6 +18,7 @@ #import #import +#import #import #import @@ -30,6 +31,8 @@ #import #import +#import "version.h" + #define TEST_TIMEOUT 16 static NSString * const kHostAddress = @"localhost:5050"; @@ -266,12 +269,38 @@ static GRPCProtoMethod *kFullDuplexCallMethod; id responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) { XCTAssertNotNil(value, @"nil value received as response."); XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value); - /* This test needs to be more clever in regards to changing the version of the core. - XCTAssertEqualObjects(call.responseHeaders[@"x-grpc-test-echo-useragent"], - @"Foo grpc-objc/0.13.0 grpc-c/0.14.0-dev (ios)", - @"Did not receive expected user agent %@", - call.responseHeaders[@"x-grpc-test-echo-useragent"]); - */ + + NSString *userAgent = call.responseHeaders[@"x-grpc-test-echo-useragent"]; + NSError *error = nil; + + // Test the regex is correct + NSString *expectedUserAgent = @"Foo grpc-objc/"; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING]; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:@" grpc-c/"]; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING]; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "]; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"]; + XCTAssertEqualObjects(userAgent, expectedUserAgent); + + // Change in format of user-agent field in a direction that does not match the regex will likely + // cause problem for certain gRPC users. @muxi for details. + NSRegularExpression *regex = + [NSRegularExpression regularExpressionWithPattern:@" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?" + options:0 + error:&error]; + NSString *customUserAgent = + [regex stringByReplacingMatchesInString:userAgent + options:0 + range:NSMakeRange(0, [userAgent length]) + withTemplate:@""]; + XCTAssertEqualObjects(customUserAgent, @"Foo"); + [response fulfill]; } completionHandler:^(NSError *errorOrNil) { XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil); diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index b01d5ffceaa..2f0c8cfe18e 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -144,6 +144,7 @@ 5EAD6D241E27047400002378 /* CronetUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CronetUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5EAD6D261E27047400002378 /* CronetUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CronetUnitTests.m; sourceTree = ""; }; 5EAD6D281E27047400002378 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EAFE8271F8EFB87007F2189 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = ""; }; 5EE84BF11D4717E40050C6CC /* InteropTestsRemoteWithCronet.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemoteWithCronet.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsRemoteWithCronet.m; sourceTree = ""; }; 5EE84BF51D4717E40050C6CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -398,6 +399,7 @@ 635697C91B14FC11007A7283 /* Tests */ = { isa = PBXGroup; children = ( + 5EAFE8271F8EFB87007F2189 /* version.h */, 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */, 63E240CC1B6C4D3A005F3B0E /* InteropTests.h */, 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */, @@ -740,9 +742,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-resources.sh", + $PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle, ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -755,9 +760,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh", + "${PODS_ROOT}/CronetFramework/Cronet.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -770,13 +778,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTestsRemote-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 4F5690DC0E6AD6663FE78B8B /* [CP] Embed Pods Frameworks */ = { @@ -800,13 +811,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalSSL-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 5F14F59509E10C2852014F9E /* [CP] Embed Pods Frameworks */ = { @@ -830,9 +844,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh", + $PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle, ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -845,9 +862,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-resources.sh", + $PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle, ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -860,13 +880,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalCleartext-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 796680C7599CB4ED736DD62A /* [CP] Check Pods Manifest.lock */ = { @@ -875,13 +898,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Tests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 80E2DDD2EC04A4009F45E933 /* [CP] Check Pods Manifest.lock */ = { @@ -890,13 +916,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-CronetUnitTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 8AD3130D3C58A0FB32FF2A36 /* [CP] Copy Pods Resources */ = { @@ -905,9 +934,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh", + $PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle, ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -935,13 +967,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-AllTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */ = { @@ -950,9 +985,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh", + $PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle, ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -965,9 +1003,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh", + "${PODS_ROOT}/CronetFramework/Cronet.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -995,9 +1036,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh", + $PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle, ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1010,13 +1054,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RxLibraryUnitTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; C0F7B1FF6F88CC5FBF362F4C /* [CP] Check Pods Manifest.lock */ = { @@ -1025,13 +1072,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTestsRemoteWithCronet-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */ = { @@ -1040,9 +1090,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh", + $PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle, ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1070,9 +1123,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh", + $PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle, ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1085,9 +1141,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh", + $PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle, ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1100,9 +1159,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh", + "${PODS_ROOT}/CronetFramework/Cronet.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1115,13 +1177,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-CoreCronetEnd2EndTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h new file mode 100644 index 00000000000..02515063fa1 --- /dev/null +++ b/src/objective-c/tests/version.h @@ -0,0 +1,27 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// This file is autogenerated from a template file. Please make +// modifications to +// `templates/src/objective-c/GRPCClient/private/version.h.template` +// instead. This file can be regenerated from the template by running +// `tools/buildgen/generate_projects.sh`. + + +#define GRPC_OBJC_VERSION_STRING @"1.8.0-dev" +#define GRPC_C_VERSION_STRING @"5.0.0-dev" diff --git a/templates/src/objective-c/tests/version.h.template b/templates/src/objective-c/tests/version.h.template new file mode 100644 index 00000000000..72774ab99ca --- /dev/null +++ b/templates/src/objective-c/tests/version.h.template @@ -0,0 +1,29 @@ +%YAML 1.2 +--- | + /* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + // This file is autogenerated from a template file. Please make + // modifications to + // `templates/src/objective-c/GRPCClient/private/version.h.template` + // instead. This file can be regenerated from the template by running + // `tools/buildgen/generate_projects.sh`. + + + #define GRPC_OBJC_VERSION_STRING @"${settings.version}" + #define GRPC_C_VERSION_STRING @"${settings.core_version}" From d0703a65f17f34ded3556531ea06cd5c005aa0a9 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 11 Oct 2017 20:55:06 -0700 Subject: [PATCH 25/35] Get latency profiles back up and working --- src/core/lib/profiling/basic_timers.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/lib/profiling/basic_timers.cc b/src/core/lib/profiling/basic_timers.cc index ab9d60481cc..0ae7d7f6002 100644 --- a/src/core/lib/profiling/basic_timers.cc +++ b/src/core/lib/profiling/basic_timers.cc @@ -209,9 +209,9 @@ static void init_output() { static void rotate_log() { /* Using malloc here, as this code could end up being called by gpr_malloc */ - gpr_timer_log *new = malloc(sizeof(*new)); + gpr_timer_log *log = static_cast(malloc(sizeof(*log))); gpr_once_init(&g_once_init, init_output); - new->num_entries = 0; + log->num_entries = 0; pthread_mutex_lock(&g_mu); if (g_thread_log != NULL) { timer_log_remove(&g_in_progress_logs, g_thread_log); @@ -221,9 +221,9 @@ static void rotate_log() { } else { g_thread_id = g_next_thread_id++; } - timer_log_push_back(&g_in_progress_logs, new); + timer_log_push_back(&g_in_progress_logs, log); pthread_mutex_unlock(&g_mu); - g_thread_log = new; + g_thread_log = log; } static void gpr_timers_log_add(const char *tagstr, marker_type type, From 4f0cd0e82c425533bef9f7ab8119cc542bcc9a41 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 22 Sep 2017 23:34:43 -0700 Subject: [PATCH 26/35] Add flow control to inproc transport so send needs a matching recv; fix some tests that assumed some sends could always go out --- .../ext/transport/inproc/inproc_transport.cc | 669 ++++++++---------- test/core/end2end/gen_build_yaml.py | 19 +- test/core/end2end/generate_tests.bzl | 20 +- .../end2end/tests/streaming_error_response.c | 1 - test/cpp/end2end/async_end2end_test.cc | 182 +++-- tools/run_tests/generated/tests.json | 92 --- 6 files changed, 445 insertions(+), 538 deletions(-) diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 1001d74c22c..67a8358927c 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -62,96 +62,22 @@ typedef struct inproc_transport { struct inproc_stream *stream_list; } inproc_transport; -typedef struct sb_list_entry { - grpc_slice_buffer sb; - struct sb_list_entry *next; -} sb_list_entry; - -// Specialize grpc_byte_stream for our use case -typedef struct { - grpc_byte_stream base; - sb_list_entry *le; - grpc_error *shutdown_error; -} inproc_slice_byte_stream; - -typedef struct { - // TODO (vjpai): Add some inlined elements to avoid alloc in simple cases - sb_list_entry *head; - sb_list_entry *tail; -} slice_buffer_list; - -static void slice_buffer_list_init(slice_buffer_list *l) { - l->head = NULL; - l->tail = NULL; -} - -static void sb_list_entry_destroy(grpc_exec_ctx *exec_ctx, sb_list_entry *le) { - grpc_slice_buffer_destroy_internal(exec_ctx, &le->sb); - gpr_free(le); -} - -static void slice_buffer_list_destroy(grpc_exec_ctx *exec_ctx, - slice_buffer_list *l) { - sb_list_entry *curr = l->head; - while (curr != NULL) { - sb_list_entry *le = curr; - curr = curr->next; - sb_list_entry_destroy(exec_ctx, le); - } - l->head = NULL; - l->tail = NULL; -} - -static bool slice_buffer_list_empty(slice_buffer_list *l) { - return l->head == NULL; -} - -static void slice_buffer_list_append_entry(slice_buffer_list *l, - sb_list_entry *next) { - next->next = NULL; - if (l->tail) { - l->tail->next = next; - l->tail = next; - } else { - l->head = next; - l->tail = next; - } -} - -static grpc_slice_buffer *slice_buffer_list_append(slice_buffer_list *l) { - sb_list_entry *next = (sb_list_entry *)gpr_malloc(sizeof(*next)); - grpc_slice_buffer_init(&next->sb); - slice_buffer_list_append_entry(l, next); - return &next->sb; -} - -static sb_list_entry *slice_buffer_list_pophead(slice_buffer_list *l) { - sb_list_entry *ret = l->head; - l->head = l->head->next; - if (l->head == NULL) { - l->tail = NULL; - } - return ret; -} - typedef struct inproc_stream { inproc_transport *t; grpc_metadata_batch to_read_initial_md; uint32_t to_read_initial_md_flags; bool to_read_initial_md_filled; - slice_buffer_list to_read_message; grpc_metadata_batch to_read_trailing_md; bool to_read_trailing_md_filled; - bool reads_needed; - bool read_closure_scheduled; - grpc_closure read_closure; + bool ops_needed; + bool op_closure_scheduled; + grpc_closure op_closure; // Write buffer used only during gap at init time when client-side // stream is set up but server side stream is not yet set up grpc_metadata_batch write_buffer_initial_md; bool write_buffer_initial_md_filled; uint32_t write_buffer_initial_md_flags; grpc_millis write_buffer_deadline; - slice_buffer_list write_buffer_message; grpc_metadata_batch write_buffer_trailing_md; bool write_buffer_trailing_md_filled; grpc_error *write_buffer_cancel_error; @@ -164,11 +90,15 @@ typedef struct inproc_stream { gpr_arena *arena; + grpc_transport_stream_op_batch *send_message_op; + grpc_transport_stream_op_batch *send_trailing_md_op; grpc_transport_stream_op_batch *recv_initial_md_op; grpc_transport_stream_op_batch *recv_message_op; grpc_transport_stream_op_batch *recv_trailing_md_op; - inproc_slice_byte_stream recv_message_stream; + grpc_slice_buffer recv_message; + grpc_slice_buffer_stream recv_stream; + bool recv_inited; bool initial_md_sent; bool trailing_md_sent; @@ -187,54 +117,11 @@ typedef struct inproc_stream { struct inproc_stream *stream_list_next; } inproc_stream; -static bool inproc_slice_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *bs, size_t max, - grpc_closure *on_complete) { - // Because inproc transport always provides the entire message atomically, - // the byte stream always has data available when this function is called. - // Thus, this function always returns true (unlike other transports) and - // there is never any need to schedule a closure - return true; -} - -static grpc_error *inproc_slice_byte_stream_pull(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *bs, - grpc_slice *slice) { - inproc_slice_byte_stream *stream = (inproc_slice_byte_stream *)bs; - if (stream->shutdown_error != GRPC_ERROR_NONE) { - return GRPC_ERROR_REF(stream->shutdown_error); - } - *slice = grpc_slice_buffer_take_first(&stream->le->sb); - return GRPC_ERROR_NONE; -} - -static void inproc_slice_byte_stream_shutdown(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *bs, - grpc_error *error) { - inproc_slice_byte_stream *stream = (inproc_slice_byte_stream *)bs; - GRPC_ERROR_UNREF(stream->shutdown_error); - stream->shutdown_error = error; -} - -static void inproc_slice_byte_stream_destroy(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *bs) { - inproc_slice_byte_stream *stream = (inproc_slice_byte_stream *)bs; - sb_list_entry_destroy(exec_ctx, stream->le); - GRPC_ERROR_UNREF(stream->shutdown_error); -} - -static const grpc_byte_stream_vtable inproc_slice_byte_stream_vtable = { - inproc_slice_byte_stream_next, inproc_slice_byte_stream_pull, - inproc_slice_byte_stream_shutdown, inproc_slice_byte_stream_destroy}; - -void inproc_slice_byte_stream_init(inproc_slice_byte_stream *s, - sb_list_entry *le) { - s->base.length = (uint32_t)le->sb.length; - s->base.flags = 0; - s->base.vtable = &inproc_slice_byte_stream_vtable; - s->le = le; - s->shutdown_error = GRPC_ERROR_NONE; -} +static grpc_closure do_nothing_closure; +static bool cancel_stream_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, + grpc_error *error); +static void op_state_machine(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error); static void ref_transport(inproc_transport *t) { INPROC_LOG(GPR_DEBUG, "ref_transport %p", t); @@ -280,12 +167,14 @@ static void unref_stream(grpc_exec_ctx *exec_ctx, inproc_stream *s, static void really_destroy_stream(grpc_exec_ctx *exec_ctx, inproc_stream *s) { INPROC_LOG(GPR_DEBUG, "really_destroy_stream %p", s); - slice_buffer_list_destroy(exec_ctx, &s->to_read_message); - slice_buffer_list_destroy(exec_ctx, &s->write_buffer_message); GRPC_ERROR_UNREF(s->write_buffer_cancel_error); GRPC_ERROR_UNREF(s->cancel_self_error); GRPC_ERROR_UNREF(s->cancel_other_error); + if (s->recv_inited) { + grpc_slice_buffer_destroy_internal(exec_ctx, &s->recv_message); + } + unref_transport(exec_ctx, s->t); if (s->closure_at_destroy) { @@ -293,9 +182,6 @@ static void really_destroy_stream(grpc_exec_ctx *exec_ctx, inproc_stream *s) { } } -static void read_state_machine(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error); - static void log_metadata(const grpc_metadata_batch *md_batch, bool is_client, bool is_initial) { for (grpc_linked_mdelem *md = md_batch->list.head; md != NULL; @@ -359,11 +245,9 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->write_buffer_initial_md_filled = false; grpc_metadata_batch_init(&s->write_buffer_trailing_md); s->write_buffer_trailing_md_filled = false; - slice_buffer_list_init(&s->to_read_message); - slice_buffer_list_init(&s->write_buffer_message); - s->reads_needed = false; - s->read_closure_scheduled = false; - GRPC_CLOSURE_INIT(&s->read_closure, read_state_machine, s, + s->ops_needed = false; + s->op_closure_scheduled = false; + GRPC_CLOSURE_INIT(&s->op_closure, op_state_machine, s, grpc_schedule_on_exec_ctx); s->t = t; s->closure_at_destroy = NULL; @@ -425,11 +309,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_metadata_batch_clear(exec_ctx, &cs->write_buffer_initial_md); cs->write_buffer_initial_md_filled = false; } - while (!slice_buffer_list_empty(&cs->write_buffer_message)) { - slice_buffer_list_append_entry( - &s->to_read_message, - slice_buffer_list_pophead(&cs->write_buffer_message)); - } if (cs->write_buffer_trailing_md_filled) { fill_in_metadata(exec_ctx, s, &cs->write_buffer_trailing_md, 0, &s->to_read_trailing_md, NULL, @@ -488,9 +367,39 @@ static void close_other_side_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, } } +// Call the on_complete closure associated with this stream_op_batch if +// this stream_op_batch is only one of the pending operations for this +// stream. This is called when one of the pending operations for the stream +// is done and about to be NULLed out +static void complete_if_batch_end_locked(grpc_exec_ctx *exec_ctx, + inproc_stream *s, grpc_error *error, + grpc_transport_stream_op_batch *op, + const char *msg) { + int is_sm = (int)(op == s->send_message_op); + int is_stm = (int)(op == s->send_trailing_md_op); + int is_rim = (int)(op == s->recv_initial_md_op); + int is_rm = (int)(op == s->recv_message_op); + int is_rtm = (int)(op == s->recv_trailing_md_op); + + if ((is_sm + is_stm + is_rim + is_rm + is_rtm) == 1) { + INPROC_LOG(GPR_DEBUG, "%s %p %p %p", msg, s, op, error); + GRPC_CLOSURE_SCHED(exec_ctx, op->on_complete, GRPC_ERROR_REF(error)); + } +} + +static void maybe_schedule_op_closure_locked(grpc_exec_ctx *exec_ctx, + inproc_stream *s, + grpc_error *error) { + if (s && s->ops_needed && !s->op_closure_scheduled) { + GRPC_CLOSURE_SCHED(exec_ctx, &s->op_closure, GRPC_ERROR_REF(error)); + s->op_closure_scheduled = true; + s->ops_needed = false; + } +} + static void fail_helper_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, grpc_error *error) { - INPROC_LOG(GPR_DEBUG, "read_state_machine %p fail_helper", s); + INPROC_LOG(GPR_DEBUG, "op_state_machine %p fail_helper", s); // If we're failing this side, we need to make sure that // we also send or have already sent trailing metadata if (!s->trailing_md_sent) { @@ -512,14 +421,7 @@ static void fail_helper_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, if (other->cancel_other_error == GRPC_ERROR_NONE) { other->cancel_other_error = GRPC_ERROR_REF(error); } - if (other->reads_needed) { - if (!other->read_closure_scheduled) { - GRPC_CLOSURE_SCHED(exec_ctx, &other->read_closure, - GRPC_ERROR_REF(error)); - other->read_closure_scheduled = true; - } - other->reads_needed = false; - } + maybe_schedule_op_closure_locked(exec_ctx, other, error); } else if (s->write_buffer_cancel_error == GRPC_ERROR_NONE) { s->write_buffer_cancel_error = GRPC_ERROR_REF(error); } @@ -564,14 +466,9 @@ static void fail_helper_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, err); // Last use of err so no need to REF and then UNREF it - if ((s->recv_initial_md_op != s->recv_message_op) && - (s->recv_initial_md_op != s->recv_trailing_md_op)) { - INPROC_LOG(GPR_DEBUG, - "fail_helper %p scheduling initial-metadata-on-complete %p", - error, s); - GRPC_CLOSURE_SCHED(exec_ctx, s->recv_initial_md_op->on_complete, - GRPC_ERROR_REF(error)); - } + complete_if_batch_end_locked( + exec_ctx, s, error, s->recv_initial_md_op, + "fail_helper scheduling recv-initial-metadata-on-complete"); s->recv_initial_md_op = NULL; } if (s->recv_message_op) { @@ -580,20 +477,30 @@ static void fail_helper_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, GRPC_CLOSURE_SCHED( exec_ctx, s->recv_message_op->payload->recv_message.recv_message_ready, GRPC_ERROR_REF(error)); - if (s->recv_message_op != s->recv_trailing_md_op) { - INPROC_LOG(GPR_DEBUG, "fail_helper %p scheduling message-on-complete %p", - s, error); - GRPC_CLOSURE_SCHED(exec_ctx, s->recv_message_op->on_complete, - GRPC_ERROR_REF(error)); - } + complete_if_batch_end_locked( + exec_ctx, s, error, s->recv_message_op, + "fail_helper scheduling recv-message-on-complete"); s->recv_message_op = NULL; } + if (s->send_message_op) { + complete_if_batch_end_locked( + exec_ctx, s, error, s->send_message_op, + "fail_helper scheduling send-message-on-complete"); + s->send_message_op = NULL; + } + if (s->send_trailing_md_op) { + complete_if_batch_end_locked( + exec_ctx, s, error, s->send_trailing_md_op, + "fail_helper scheduling send-trailng-md-on-complete"); + s->send_trailing_md_op = NULL; + } if (s->recv_trailing_md_op) { INPROC_LOG(GPR_DEBUG, "fail_helper %p scheduling trailing-md-on-complete %p", s, error); - GRPC_CLOSURE_SCHED(exec_ctx, s->recv_trailing_md_op->on_complete, - GRPC_ERROR_REF(error)); + complete_if_batch_end_locked( + exec_ctx, s, error, s->recv_trailing_md_op, + "fail_helper scheduling recv-trailing-metadata-on-complete"); s->recv_trailing_md_op = NULL; } close_other_side_locked(exec_ctx, s, "fail_helper:other_side"); @@ -602,12 +509,61 @@ static void fail_helper_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, GRPC_ERROR_UNREF(error); } -static void read_state_machine(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error) { +static void message_transfer_locked(grpc_exec_ctx *exec_ctx, + inproc_stream *sender, + inproc_stream *receiver) { + size_t remaining = + sender->send_message_op->payload->send_message.send_message->length; + if (receiver->recv_inited) { + grpc_slice_buffer_destroy_internal(exec_ctx, &receiver->recv_message); + } + grpc_slice_buffer_init(&receiver->recv_message); + receiver->recv_inited = true; + do { + grpc_slice message_slice; + grpc_closure unused; + GPR_ASSERT(grpc_byte_stream_next( + exec_ctx, sender->send_message_op->payload->send_message.send_message, + SIZE_MAX, &unused)); + grpc_error *error = grpc_byte_stream_pull( + exec_ctx, sender->send_message_op->payload->send_message.send_message, + &message_slice); + if (error != GRPC_ERROR_NONE) { + cancel_stream_locked(exec_ctx, sender, GRPC_ERROR_REF(error)); + break; + } + GPR_ASSERT(error == GRPC_ERROR_NONE); + remaining -= GRPC_SLICE_LENGTH(message_slice); + grpc_slice_buffer_add(&receiver->recv_message, message_slice); + } while (remaining > 0); + + grpc_slice_buffer_stream_init(&receiver->recv_stream, &receiver->recv_message, + 0); + *receiver->recv_message_op->payload->recv_message.recv_message = + &receiver->recv_stream.base; + INPROC_LOG(GPR_DEBUG, "message_transfer_locked %p scheduling message-ready", + receiver); + GRPC_CLOSURE_SCHED( + exec_ctx, + receiver->recv_message_op->payload->recv_message.recv_message_ready, + GRPC_ERROR_NONE); + complete_if_batch_end_locked( + exec_ctx, sender, GRPC_ERROR_NONE, sender->send_message_op, + "message_transfer scheduling sender on_complete"); + complete_if_batch_end_locked( + exec_ctx, receiver, GRPC_ERROR_NONE, receiver->recv_message_op, + "message_transfer scheduling receiver on_complete"); + + receiver->recv_message_op = NULL; + sender->send_message_op = NULL; +} + +static void op_state_machine(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { // This function gets called when we have contents in the unprocessed reads // Get what we want based on our ops wanted // Schedule our appropriate closures - // and then return to reads_needed state if still needed + // and then return to ops_needed state if still needed // Since this is a closure directly invoked by the combiner, it should not // unref the error parameter explicitly; the combiner will do that implicitly @@ -615,12 +571,14 @@ static void read_state_machine(grpc_exec_ctx *exec_ctx, void *arg, bool needs_close = false; - INPROC_LOG(GPR_DEBUG, "read_state_machine %p", arg); + INPROC_LOG(GPR_DEBUG, "op_state_machine %p", arg); inproc_stream *s = (inproc_stream *)arg; gpr_mu *mu = &s->t->mu->mu; // keep aside in case s gets closed gpr_mu_lock(mu); - s->read_closure_scheduled = false; + s->op_closure_scheduled = false; // cancellation takes precedence + inproc_stream *other = s->other_side; + if (s->cancel_self_error != GRPC_ERROR_NONE) { fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(s->cancel_self_error)); goto done; @@ -632,89 +590,116 @@ static void read_state_machine(grpc_exec_ctx *exec_ctx, void *arg, goto done; } - if (s->recv_initial_md_op) { - if (!s->to_read_initial_md_filled) { - // We entered the state machine on some other kind of read even though - // we still haven't satisfied initial md . That's an error. - new_err = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unexpected frame sequencing"); - INPROC_LOG(GPR_DEBUG, - "read_state_machine %p scheduling on_complete errors for no " - "initial md %p", - s, new_err); + if (s->send_message_op && other) { + if (other->recv_message_op) { + message_transfer_locked(exec_ctx, s, other); + maybe_schedule_op_closure_locked(exec_ctx, other, GRPC_ERROR_NONE); + } else if (!s->t->is_client && + (s->trailing_md_sent || other->recv_trailing_md_op)) { + // A server send will never be matched if the client is waiting + // for trailing metadata already + complete_if_batch_end_locked( + exec_ctx, s, GRPC_ERROR_NONE, s->send_message_op, + "op_state_machine scheduling send-message-on-complete"); + s->send_message_op = NULL; + } + } + // Pause a send trailing metadata if there is still an outstanding + // send message unless we know that the send message will never get + // matched to a receive. This happens on the client if the server has + // already sent status. + if (s->send_trailing_md_op && + (!s->send_message_op || + (s->t->is_client && + (s->trailing_md_recvd || s->to_read_trailing_md_filled)))) { + grpc_metadata_batch *dest = (other == NULL) ? &s->write_buffer_trailing_md + : &other->to_read_trailing_md; + bool *destfilled = (other == NULL) ? &s->write_buffer_trailing_md_filled + : &other->to_read_trailing_md_filled; + if (*destfilled || s->trailing_md_sent) { + // The buffer is already in use; that's an error! + INPROC_LOG(GPR_DEBUG, "Extra trailing metadata %p", s); + new_err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Extra trailing metadata"); fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(new_err)); goto done; - } else if (s->initial_md_recvd) { + } else { + if (other && !other->closed) { + fill_in_metadata(exec_ctx, s, + s->send_trailing_md_op->payload->send_trailing_metadata + .send_trailing_metadata, + 0, dest, NULL, destfilled); + } + s->trailing_md_sent = true; + if (!s->t->is_client && s->trailing_md_recvd && s->recv_trailing_md_op) { + INPROC_LOG(GPR_DEBUG, + "op_state_machine %p scheduling trailing-md-on-complete", s); + GRPC_CLOSURE_SCHED(exec_ctx, s->recv_trailing_md_op->on_complete, + GRPC_ERROR_NONE); + s->recv_trailing_md_op = NULL; + needs_close = true; + } + } + maybe_schedule_op_closure_locked(exec_ctx, other, GRPC_ERROR_NONE); + complete_if_batch_end_locked( + exec_ctx, s, GRPC_ERROR_NONE, s->send_trailing_md_op, + "op_state_machine scheduling send-trailing-metadata-on-complete"); + s->send_trailing_md_op = NULL; + } + if (s->recv_initial_md_op) { + if (s->initial_md_recvd) { new_err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Already recvd initial md"); INPROC_LOG( GPR_DEBUG, - "read_state_machine %p scheduling on_complete errors for already " + "op_state_machine %p scheduling on_complete errors for already " "recvd initial md %p", s, new_err); fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(new_err)); goto done; } - s->initial_md_recvd = true; - new_err = fill_in_metadata( - exec_ctx, s, &s->to_read_initial_md, s->to_read_initial_md_flags, - s->recv_initial_md_op->payload->recv_initial_metadata - .recv_initial_metadata, - s->recv_initial_md_op->payload->recv_initial_metadata.recv_flags, NULL); - s->recv_initial_md_op->payload->recv_initial_metadata.recv_initial_metadata - ->deadline = s->deadline; - grpc_metadata_batch_clear(exec_ctx, &s->to_read_initial_md); - s->to_read_initial_md_filled = false; - INPROC_LOG(GPR_DEBUG, - "read_state_machine %p scheduling initial-metadata-ready %p", s, - new_err); - GRPC_CLOSURE_SCHED(exec_ctx, - s->recv_initial_md_op->payload->recv_initial_metadata - .recv_initial_metadata_ready, - GRPC_ERROR_REF(new_err)); - if ((s->recv_initial_md_op != s->recv_message_op) && - (s->recv_initial_md_op != s->recv_trailing_md_op)) { - INPROC_LOG( - GPR_DEBUG, - "read_state_machine %p scheduling initial-metadata-on-complete %p", s, - new_err); - GRPC_CLOSURE_SCHED(exec_ctx, s->recv_initial_md_op->on_complete, - GRPC_ERROR_REF(new_err)); - } - s->recv_initial_md_op = NULL; - - if (new_err != GRPC_ERROR_NONE) { + if (s->to_read_initial_md_filled) { + s->initial_md_recvd = true; + new_err = fill_in_metadata( + exec_ctx, s, &s->to_read_initial_md, s->to_read_initial_md_flags, + s->recv_initial_md_op->payload->recv_initial_metadata + .recv_initial_metadata, + s->recv_initial_md_op->payload->recv_initial_metadata.recv_flags, + NULL); + s->recv_initial_md_op->payload->recv_initial_metadata + .recv_initial_metadata->deadline = s->deadline; + grpc_metadata_batch_clear(exec_ctx, &s->to_read_initial_md); + s->to_read_initial_md_filled = false; INPROC_LOG(GPR_DEBUG, - "read_state_machine %p scheduling on_complete errors2 %p", s, + "op_state_machine %p scheduling initial-metadata-ready %p", s, new_err); - fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(new_err)); - goto done; + GRPC_CLOSURE_SCHED(exec_ctx, + s->recv_initial_md_op->payload->recv_initial_metadata + .recv_initial_metadata_ready, + GRPC_ERROR_REF(new_err)); + complete_if_batch_end_locked( + exec_ctx, s, new_err, s->recv_initial_md_op, + "op_state_machine scheduling recv-initial-metadata-on-complete"); + s->recv_initial_md_op = NULL; + + if (new_err != GRPC_ERROR_NONE) { + INPROC_LOG(GPR_DEBUG, + "op_state_machine %p scheduling on_complete errors2 %p", s, + new_err); + fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(new_err)); + goto done; + } } } - if (s->to_read_initial_md_filled) { - new_err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unexpected recv frame"); - fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(new_err)); - goto done; - } - if (!slice_buffer_list_empty(&s->to_read_message) && s->recv_message_op) { - inproc_slice_byte_stream_init( - &s->recv_message_stream, - slice_buffer_list_pophead(&s->to_read_message)); - *s->recv_message_op->payload->recv_message.recv_message = - &s->recv_message_stream.base; - INPROC_LOG(GPR_DEBUG, "read_state_machine %p scheduling message-ready", s); - GRPC_CLOSURE_SCHED( - exec_ctx, s->recv_message_op->payload->recv_message.recv_message_ready, - GRPC_ERROR_NONE); - if (s->recv_message_op != s->recv_trailing_md_op) { - INPROC_LOG(GPR_DEBUG, - "read_state_machine %p scheduling message-on-complete %p", s, - new_err); - GRPC_CLOSURE_SCHED(exec_ctx, s->recv_message_op->on_complete, - GRPC_ERROR_REF(new_err)); + if (s->recv_message_op) { + if (other && other->send_message_op) { + message_transfer_locked(exec_ctx, other, s); + maybe_schedule_op_closure_locked(exec_ctx, other, GRPC_ERROR_NONE); } - s->recv_message_op = NULL; + } + if (s->recv_trailing_md_op && s->t->is_client && other && + other->send_message_op) { + maybe_schedule_op_closure_locked(exec_ctx, other, GRPC_ERROR_NONE); } if (s->to_read_trailing_md_filled) { if (s->trailing_md_recvd) { @@ -722,7 +707,7 @@ static void read_state_machine(grpc_exec_ctx *exec_ctx, void *arg, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Already recvd trailing md"); INPROC_LOG( GPR_DEBUG, - "read_state_machine %p scheduling on_complete errors for already " + "op_state_machine %p scheduling on_complete errors for already " "recvd trailing md %p", s, new_err); fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(new_err)); @@ -731,21 +716,24 @@ static void read_state_machine(grpc_exec_ctx *exec_ctx, void *arg, if (s->recv_message_op != NULL) { // This message needs to be wrapped up because it will never be // satisfied - INPROC_LOG(GPR_DEBUG, "read_state_machine %p scheduling message-ready", - s); + INPROC_LOG(GPR_DEBUG, "op_state_machine %p scheduling message-ready", s); GRPC_CLOSURE_SCHED( exec_ctx, s->recv_message_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); - if (s->recv_message_op != s->recv_trailing_md_op) { - INPROC_LOG(GPR_DEBUG, - "read_state_machine %p scheduling message-on-complete %p", s, - new_err); - GRPC_CLOSURE_SCHED(exec_ctx, s->recv_message_op->on_complete, - GRPC_ERROR_REF(new_err)); - } + complete_if_batch_end_locked( + exec_ctx, s, new_err, s->recv_message_op, + "op_state_machine scheduling recv-message-on-complete"); s->recv_message_op = NULL; } + if ((s->trailing_md_sent || s->t->is_client) && s->send_message_op) { + // Nothing further will try to receive from this stream, so finish off + // any outstanding send_message op + complete_if_batch_end_locked( + exec_ctx, s, new_err, s->send_message_op, + "op_state_machine scheduling send-message-on-complete"); + s->send_message_op = NULL; + } if (s->recv_trailing_md_op != NULL) { // We wanted trailing metadata and we got it s->trailing_md_recvd = true; @@ -763,61 +751,65 @@ static void read_state_machine(grpc_exec_ctx *exec_ctx, void *arg, // (If the server hasn't already sent its trailing md, it doesn't have // a final status, so don't mark this op complete) if (s->t->is_client || s->trailing_md_sent) { - INPROC_LOG( - GPR_DEBUG, - "read_state_machine %p scheduling trailing-md-on-complete %p", s, - new_err); + INPROC_LOG(GPR_DEBUG, + "op_state_machine %p scheduling trailing-md-on-complete %p", + s, new_err); GRPC_CLOSURE_SCHED(exec_ctx, s->recv_trailing_md_op->on_complete, GRPC_ERROR_REF(new_err)); s->recv_trailing_md_op = NULL; needs_close = true; } else { INPROC_LOG(GPR_DEBUG, - "read_state_machine %p server needs to delay handling " + "op_state_machine %p server needs to delay handling " "trailing-md-on-complete %p", s, new_err); } } else { INPROC_LOG( GPR_DEBUG, - "read_state_machine %p has trailing md but not yet waiting for it", - s); + "op_state_machine %p has trailing md but not yet waiting for it", s); } } if (s->trailing_md_recvd && s->recv_message_op) { // No further message will come on this stream, so finish off the // recv_message_op - INPROC_LOG(GPR_DEBUG, "read_state_machine %p scheduling message-ready", s); + INPROC_LOG(GPR_DEBUG, "op_state_machine %p scheduling message-ready", s); GRPC_CLOSURE_SCHED( exec_ctx, s->recv_message_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); - if (s->recv_message_op != s->recv_trailing_md_op) { - INPROC_LOG(GPR_DEBUG, - "read_state_machine %p scheduling message-on-complete %p", s, - new_err); - GRPC_CLOSURE_SCHED(exec_ctx, s->recv_message_op->on_complete, - GRPC_ERROR_REF(new_err)); - } + complete_if_batch_end_locked( + exec_ctx, s, new_err, s->recv_message_op, + "op_state_machine scheduling recv-message-on-complete"); s->recv_message_op = NULL; } - if (s->recv_message_op || s->recv_trailing_md_op) { + if (s->trailing_md_recvd && (s->trailing_md_sent || s->t->is_client) && + s->send_message_op) { + // Nothing further will try to receive from this stream, so finish off + // any outstanding send_message op + complete_if_batch_end_locked( + exec_ctx, s, new_err, s->send_message_op, + "op_state_machine scheduling send-message-on-complete"); + s->send_message_op = NULL; + } + if (s->send_message_op || s->send_trailing_md_op || s->recv_initial_md_op || + s->recv_message_op || s->recv_trailing_md_op) { // Didn't get the item we wanted so we still need to get // rescheduled - INPROC_LOG(GPR_DEBUG, "read_state_machine %p still needs closure %p %p", s, - s->recv_message_op, s->recv_trailing_md_op); - s->reads_needed = true; + INPROC_LOG( + GPR_DEBUG, "op_state_machine %p still needs closure %p %p %p %p %p", s, + s->send_message_op, s->send_trailing_md_op, s->recv_initial_md_op, + s->recv_message_op, s->recv_trailing_md_op); + s->ops_needed = true; } done: if (needs_close) { - close_other_side_locked(exec_ctx, s, "read_state_machine"); + close_other_side_locked(exec_ctx, s, "op_state_machine"); close_stream_locked(exec_ctx, s); } gpr_mu_unlock(mu); GRPC_ERROR_UNREF(new_err); } -static grpc_closure do_nothing_closure; - static bool cancel_stream_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, grpc_error *error) { bool ret = false; // was the cancel accepted @@ -826,14 +818,7 @@ static bool cancel_stream_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, if (s->cancel_self_error == GRPC_ERROR_NONE) { ret = true; s->cancel_self_error = GRPC_ERROR_REF(error); - if (s->reads_needed) { - if (!s->read_closure_scheduled) { - GRPC_CLOSURE_SCHED(exec_ctx, &s->read_closure, - GRPC_ERROR_REF(s->cancel_self_error)); - s->read_closure_scheduled = true; - } - s->reads_needed = false; - } + maybe_schedule_op_closure_locked(exec_ctx, s, s->cancel_self_error); // Send trailing md to the other side indicating cancellation, even if we // already have s->trailing_md_sent = true; @@ -853,14 +838,8 @@ static bool cancel_stream_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, if (other->cancel_other_error == GRPC_ERROR_NONE) { other->cancel_other_error = GRPC_ERROR_REF(s->cancel_self_error); } - if (other->reads_needed) { - if (!other->read_closure_scheduled) { - GRPC_CLOSURE_SCHED(exec_ctx, &other->read_closure, - GRPC_ERROR_REF(other->cancel_other_error)); - other->read_closure_scheduled = true; - } - other->reads_needed = false; - } + maybe_schedule_op_closure_locked(exec_ctx, other, + other->cancel_other_error); } else if (s->write_buffer_cancel_error == GRPC_ERROR_NONE) { s->write_buffer_cancel_error = GRPC_ERROR_REF(s->cancel_self_error); } @@ -869,11 +848,9 @@ static bool cancel_stream_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s, // couldn't complete that because we hadn't yet sent out trailing // md, now's the chance if (!s->t->is_client && s->trailing_md_recvd && s->recv_trailing_md_op) { - INPROC_LOG(GPR_DEBUG, - "cancel_stream %p scheduling trailing-md-on-complete %p", s, - s->cancel_self_error); - GRPC_CLOSURE_SCHED(exec_ctx, s->recv_trailing_md_op->on_complete, - GRPC_ERROR_REF(s->cancel_self_error)); + complete_if_batch_end_locked( + exec_ctx, s, s->cancel_self_error, s->recv_trailing_md_op, + "cancel_stream scheduling trailing-md-on-complete"); s->recv_trailing_md_op = NULL; } } @@ -918,7 +895,8 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, // already self-canceled so still give it an error error = GRPC_ERROR_REF(s->cancel_self_error); } else { - INPROC_LOG(GPR_DEBUG, "perform_stream_op %p%s%s%s%s%s%s", s, + INPROC_LOG(GPR_DEBUG, "perform_stream_op %p %s%s%s%s%s%s%s", s, + s->t->is_client ? "client" : "server", op->send_initial_metadata ? " send_initial_metadata" : "", op->send_message ? " send_message" : "", op->send_trailing_metadata ? " send_trailing_metadata" : "", @@ -929,10 +907,9 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, bool needs_close = false; + inproc_stream *other = s->other_side; if (error == GRPC_ERROR_NONE && - (op->send_initial_metadata || op->send_message || - op->send_trailing_metadata)) { - inproc_stream *other = s->other_side; + (op->send_initial_metadata || op->send_trailing_metadata)) { if (s->t->is_closed) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Endpoint already shutdown"); } @@ -963,72 +940,21 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->initial_md_sent = true; } } - } - if (error == GRPC_ERROR_NONE && op->send_message) { - size_t remaining = op->payload->send_message.send_message->length; - grpc_slice_buffer *dest = slice_buffer_list_append( - (other == NULL) ? &s->write_buffer_message : &other->to_read_message); - do { - grpc_slice message_slice; - grpc_closure unused; - GPR_ASSERT(grpc_byte_stream_next(exec_ctx, - op->payload->send_message.send_message, - SIZE_MAX, &unused)); - error = grpc_byte_stream_pull( - exec_ctx, op->payload->send_message.send_message, &message_slice); - if (error != GRPC_ERROR_NONE) { - cancel_stream_locked(exec_ctx, s, GRPC_ERROR_REF(error)); - break; - } - GPR_ASSERT(error == GRPC_ERROR_NONE); - remaining -= GRPC_SLICE_LENGTH(message_slice); - grpc_slice_buffer_add(dest, message_slice); - } while (remaining != 0); - grpc_byte_stream_destroy(exec_ctx, - op->payload->send_message.send_message); - } - if (error == GRPC_ERROR_NONE && op->send_trailing_metadata) { - grpc_metadata_batch *dest = (other == NULL) ? &s->write_buffer_trailing_md - : &other->to_read_trailing_md; - bool *destfilled = (other == NULL) ? &s->write_buffer_trailing_md_filled - : &other->to_read_trailing_md_filled; - if (*destfilled || s->trailing_md_sent) { - // The buffer is already in use; that's an error! - INPROC_LOG(GPR_DEBUG, "Extra trailing metadata %p", s); - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Extra trailing metadata"); - } else { - if (!other->closed) { - fill_in_metadata( - exec_ctx, s, - op->payload->send_trailing_metadata.send_trailing_metadata, 0, - dest, NULL, destfilled); - } - s->trailing_md_sent = true; - if (!s->t->is_client && s->trailing_md_recvd && - s->recv_trailing_md_op) { - INPROC_LOG(GPR_DEBUG, - "perform_stream_op %p scheduling trailing-md-on-complete", - s); - GRPC_CLOSURE_SCHED(exec_ctx, s->recv_trailing_md_op->on_complete, - GRPC_ERROR_NONE); - s->recv_trailing_md_op = NULL; - needs_close = true; - } - } - } - if (other != NULL && other->reads_needed) { - if (!other->read_closure_scheduled) { - GRPC_CLOSURE_SCHED(exec_ctx, &other->read_closure, error); - other->read_closure_scheduled = true; - } - other->reads_needed = false; + maybe_schedule_op_closure_locked(exec_ctx, other, error); } } + if (error == GRPC_ERROR_NONE && - (op->recv_initial_metadata || op->recv_message || + (op->send_message || op->send_trailing_metadata || + op->recv_initial_metadata || op->recv_message || op->recv_trailing_metadata)) { - // If there are any reads, mark it so that the read closure will react to - // them + // Mark ops that need to be processed by the closure + if (op->send_message) { + s->send_message_op = op; + } + if (op->send_trailing_metadata) { + s->send_trailing_md_op = op; + } if (op->recv_initial_metadata) { s->recv_initial_md_op = op; } @@ -1040,25 +966,28 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, } // We want to initiate the closure if: - // 1. There is initial metadata and something ready to take that - // 2. There is a message and something ready to take it - // 3. There is trailing metadata, even if nothing specifically wants - // that because that can shut down the message as well - if ((s->to_read_initial_md_filled && op->recv_initial_metadata) || - ((!slice_buffer_list_empty(&s->to_read_message) || - s->trailing_md_recvd) && - op->recv_message) || - (s->to_read_trailing_md_filled)) { - if (!s->read_closure_scheduled) { - GRPC_CLOSURE_SCHED(exec_ctx, &s->read_closure, GRPC_ERROR_NONE); - s->read_closure_scheduled = true; + // 1. We want to send a message and the other side wants to receive or end + // 2. We want to send trailing metadata and there isn't an unmatched send + // 3. We want initial metadata and the other side has sent it + // 4. We want to receive a message and there is a message ready + // 5. There is trailing metadata, even if nothing specifically wants + // that because that can shut down the receive message as well + if ((op->send_message && other && ((other->recv_message_op != NULL) || + (other->recv_trailing_md_op != NULL))) || + (op->send_trailing_metadata && !op->send_message) || + (op->recv_initial_metadata && s->to_read_initial_md_filled) || + (op->recv_message && (other && other->send_message_op != NULL)) || + (s->to_read_trailing_md_filled || s->trailing_md_recvd)) { + if (!s->op_closure_scheduled) { + GRPC_CLOSURE_SCHED(exec_ctx, &s->op_closure, GRPC_ERROR_NONE); + s->op_closure_scheduled = true; } } else { - s->reads_needed = true; + s->ops_needed = true; } } else { if (error != GRPC_ERROR_NONE) { - // Schedule op's read closures that we didn't push to read state machine + // Schedule op's closures that we didn't push to op state machine if (op->recv_initial_metadata) { INPROC_LOG( GPR_DEBUG, diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index e1dc69994c4..f7f996d5c19 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -24,15 +24,15 @@ import hashlib FixtureOptions = collections.namedtuple( 'FixtureOptions', - 'fullstack includes_proxy dns_resolver name_resolution secure platforms ci_mac tracing exclude_configs exclude_iomgrs large_writes enables_compression supports_compression is_inproc is_http2 supports_proxy_auth') + 'fullstack includes_proxy dns_resolver name_resolution secure platforms ci_mac tracing exclude_configs exclude_iomgrs large_writes enables_compression supports_compression is_inproc is_http2 supports_proxy_auth supports_write_buffering') default_unsecure_fixture_options = FixtureOptions( - True, False, True, True, False, ['windows', 'linux', 'mac', 'posix'], True, False, [], [], True, False, True, False, True, False) + True, False, True, True, False, ['windows', 'linux', 'mac', 'posix'], True, False, [], [], True, False, True, False, True, False, True) socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace(fullstack=False, dns_resolver=False) default_secure_fixture_options = default_unsecure_fixture_options._replace(secure=True) uds_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv']) fd_unsecure_fixture_options = default_unsecure_fixture_options._replace( dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv']) -inproc_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, fullstack=False, name_resolution=False, supports_compression=False, is_inproc=True, is_http2=False) +inproc_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, fullstack=False, name_resolution=False, supports_compression=False, is_inproc=True, is_http2=False, supports_write_buffering=False) # maps fixture name to whether it requires the security library END2END_FIXTURES = { @@ -68,8 +68,8 @@ END2END_FIXTURES = { TestOptions = collections.namedtuple( 'TestOptions', - 'needs_fullstack needs_dns needs_names proxyable secure traceable cpu_cost exclude_iomgrs large_writes flaky allows_compression needs_compression exclude_inproc needs_http2 needs_proxy_auth') -default_test_options = TestOptions(False, False, False, True, False, True, 1.0, [], False, False, True, False, False, False, False) + 'needs_fullstack needs_dns needs_names proxyable secure traceable cpu_cost exclude_iomgrs large_writes flaky allows_compression needs_compression exclude_inproc needs_http2 needs_proxy_auth needs_write_buffering') +default_test_options = TestOptions(False, False, False, True, False, True, 1.0, [], False, False, True, False, False, False, False, False) connectivity_test_options = default_test_options._replace(needs_fullstack=True) LOWCPU = 0.1 @@ -146,8 +146,10 @@ END2END_TESTS = { 'streaming_error_response': default_test_options._replace(cpu_cost=LOWCPU), 'trailing_metadata': default_test_options, 'workaround_cronet_compression': default_test_options, - 'write_buffering': default_test_options._replace(cpu_cost=LOWCPU), - 'write_buffering_at_end': default_test_options._replace(cpu_cost=LOWCPU), + 'write_buffering': default_test_options._replace(cpu_cost=LOWCPU, + needs_write_buffering=True), + 'write_buffering_at_end': default_test_options._replace(cpu_cost=LOWCPU, + needs_write_buffering=True), } @@ -185,6 +187,9 @@ def compatible(f, t): if END2END_TESTS[t].needs_proxy_auth: if not END2END_FIXTURES[f].supports_proxy_auth: return False + if END2END_TESTS[t].needs_write_buffering: + if not END2END_FIXTURES[f].supports_write_buffering: + return False return True diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index d48ddb46064..89a95edfd7b 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -21,7 +21,8 @@ load("//bazel:grpc_build_system.bzl", "grpc_sh_test", "grpc_cc_binary", "grpc_cc def fixture_options(fullstack=True, includes_proxy=False, dns_resolver=True, name_resolution=True, secure=True, tracing=False, platforms=['windows', 'linux', 'mac', 'posix'], - is_inproc=False, is_http2=True, supports_proxy_auth=False): + is_inproc=False, is_http2=True, supports_proxy_auth=False, + supports_write_buffering=True): return struct( fullstack=fullstack, includes_proxy=includes_proxy, @@ -31,7 +32,8 @@ def fixture_options(fullstack=True, includes_proxy=False, dns_resolver=True, tracing=tracing, is_inproc=is_inproc, is_http2=is_http2, - supports_proxy_auth=supports_proxy_auth + supports_proxy_auth=supports_proxy_auth, + supports_write_buffering=supports_write_buffering #platforms=platforms ) @@ -61,14 +63,14 @@ END2END_FIXTURES = { platforms=['linux', 'mac', 'posix']), 'inproc': fixture_options(fullstack=False, dns_resolver=False, name_resolution=False, is_inproc=True, - is_http2=False), + is_http2=False, supports_write_buffering=False), } def test_options(needs_fullstack=False, needs_dns=False, needs_names=False, proxyable=True, secure=False, traceable=False, exclude_inproc=False, needs_http2=False, - needs_proxy_auth=False): + needs_proxy_auth=False, needs_write_buffering=False): return struct( needs_fullstack=needs_fullstack, needs_dns=needs_dns, @@ -78,7 +80,8 @@ def test_options(needs_fullstack=False, needs_dns=False, needs_names=False, traceable=traceable, exclude_inproc=exclude_inproc, needs_http2=needs_http2, - needs_proxy_auth=needs_proxy_auth + needs_proxy_auth=needs_proxy_auth, + needs_write_buffering=needs_write_buffering ) @@ -144,8 +147,8 @@ END2END_TESTS = { 'authority_not_supported': test_options(), 'filter_latency': test_options(), 'workaround_cronet_compression': test_options(), - 'write_buffering': test_options(), - 'write_buffering_at_end': test_options(), + 'write_buffering': test_options(needs_write_buffering=True), + 'write_buffering_at_end': test_options(needs_write_buffering=True), } @@ -174,6 +177,9 @@ def compatible(fopt, topt): if topt.needs_proxy_auth: if not fopt.supports_proxy_auth: return False + if topt.needs_write_buffering: + if not fopt.supports_write_buffering: + return False return True diff --git a/test/core/end2end/tests/streaming_error_response.c b/test/core/end2end/tests/streaming_error_response.c index 9d562b90906..8891b8674ce 100644 --- a/test/core/end2end/tests/streaming_error_response.c +++ b/test/core/end2end/tests/streaming_error_response.c @@ -183,7 +183,6 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); - cq_verify(cqv); if (!request_status_early) { memset(ops, 0, sizeof(ops)); diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index a14b4d5295c..2a33e8ae115 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -1304,7 +1304,6 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { ServerTryCancelRequestPhase server_try_cancel) { ResetStub(); - EchoRequest send_request; EchoRequest recv_request; EchoResponse send_response; EchoResponse recv_response; @@ -1315,31 +1314,24 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { ServerAsyncReader srv_stream(&srv_ctx); // Initiate the 'RequestStream' call on client + CompletionQueue cli_cq; + std::unique_ptr> cli_stream( - stub_->AsyncRequestStream(&cli_ctx, &recv_response, cq_.get(), tag(1))); - Verifier(GetParam().disable_blocking).Expect(1, true).Verify(cq_.get()); + stub_->AsyncRequestStream(&cli_ctx, &recv_response, &cli_cq, tag(1))); // On the server, request to be notified of 'RequestStream' calls // and receive the 'RequestStream' call just made by the client srv_ctx.AsyncNotifyWhenDone(tag(11)); service_->RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), tag(2)); + std::thread t1([this, &cli_cq] { + Verifier(GetParam().disable_blocking).Expect(1, true).Verify(&cli_cq); + }); Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); - - // Client sends 3 messages (tags 3, 4 and 5) - for (int tag_idx = 3; tag_idx <= 5; tag_idx++) { - send_request.set_message("Ping " + grpc::to_string(tag_idx)); - cli_stream->Write(send_request, tag(tag_idx)); - Verifier(GetParam().disable_blocking) - .Expect(tag_idx, true) - .Verify(cq_.get()); - } - cli_stream->WritesDone(tag(6)); - Verifier(GetParam().disable_blocking).Expect(6, true).Verify(cq_.get()); + t1.join(); bool expected_server_cq_result = true; - bool ignore_cq_result = false; - bool want_done_tag = false; + bool expected_client_cq_result = true; if (server_try_cancel == CANCEL_BEFORE_PROCESSING) { srv_ctx.TryCancel(); @@ -1347,10 +1339,36 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { EXPECT_TRUE(srv_ctx.IsCancelled()); // Since cancellation is done before server reads any results, we know - // for sure that all cq results will return false from this point forward + // for sure that all server cq results will return false from this + // point forward expected_server_cq_result = false; + expected_client_cq_result = false; } + bool ignore_client_cq_result = + (server_try_cancel == CANCEL_DURING_PROCESSING) || + (server_try_cancel == CANCEL_BEFORE_PROCESSING); + + std::thread cli_thread([&cli_cq, &cli_stream, &expected_client_cq_result, + &ignore_client_cq_result, this] { + EchoRequest send_request; + // Client sends 3 messages (tags 3, 4 and 5) + for (int tag_idx = 3; tag_idx <= 5; tag_idx++) { + send_request.set_message("Ping " + grpc::to_string(tag_idx)); + cli_stream->Write(send_request, tag(tag_idx)); + Verifier(GetParam().disable_blocking) + .Expect(tag_idx, expected_client_cq_result) + .Verify(&cli_cq, ignore_client_cq_result); + } + cli_stream->WritesDone(tag(6)); + // Ignore ok on WritesDone since cancel can affect it + Verifier(GetParam().disable_blocking) + .Expect(6, expected_client_cq_result) + .Verify(&cli_cq, ignore_client_cq_result); + }); + + bool ignore_cq_result = false; + bool want_done_tag = false; std::thread* server_try_cancel_thd = nullptr; auto verif = Verifier(GetParam().disable_blocking); @@ -1387,6 +1405,8 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { } } + cli_thread.join(); + if (server_try_cancel_thd != nullptr) { server_try_cancel_thd->join(); delete server_try_cancel_thd; @@ -1415,9 +1435,15 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { // Client will see the cancellation cli_stream->Finish(&recv_status, tag(10)); - Verifier(GetParam().disable_blocking).Expect(10, true).Verify(cq_.get()); + Verifier(GetParam().disable_blocking).Expect(10, true).Verify(&cli_cq); EXPECT_FALSE(recv_status.ok()); EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code()); + + cli_cq.Shutdown(); + void* dummy_tag; + bool dummy_ok; + while (cli_cq.Next(&dummy_tag, &dummy_ok)) { + } } // Helper for testing server-streaming RPCs which are cancelled on the server. @@ -1439,7 +1465,6 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { EchoRequest send_request; EchoRequest recv_request; EchoResponse send_response; - EchoResponse recv_response; Status recv_status; ClientContext cli_ctx; ServerContext srv_ctx; @@ -1447,20 +1472,29 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { send_request.set_message("Ping"); // Initiate the 'ResponseStream' call on the client + CompletionQueue cli_cq; std::unique_ptr> cli_stream( - stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1))); - Verifier(GetParam().disable_blocking).Expect(1, true).Verify(cq_.get()); + stub_->AsyncResponseStream(&cli_ctx, send_request, &cli_cq, tag(1))); // On the server, request to be notified of 'ResponseStream' calls and // receive the call just made by the client srv_ctx.AsyncNotifyWhenDone(tag(11)); service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, cq_.get(), cq_.get(), tag(2)); + + std::thread t1([this, &cli_cq] { + Verifier(GetParam().disable_blocking).Expect(1, true).Verify(&cli_cq); + }); Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + t1.join(); + EXPECT_EQ(send_request.message(), recv_request.message()); bool expected_cq_result = true; bool ignore_cq_result = false; bool want_done_tag = false; + bool expected_client_cq_result = true; + bool ignore_client_cq_result = + (server_try_cancel != CANCEL_BEFORE_PROCESSING); if (server_try_cancel == CANCEL_BEFORE_PROCESSING) { srv_ctx.TryCancel(); @@ -1470,8 +1504,21 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { // We know for sure that all cq results will be false from this point // since the server cancelled the RPC expected_cq_result = false; + expected_client_cq_result = false; } + std::thread cli_thread([&cli_cq, &cli_stream, &expected_client_cq_result, + &ignore_client_cq_result, this] { + // Client attempts to read the three messages from the server + for (int tag_idx = 6; tag_idx <= 8; tag_idx++) { + EchoResponse recv_response; + cli_stream->Read(&recv_response, tag(tag_idx)); + Verifier(GetParam().disable_blocking) + .Expect(tag_idx, expected_client_cq_result) + .Verify(&cli_cq, ignore_client_cq_result); + } + }); + std::thread* server_try_cancel_thd = nullptr; auto verif = Verifier(GetParam().disable_blocking); @@ -1519,10 +1566,6 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { srv_ctx.TryCancel(); want_done_tag = true; verif.Expect(11, true); - - // Client reads may fail bacause it is notified that the stream is - // cancelled. - ignore_cq_result = true; } if (want_done_tag) { @@ -1531,13 +1574,7 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { want_done_tag = false; } - // Client attemts to read the three messages from the server - for (int tag_idx = 6; tag_idx <= 8; tag_idx++) { - cli_stream->Read(&recv_response, tag(tag_idx)); - Verifier(GetParam().disable_blocking) - .Expect(tag_idx, expected_cq_result) - .Verify(cq_.get(), ignore_cq_result); - } + cli_thread.join(); // The RPC has been cancelled at this point for sure (i.e irrespective of // the value of `server_try_cancel` is). So, from this point forward, we @@ -1549,9 +1586,15 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { // Client will see the cancellation cli_stream->Finish(&recv_status, tag(10)); - Verifier(GetParam().disable_blocking).Expect(10, true).Verify(cq_.get()); + Verifier(GetParam().disable_blocking).Expect(10, true).Verify(&cli_cq); EXPECT_FALSE(recv_status.ok()); EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code()); + + cli_cq.Shutdown(); + void* dummy_tag; + bool dummy_ok; + while (cli_cq.Next(&dummy_tag, &dummy_ok)) { + } } // Helper for testing bidirectinal-streaming RPCs which are cancelled on the @@ -1584,38 +1627,52 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { // Initiate the call from the client side std::unique_ptr> cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1))); - Verifier(GetParam().disable_blocking).Expect(1, true).Verify(cq_.get()); // On the server, request to be notified of the 'BidiStream' call and // receive the call just made by the client srv_ctx.AsyncNotifyWhenDone(tag(11)); service_->RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), tag(2)); - Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + Verifier(GetParam().disable_blocking) + .Expect(1, true) + .Expect(2, true) + .Verify(cq_.get()); + + auto verif = Verifier(GetParam().disable_blocking); // Client sends the first and the only message send_request.set_message("Ping"); cli_stream->Write(send_request, tag(3)); - Verifier(GetParam().disable_blocking).Expect(3, true).Verify(cq_.get()); + verif.Expect(3, true); bool expected_cq_result = true; bool ignore_cq_result = false; bool want_done_tag = false; + int got_tag, got_tag2; + bool tag_3_done = false; + if (server_try_cancel == CANCEL_BEFORE_PROCESSING) { srv_ctx.TryCancel(); - Verifier(GetParam().disable_blocking).Expect(11, true).Verify(cq_.get()); - EXPECT_TRUE(srv_ctx.IsCancelled()); - - // We know for sure that all cq results will be false from this point - // since the server cancelled the RPC + verif.Expect(11, true); + // We know for sure that all server cq results will be false from + // this point since the server cancelled the RPC. However, we can't + // say for sure about the client expected_cq_result = false; + ignore_cq_result = true; + + do { + got_tag = verif.Next(cq_.get(), ignore_cq_result); + GPR_ASSERT(((got_tag == 3) && !tag_3_done) || (got_tag == 11)); + if (got_tag == 3) { + tag_3_done = true; + } + } while (got_tag != 11); + EXPECT_TRUE(srv_ctx.IsCancelled()); } std::thread* server_try_cancel_thd = nullptr; - auto verif = Verifier(GetParam().disable_blocking); - if (server_try_cancel == CANCEL_DURING_PROCESSING) { server_try_cancel_thd = new std::thread(&ServerContext::TryCancel, &srv_ctx); @@ -1630,39 +1687,42 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { verif.Expect(11, true); } - int got_tag; srv_stream.Read(&recv_request, tag(4)); verif.Expect(4, expected_cq_result); - got_tag = verif.Next(cq_.get(), ignore_cq_result); - GPR_ASSERT((got_tag == 4) || (got_tag == 11 && want_done_tag)); - if (got_tag == 11) { + got_tag = tag_3_done ? 3 : verif.Next(cq_.get(), ignore_cq_result); + got_tag2 = verif.Next(cq_.get(), ignore_cq_result); + GPR_ASSERT((got_tag == 3) || (got_tag == 4) || + (got_tag == 11 && want_done_tag)); + GPR_ASSERT((got_tag2 == 3) || (got_tag2 == 4) || + (got_tag2 == 11 && want_done_tag)); + // If we get 3 and 4, we don't need to wait for 11, but if + // we get 11, we should also clear 3 and 4 + if (got_tag + got_tag2 != 7) { EXPECT_TRUE(srv_ctx.IsCancelled()); want_done_tag = false; - // Now get the other entry that we were waiting on - EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), 4); + got_tag = verif.Next(cq_.get(), ignore_cq_result); + GPR_ASSERT((got_tag == 3) || (got_tag == 4)); } send_response.set_message("Pong"); srv_stream.Write(send_response, tag(5)); verif.Expect(5, expected_cq_result); - got_tag = verif.Next(cq_.get(), ignore_cq_result); - GPR_ASSERT((got_tag == 5) || (got_tag == 11 && want_done_tag)); - if (got_tag == 11) { - EXPECT_TRUE(srv_ctx.IsCancelled()); - want_done_tag = false; - // Now get the other entry that we were waiting on - EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), 5); - } cli_stream->Read(&recv_response, tag(6)); verif.Expect(6, expected_cq_result); got_tag = verif.Next(cq_.get(), ignore_cq_result); - GPR_ASSERT((got_tag == 6) || (got_tag == 11 && want_done_tag)); - if (got_tag == 11) { + got_tag2 = verif.Next(cq_.get(), ignore_cq_result); + GPR_ASSERT((got_tag == 5) || (got_tag == 6) || + (got_tag == 11 && want_done_tag)); + GPR_ASSERT((got_tag2 == 5) || (got_tag2 == 6) || + (got_tag2 == 11 && want_done_tag)); + // If we get 5 and 6, we don't need to wait for 11, but if + // we get 11, we should also clear 5 and 6 + if (got_tag + got_tag2 != 11) { EXPECT_TRUE(srv_ctx.IsCancelled()); want_done_tag = false; - // Now get the other entry that we were waiting on - EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), 6); + got_tag = verif.Next(cq_.get(), ignore_cq_result); + GPR_ASSERT((got_tag == 5) || (got_tag == 6)); } // This is expected to succeed in all cases diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 91c7d4c38e5..a1644dfa097 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -29976,52 +29976,6 @@ "posix" ] }, - { - "args": [ - "write_buffering" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "write_buffering_at_end" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "authority_not_supported" @@ -48359,52 +48313,6 @@ "posix" ] }, - { - "args": [ - "write_buffering" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "write_buffering_at_end" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "--scenarios_json", From 4d7f40854fc55319b29eceed8f9b95f752d43284 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Fri, 6 Oct 2017 14:51:11 -0700 Subject: [PATCH 27/35] Make constructors for `Async*Call` objects public --- src/csharp/Grpc.Core/AsyncClientStreamingCall.cs | 16 +++++++++++++++- src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs | 16 +++++++++++++++- src/csharp/Grpc.Core/AsyncServerStreamingCall.cs | 14 +++++++++++++- src/csharp/Grpc.Core/AsyncUnaryCall.cs | 15 ++++++++++++++- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs b/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs index 087b6859639..f59989655ec 100644 --- a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs +++ b/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs @@ -36,7 +36,21 @@ namespace Grpc.Core readonly Func getTrailersFunc; readonly Action disposeAction; - internal AsyncClientStreamingCall(IClientStreamWriter requestStream, Task responseAsync, Task responseHeadersAsync, Func getStatusFunc, Func getTrailersFunc, Action disposeAction) + /// + /// Creates a new AsyncClientStreamingCall object with the specified properties. + /// + /// Stream of request values. + /// The response of the asynchronous call. + /// Response headers of the asynchronous call. + /// Delegate returning the status of the call. + /// Delegate returning the trailing metadata of the call. + /// Delegate to invoke when Dispose is called on the call object. + public AsyncClientStreamingCall(IClientStreamWriter requestStream, + Task responseAsync, + Task responseHeadersAsync, + Func getStatusFunc, + Func getTrailersFunc, + Action disposeAction) { this.requestStream = requestStream; this.responseAsync = responseAsync; diff --git a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs b/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs index ce49fb1596d..1cb1a918595 100644 --- a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs +++ b/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs @@ -35,7 +35,21 @@ namespace Grpc.Core readonly Func getTrailersFunc; readonly Action disposeAction; - internal AsyncDuplexStreamingCall(IClientStreamWriter requestStream, IAsyncStreamReader responseStream, Task responseHeadersAsync, Func getStatusFunc, Func getTrailersFunc, Action disposeAction) + /// + /// Creates a new AsyncDuplexStreamingCall object with the specified properties. + /// + /// Stream of request values. + /// Stream of response values. + /// Response headers of the asynchronous call. + /// Delegate returning the status of the call. + /// Delegate returning the trailing metadata of the call. + /// Delegate to invoke when Dispose is called on the call object. + public AsyncDuplexStreamingCall(IClientStreamWriter requestStream, + IAsyncStreamReader responseStream, + Task responseHeadersAsync, + Func getStatusFunc, + Func getTrailersFunc, + Action disposeAction) { this.requestStream = requestStream; this.responseStream = responseStream; diff --git a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs b/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs index fbc97b81481..4303b0b1b02 100644 --- a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs +++ b/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs @@ -33,7 +33,19 @@ namespace Grpc.Core readonly Func getTrailersFunc; readonly Action disposeAction; - internal AsyncServerStreamingCall(IAsyncStreamReader responseStream, Task responseHeadersAsync, Func getStatusFunc, Func getTrailersFunc, Action disposeAction) + /// + /// Creates a new AsyncDuplexStreamingCall object with the specified properties. + /// + /// Stream of response values. + /// Response headers of the asynchronous call. + /// Delegate returning the status of the call. + /// Delegate returning the trailing metadata of the call. + /// Delegate to invoke when Dispose is called on the call object. + public AsyncServerStreamingCall(IAsyncStreamReader responseStream, + Task responseHeadersAsync, + Func getStatusFunc, + Func getTrailersFunc, + Action disposeAction) { this.responseStream = responseStream; this.responseHeadersAsync = responseHeadersAsync; diff --git a/src/csharp/Grpc.Core/AsyncUnaryCall.cs b/src/csharp/Grpc.Core/AsyncUnaryCall.cs index 6348f3c5fd4..17747f86caa 100644 --- a/src/csharp/Grpc.Core/AsyncUnaryCall.cs +++ b/src/csharp/Grpc.Core/AsyncUnaryCall.cs @@ -34,7 +34,20 @@ namespace Grpc.Core readonly Func getTrailersFunc; readonly Action disposeAction; - internal AsyncUnaryCall(Task responseAsync, Task responseHeadersAsync, Func getStatusFunc, Func getTrailersFunc, Action disposeAction) + + /// + /// Creates a new AsyncUnaryCall object with the specified properties. + /// + /// The response of the asynchronous call. + /// Response headers of the asynchronous call. + /// Delegate returning the status of the call. + /// Delegate returning the trailing metadata of the call. + /// Delegate to invoke when Dispose is called on the call object. + public AsyncUnaryCall(Task responseAsync, + Task responseHeadersAsync, + Func getStatusFunc, + Func getTrailersFunc, + Action disposeAction) { this.responseAsync = responseAsync; this.responseHeadersAsync = responseHeadersAsync; From fa7ae246ca4779b9351792f4f1ac3e5852ff4844 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 12 Oct 2017 09:37:57 -0700 Subject: [PATCH 28/35] Add call combiner stats --- src/core/lib/debug/stats_data.cc | 5 +++++ src/core/lib/debug/stats_data.h | 8 ++++++++ src/core/lib/debug/stats_data.yaml | 7 ++++++- src/core/lib/debug/stats_data_bq_schema.sql | 2 ++ src/core/lib/iomgr/call_combiner.cc | 3 +++ .../performance/massage_qps_stats.py | 2 ++ .../performance/scenario_result_schema.json | 20 +++++++++++++++++++ 7 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/core/lib/debug/stats_data.cc b/src/core/lib/debug/stats_data.cc index b4ae8f312cd..2271c87e568 100644 --- a/src/core/lib/debug/stats_data.cc +++ b/src/core/lib/debug/stats_data.cc @@ -104,6 +104,8 @@ const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT] = { "combiner_locks_scheduled_items", "combiner_locks_scheduled_final_items", "combiner_locks_offloaded", + "call_combiner_locks_initiated", + "call_combiner_locks_scheduled_items", "executor_scheduled_short_items", "executor_scheduled_long_items", "executor_scheduled_to_self", @@ -213,6 +215,9 @@ const char *grpc_stats_counter_doc[GRPC_STATS_COUNTER_COUNT] = { "Number of items scheduled against combiner locks", "Number of final items scheduled against combiner locks", "Number of combiner locks offloaded to different threads", + "Number of call combiner lock entries by process (first items queued to a " + "call combiner)", + "Number of items scheduled against call combiner locks", "Number of finite runtime closures scheduled against the executor (gRPC " "thread pool)", "Number of potentially infinite runtime closures scheduled against the " diff --git a/src/core/lib/debug/stats_data.h b/src/core/lib/debug/stats_data.h index d4c4437ca07..bfa5c1a61be 100644 --- a/src/core/lib/debug/stats_data.h +++ b/src/core/lib/debug/stats_data.h @@ -110,6 +110,8 @@ typedef enum { GRPC_STATS_COUNTER_COMBINER_LOCKS_SCHEDULED_ITEMS, GRPC_STATS_COUNTER_COMBINER_LOCKS_SCHEDULED_FINAL_ITEMS, GRPC_STATS_COUNTER_COMBINER_LOCKS_OFFLOADED, + GRPC_STATS_COUNTER_CALL_COMBINER_LOCKS_INITIATED, + GRPC_STATS_COUNTER_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS, GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_SHORT_ITEMS, GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_LONG_ITEMS, GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_TO_SELF, @@ -407,6 +409,12 @@ typedef enum { #define GRPC_STATS_INC_COMBINER_LOCKS_OFFLOADED(exec_ctx) \ GRPC_STATS_INC_COUNTER((exec_ctx), \ GRPC_STATS_COUNTER_COMBINER_LOCKS_OFFLOADED) +#define GRPC_STATS_INC_CALL_COMBINER_LOCKS_INITIATED(exec_ctx) \ + GRPC_STATS_INC_COUNTER((exec_ctx), \ + GRPC_STATS_COUNTER_CALL_COMBINER_LOCKS_INITIATED) +#define GRPC_STATS_INC_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS(exec_ctx) \ + GRPC_STATS_INC_COUNTER( \ + (exec_ctx), GRPC_STATS_COUNTER_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS) #define GRPC_STATS_INC_EXECUTOR_SCHEDULED_SHORT_ITEMS(exec_ctx) \ GRPC_STATS_INC_COUNTER((exec_ctx), \ GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_SHORT_ITEMS) diff --git a/src/core/lib/debug/stats_data.yaml b/src/core/lib/debug/stats_data.yaml index 00e81e74e20..d12c8df663f 100644 --- a/src/core/lib/debug/stats_data.yaml +++ b/src/core/lib/debug/stats_data.yaml @@ -245,6 +245,12 @@ doc: Number of final items scheduled against combiner locks - counter: combiner_locks_offloaded doc: Number of combiner locks offloaded to different threads +# call combiner locks +- counter: call_combiner_locks_initiated + doc: Number of call combiner lock entries by process + (first items queued to a call combiner) +- counter: call_combiner_locks_scheduled_items + doc: Number of items scheduled against call combiner locks # executor - counter: executor_scheduled_short_items doc: Number of finite runtime closures scheduled against the executor @@ -282,4 +288,3 @@ - counter: cq_ev_queue_transient_pop_failures doc: Number of times NULL was popped out of completion queue's event queue even though the event queue was not empty - diff --git a/src/core/lib/debug/stats_data_bq_schema.sql b/src/core/lib/debug/stats_data_bq_schema.sql index f34b0c25a03..5e541b9181e 100644 --- a/src/core/lib/debug/stats_data_bq_schema.sql +++ b/src/core/lib/debug/stats_data_bq_schema.sql @@ -79,6 +79,8 @@ combiner_locks_initiated_per_iteration:FLOAT, combiner_locks_scheduled_items_per_iteration:FLOAT, combiner_locks_scheduled_final_items_per_iteration:FLOAT, combiner_locks_offloaded_per_iteration:FLOAT, +call_combiner_locks_initiated_per_iteration:FLOAT, +call_combiner_locks_scheduled_items_per_iteration:FLOAT, executor_scheduled_short_items_per_iteration:FLOAT, executor_scheduled_long_items_per_iteration:FLOAT, executor_scheduled_to_self_per_iteration:FLOAT, diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc index bab3df021a6..8b08d307a19 100644 --- a/src/core/lib/iomgr/call_combiner.cc +++ b/src/core/lib/iomgr/call_combiner.cc @@ -21,6 +21,7 @@ #include #include +#include "src/core/lib/debug/stats.h" grpc_tracer_flag grpc_call_combiner_trace = GRPC_TRACER_INITIALIZER(false, "call_combiner"); @@ -73,7 +74,9 @@ void grpc_call_combiner_start(grpc_exec_ctx* exec_ctx, gpr_log(GPR_DEBUG, " size: %" PRIdPTR " -> %" PRIdPTR, prev_size, prev_size + 1); } + GRPC_STATS_INC_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS(exec_ctx); if (prev_size == 0) { + GRPC_STATS_INC_CALL_COMBINER_LOCKS_INITIATED(exec_ctx); if (GRPC_TRACER_ON(grpc_call_combiner_trace)) { gpr_log(GPR_DEBUG, " EXECUTING IMMEDIATELY"); } diff --git a/tools/run_tests/performance/massage_qps_stats.py b/tools/run_tests/performance/massage_qps_stats.py index e0b6ce6ba63..eadd17db8ee 100644 --- a/tools/run_tests/performance/massage_qps_stats.py +++ b/tools/run_tests/performance/massage_qps_stats.py @@ -101,6 +101,8 @@ def massage_qps_stats(scenario_result): stats["core_combiner_locks_scheduled_items"] = massage_qps_stats_helpers.counter(core_stats, "combiner_locks_scheduled_items") stats["core_combiner_locks_scheduled_final_items"] = massage_qps_stats_helpers.counter(core_stats, "combiner_locks_scheduled_final_items") stats["core_combiner_locks_offloaded"] = massage_qps_stats_helpers.counter(core_stats, "combiner_locks_offloaded") + stats["core_call_combiner_locks_initiated"] = massage_qps_stats_helpers.counter(core_stats, "call_combiner_locks_initiated") + stats["core_call_combiner_locks_scheduled_items"] = massage_qps_stats_helpers.counter(core_stats, "call_combiner_locks_scheduled_items") stats["core_executor_scheduled_short_items"] = massage_qps_stats_helpers.counter(core_stats, "executor_scheduled_short_items") stats["core_executor_scheduled_long_items"] = massage_qps_stats_helpers.counter(core_stats, "executor_scheduled_long_items") stats["core_executor_scheduled_to_self"] = massage_qps_stats_helpers.counter(core_stats, "executor_scheduled_to_self") diff --git a/tools/run_tests/performance/scenario_result_schema.json b/tools/run_tests/performance/scenario_result_schema.json index f11e6359f65..1d726539b90 100644 --- a/tools/run_tests/performance/scenario_result_schema.json +++ b/tools/run_tests/performance/scenario_result_schema.json @@ -515,6 +515,16 @@ "name": "core_combiner_locks_offloaded", "type": "INTEGER" }, + { + "mode": "NULLABLE", + "name": "core_call_combiner_locks_initiated", + "type": "INTEGER" + }, + { + "mode": "NULLABLE", + "name": "core_call_combiner_locks_scheduled_items", + "type": "INTEGER" + }, { "mode": "NULLABLE", "name": "core_executor_scheduled_short_items", @@ -1327,6 +1337,16 @@ "name": "core_combiner_locks_offloaded", "type": "INTEGER" }, + { + "mode": "NULLABLE", + "name": "core_call_combiner_locks_initiated", + "type": "INTEGER" + }, + { + "mode": "NULLABLE", + "name": "core_call_combiner_locks_scheduled_items", + "type": "INTEGER" + }, { "mode": "NULLABLE", "name": "core_executor_scheduled_short_items", From 2638cd9ff5e9f99a436f4369db46c904fae78d43 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 12 Oct 2017 09:41:55 -0700 Subject: [PATCH 29/35] Track where combiners are initiated in latency traces --- src/core/lib/iomgr/combiner.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lib/iomgr/combiner.cc b/src/core/lib/iomgr/combiner.cc index 0e707ef8392..53f4b7eaa7e 100644 --- a/src/core/lib/iomgr/combiner.cc +++ b/src/core/lib/iomgr/combiner.cc @@ -165,6 +165,7 @@ static void combiner_exec(grpc_exec_ctx *exec_ctx, grpc_closure *cl, lock, cl, last)); if (last == 1) { GRPC_STATS_INC_COMBINER_LOCKS_INITIATED(exec_ctx); + GPR_TIMER_MARK("combiner.initiated", 0); gpr_atm_no_barrier_store(&lock->initiating_exec_ctx_or_null, (gpr_atm)exec_ctx); // first element on this list: add it to the list of combiner locks From 7befe5d8e568da23edab19b02b953a33dd973e9f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 12 Oct 2017 09:53:02 -0700 Subject: [PATCH 30/35] Add counters --- src/core/lib/debug/stats_data.cc | 4 ++++ src/core/lib/debug/stats_data.h | 7 +++++++ src/core/lib/debug/stats_data.yaml | 4 ++++ src/core/lib/debug/stats_data_bq_schema.sql | 2 ++ src/core/lib/iomgr/call_combiner.cc | 2 ++ .../performance/massage_qps_stats.py | 2 ++ .../performance/scenario_result_schema.json | 20 +++++++++++++++++++ 7 files changed, 41 insertions(+) diff --git a/src/core/lib/debug/stats_data.cc b/src/core/lib/debug/stats_data.cc index 2271c87e568..5d737c56cbf 100644 --- a/src/core/lib/debug/stats_data.cc +++ b/src/core/lib/debug/stats_data.cc @@ -106,6 +106,8 @@ const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT] = { "combiner_locks_offloaded", "call_combiner_locks_initiated", "call_combiner_locks_scheduled_items", + "call_combiner_set_notify_on_cancel", + "call_combiner_cancelled", "executor_scheduled_short_items", "executor_scheduled_long_items", "executor_scheduled_to_self", @@ -218,6 +220,8 @@ const char *grpc_stats_counter_doc[GRPC_STATS_COUNTER_COUNT] = { "Number of call combiner lock entries by process (first items queued to a " "call combiner)", "Number of items scheduled against call combiner locks", + "Number of times a cancellation callback was set on a call combiner", + "Number of times a call combiner was cancelled", "Number of finite runtime closures scheduled against the executor (gRPC " "thread pool)", "Number of potentially infinite runtime closures scheduled against the " diff --git a/src/core/lib/debug/stats_data.h b/src/core/lib/debug/stats_data.h index bfa5c1a61be..031942df5c5 100644 --- a/src/core/lib/debug/stats_data.h +++ b/src/core/lib/debug/stats_data.h @@ -112,6 +112,8 @@ typedef enum { GRPC_STATS_COUNTER_COMBINER_LOCKS_OFFLOADED, GRPC_STATS_COUNTER_CALL_COMBINER_LOCKS_INITIATED, GRPC_STATS_COUNTER_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS, + GRPC_STATS_COUNTER_CALL_COMBINER_SET_NOTIFY_ON_CANCEL, + GRPC_STATS_COUNTER_CALL_COMBINER_CANCELLED, GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_SHORT_ITEMS, GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_LONG_ITEMS, GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_TO_SELF, @@ -415,6 +417,11 @@ typedef enum { #define GRPC_STATS_INC_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS(exec_ctx) \ GRPC_STATS_INC_COUNTER( \ (exec_ctx), GRPC_STATS_COUNTER_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS) +#define GRPC_STATS_INC_CALL_COMBINER_SET_NOTIFY_ON_CANCEL(exec_ctx) \ + GRPC_STATS_INC_COUNTER( \ + (exec_ctx), GRPC_STATS_COUNTER_CALL_COMBINER_SET_NOTIFY_ON_CANCEL) +#define GRPC_STATS_INC_CALL_COMBINER_CANCELLED(exec_ctx) \ + GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_CALL_COMBINER_CANCELLED) #define GRPC_STATS_INC_EXECUTOR_SCHEDULED_SHORT_ITEMS(exec_ctx) \ GRPC_STATS_INC_COUNTER((exec_ctx), \ GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_SHORT_ITEMS) diff --git a/src/core/lib/debug/stats_data.yaml b/src/core/lib/debug/stats_data.yaml index d12c8df663f..af4553028e3 100644 --- a/src/core/lib/debug/stats_data.yaml +++ b/src/core/lib/debug/stats_data.yaml @@ -251,6 +251,10 @@ (first items queued to a call combiner) - counter: call_combiner_locks_scheduled_items doc: Number of items scheduled against call combiner locks +- counter: call_combiner_set_notify_on_cancel + doc: Number of times a cancellation callback was set on a call combiner +- counter: call_combiner_cancelled + doc: Number of times a call combiner was cancelled # executor - counter: executor_scheduled_short_items doc: Number of finite runtime closures scheduled against the executor diff --git a/src/core/lib/debug/stats_data_bq_schema.sql b/src/core/lib/debug/stats_data_bq_schema.sql index 5e541b9181e..04b6d471f63 100644 --- a/src/core/lib/debug/stats_data_bq_schema.sql +++ b/src/core/lib/debug/stats_data_bq_schema.sql @@ -81,6 +81,8 @@ combiner_locks_scheduled_final_items_per_iteration:FLOAT, combiner_locks_offloaded_per_iteration:FLOAT, call_combiner_locks_initiated_per_iteration:FLOAT, call_combiner_locks_scheduled_items_per_iteration:FLOAT, +call_combiner_set_notify_on_cancel_per_iteration:FLOAT, +call_combiner_cancelled_per_iteration:FLOAT, executor_scheduled_short_items_per_iteration:FLOAT, executor_scheduled_long_items_per_iteration:FLOAT, executor_scheduled_to_self_per_iteration:FLOAT, diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc index 8b08d307a19..0ba32a1e463 100644 --- a/src/core/lib/iomgr/call_combiner.cc +++ b/src/core/lib/iomgr/call_combiner.cc @@ -138,6 +138,7 @@ void grpc_call_combiner_stop(grpc_exec_ctx* exec_ctx, void grpc_call_combiner_set_notify_on_cancel(grpc_exec_ctx* exec_ctx, grpc_call_combiner* call_combiner, grpc_closure* closure) { + GRPC_STATS_INC_CALL_COMBINER_SET_NOTIFY_ON_CANCEL(exec_ctx); while (true) { // Decode original state. gpr_atm original_state = gpr_atm_acq_load(&call_combiner->cancel_state); @@ -182,6 +183,7 @@ void grpc_call_combiner_set_notify_on_cancel(grpc_exec_ctx* exec_ctx, void grpc_call_combiner_cancel(grpc_exec_ctx* exec_ctx, grpc_call_combiner* call_combiner, grpc_error* error) { + GRPC_STATS_INC_CALL_COMBINER_CANCELLED(exec_ctx); while (true) { gpr_atm original_state = gpr_atm_acq_load(&call_combiner->cancel_state); grpc_error* original_error = decode_cancel_state_error(original_state); diff --git a/tools/run_tests/performance/massage_qps_stats.py b/tools/run_tests/performance/massage_qps_stats.py index eadd17db8ee..48c57581a52 100644 --- a/tools/run_tests/performance/massage_qps_stats.py +++ b/tools/run_tests/performance/massage_qps_stats.py @@ -103,6 +103,8 @@ def massage_qps_stats(scenario_result): stats["core_combiner_locks_offloaded"] = massage_qps_stats_helpers.counter(core_stats, "combiner_locks_offloaded") stats["core_call_combiner_locks_initiated"] = massage_qps_stats_helpers.counter(core_stats, "call_combiner_locks_initiated") stats["core_call_combiner_locks_scheduled_items"] = massage_qps_stats_helpers.counter(core_stats, "call_combiner_locks_scheduled_items") + stats["core_call_combiner_set_notify_on_cancel"] = massage_qps_stats_helpers.counter(core_stats, "call_combiner_set_notify_on_cancel") + stats["core_call_combiner_cancelled"] = massage_qps_stats_helpers.counter(core_stats, "call_combiner_cancelled") stats["core_executor_scheduled_short_items"] = massage_qps_stats_helpers.counter(core_stats, "executor_scheduled_short_items") stats["core_executor_scheduled_long_items"] = massage_qps_stats_helpers.counter(core_stats, "executor_scheduled_long_items") stats["core_executor_scheduled_to_self"] = massage_qps_stats_helpers.counter(core_stats, "executor_scheduled_to_self") diff --git a/tools/run_tests/performance/scenario_result_schema.json b/tools/run_tests/performance/scenario_result_schema.json index 1d726539b90..b00c2eed165 100644 --- a/tools/run_tests/performance/scenario_result_schema.json +++ b/tools/run_tests/performance/scenario_result_schema.json @@ -525,6 +525,16 @@ "name": "core_call_combiner_locks_scheduled_items", "type": "INTEGER" }, + { + "mode": "NULLABLE", + "name": "core_call_combiner_set_notify_on_cancel", + "type": "INTEGER" + }, + { + "mode": "NULLABLE", + "name": "core_call_combiner_cancelled", + "type": "INTEGER" + }, { "mode": "NULLABLE", "name": "core_executor_scheduled_short_items", @@ -1347,6 +1357,16 @@ "name": "core_call_combiner_locks_scheduled_items", "type": "INTEGER" }, + { + "mode": "NULLABLE", + "name": "core_call_combiner_set_notify_on_cancel", + "type": "INTEGER" + }, + { + "mode": "NULLABLE", + "name": "core_call_combiner_cancelled", + "type": "INTEGER" + }, { "mode": "NULLABLE", "name": "core_executor_scheduled_short_items", From fbf8128da8ea1dd55729c957e915afedb8754f0d Mon Sep 17 00:00:00 2001 From: Frank Groeneveld Date: Thu, 12 Oct 2017 08:27:14 +0200 Subject: [PATCH 31/35] Add OpenBSD support --- Makefile | 2 +- build.yaml | 4 +- grpc.gemspec | 1 + include/grpc/impl/codegen/port_platform.h | 23 + setup.py | 2 + src/c-ares/gen_build_yaml.py | 5 +- src/core/lib/iomgr/port.h | 10 + src/core/lib/support/time_posix.cc | 2 +- src/ruby/ext/grpc/extconf.rb | 4 +- .../cares/config_openbsd/ares_config.h | 502 ++++++++++++++++++ .../generated/sources_and_headers.json | 3 +- 11 files changed, 551 insertions(+), 7 deletions(-) create mode 100644 third_party/cares/config_openbsd/ares_config.h diff --git a/Makefile b/Makefile index 0357f7baac6..7cf412d21dc 100644 --- a/Makefile +++ b/Makefile @@ -8423,7 +8423,7 @@ PUBLIC_HEADERS_C += \ LIBARES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBARES_SRC)))) -$(LIBARES_OBJS): CPPFLAGS += -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,) +$(LIBARES_OBJS): CPPFLAGS += -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden $(if $(subst OpenBSD,,$(SYSTEM)),,-Ithird_party/cares/config_openbsd) -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,) $(LIBARES_OBJS): CFLAGS += -Wno-sign-conversion $(if $(subst Darwin,,$(SYSTEM)),,-Wno-shorten-64-to-32) $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,) $(LIBDIR)/$(CONFIG)/libares.a: $(ZLIB_DEP) $(LIBARES_OBJS) diff --git a/build.yaml b/build.yaml index fac62d21d17..2237fe10cd8 100644 --- a/build.yaml +++ b/build.yaml @@ -4872,8 +4872,8 @@ defaults: $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,) CPPFLAGS: -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden - -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst - MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,) + $(if $(subst OpenBSD,,$(SYSTEM)),,-Ithird_party/cares/config_openbsd) -D_GNU_SOURCE + -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,) benchmark: CPPFLAGS: -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX boringssl: diff --git a/grpc.gemspec b/grpc.gemspec index ce23e6f7df5..6b35d7a7c1d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1125,6 +1125,7 @@ Gem::Specification.new do |s| s.files += %w( third_party/cares/ares_build.h ) s.files += %w( third_party/cares/config_linux/ares_config.h ) s.files += %w( third_party/cares/config_darwin/ares_config.h ) + s.files += %w( third_party/cares/config_openbsd/ares_config.h ) s.files += %w( third_party/cares/cares/ares__close_sockets.c ) s.files += %w( third_party/cares/cares/ares__get_hostent.c ) s.files += %w( third_party/cares/cares/ares__read_line.c ) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index baea4bcf529..fb4bfc3162f 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -241,6 +241,29 @@ #else /* _LP64 */ #define GPR_ARCH_32 1 #endif /* _LP64 */ +#elif defined(__OpenBSD__) +#define GPR_PLATFORM_STRING "openbsd" +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif +#define GPR_OPENBSD 1 +#define GPR_CPU_POSIX 1 +#define GPR_GCC_ATOMIC 1 +#define GPR_GCC_TLS 1 +#define GPR_POSIX_LOG 1 +#define GPR_POSIX_ENV 1 +#define GPR_POSIX_TMPFILE 1 +#define GPR_POSIX_STRING 1 +#define GPR_POSIX_SUBPROCESS 1 +#define GPR_POSIX_SYNC 1 +#define GPR_POSIX_TIME 1 +#define GPR_GETPID_IN_UNISTD_H 1 +#define GPR_SUPPORT_CHANNELS_FROM_FD 1 +#ifdef _LP64 +#define GPR_ARCH_64 1 +#else /* _LP64 */ +#define GPR_ARCH_32 1 +#endif /* _LP64 */ #elif defined(__native_client__) #define GPR_PLATFORM_STRING "nacl" #ifndef _BSD_SOURCE diff --git a/setup.py b/setup.py index 90c9316b0da..5a85ed8545e 100644 --- a/setup.py +++ b/setup.py @@ -44,6 +44,8 @@ if 'linux' in sys.platform: CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_linux'),) if 'darwin' in sys.platform: CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_darwin'),) +if 'openbsd' in sys.platform: + CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_openbsd'),) README = os.path.join(PYTHON_STEM, 'README.rst') # Ensure we're in the proper directory whether or not we're being used by pip. diff --git a/src/c-ares/gen_build_yaml.py b/src/c-ares/gen_build_yaml.py index 6f8b7485acb..b7707dc36da 100755 --- a/src/c-ares/gen_build_yaml.py +++ b/src/c-ares/gen_build_yaml.py @@ -33,6 +33,8 @@ try: return 'src/cares/cares/config_linux/ares_config.h' if 'darwin' in sys.platform: return 'src/cares/cares/config_darwin/ares_config.h' + if 'openbsd' in sys.platform: + return 'src/cares/cares/config_openbsd/ares_config.h' if not os.path.isfile('third_party/cares/cares/ares_config.h'): gen_ares_build(x) return 'third_party/cares/cares/ares_config.h' @@ -125,7 +127,8 @@ try: "third_party/cares/cares/setup_once.h", "third_party/cares/ares_build.h", "third_party/cares/config_linux/ares_config.h", - "third_party/cares/config_darwin/ares_config.h" + "third_party/cares/config_darwin/ares_config.h", + "third_party/cares/config_openbsd/ares_config.h" ], }] except: diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 42033d0ba4b..1cc6d984910 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -109,6 +109,16 @@ #define GRPC_POSIX_SOCKETUTILS 1 #define GRPC_POSIX_WAKEUP_FD 1 #define GRPC_TIMER_USE_GENERIC 1 +#elif defined(GPR_OPENBSD) +#define GRPC_HAVE_IFADDRS 1 +#define GRPC_HAVE_IPV6_RECVPKTINFO 1 +#define GRPC_HAVE_UNIX_SOCKET 1 +#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1 +#define GRPC_POSIX_SOCKET 1 +#define GRPC_POSIX_SOCKETADDR 1 +#define GRPC_POSIX_SOCKETUTILS 1 +#define GRPC_POSIX_WAKEUP_FD 1 +#define GRPC_TIMER_USE_GENERIC 1 #elif defined(GPR_NACL) #define GRPC_HAVE_ARPA_NAMESER 1 #define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1 diff --git a/src/core/lib/support/time_posix.cc b/src/core/lib/support/time_posix.cc index 3267ea6b541..3f8a9094fd6 100644 --- a/src/core/lib/support/time_posix.cc +++ b/src/core/lib/support/time_posix.cc @@ -42,7 +42,7 @@ static struct timespec timespec_from_gpr(gpr_timespec gts) { return rv; } -#if _POSIX_TIMERS > 0 +#if _POSIX_TIMERS > 0 || defined(__OpenBSD__) static gpr_timespec gpr_from_timespec(struct timespec ts, gpr_clock_type clock_type) { /* diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index e5ab02b9fc0..9d2cf2a08ad 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -41,6 +41,7 @@ LIB_DIRS = [ ] windows = RUBY_PLATFORM =~ /mingw|mswin/ +bsd = RUBY_PLATFORM =~ /bsd/ grpc_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) @@ -70,7 +71,8 @@ unless windows puts 'Building internal gRPC into ' + grpc_lib_dir nproc = 4 nproc = Etc.nprocessors * 2 if Etc.respond_to? :nprocessors - system("make -j#{nproc} -C #{grpc_root} #{grpc_lib_dir}/libgrpc.a CONFIG=#{grpc_config} Q=") + make = bsd ? 'gmake' : 'make' + system("#{make} -j#{nproc} -C #{grpc_root} #{grpc_lib_dir}/libgrpc.a CONFIG=#{grpc_config} Q=") exit 1 unless $? == 0 end diff --git a/third_party/cares/config_openbsd/ares_config.h b/third_party/cares/config_openbsd/ares_config.h new file mode 100644 index 00000000000..3b3320db8f6 --- /dev/null +++ b/third_party/cares/config_openbsd/ares_config.h @@ -0,0 +1,502 @@ +/* ares_config.h. Generated from ares_config.h.in by configure. */ +/* ares_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* define this if ares is built for a big endian system */ +/* #undef ARES_BIG_ENDIAN */ + +/* when building as static part of libcurl */ +/* #undef BUILDING_LIBCURL */ + +/* Defined for build that exposes internal static functions for testing. */ +/* #undef CARES_EXPOSE_STATICS */ + +/* Defined for build with symbol hiding. */ +#define CARES_SYMBOL_HIDING 1 + +/* Definition to make a library symbol externally visible. */ +#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((__visibility__ ("default"))) + +/* the signed version of size_t */ +#define CARES_TYPEOF_ARES_SSIZE_T ssize_t + +/* Use resolver library to configure cares */ +/* #undef CARES_USE_LIBRESOLV */ + +/* if a /etc/inet dir is being used */ +/* #undef ETC_INET */ + +/* Define to the type of arg 2 for gethostname. */ +#define GETHOSTNAME_TYPE_ARG2 size_t + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#define GETNAMEINFO_QUAL_ARG1 const + +/* Define to the type of arg 1 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * + +/* Define to the type of arg 2 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG2 socklen_t + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG46 size_t + +/* Define to the type of arg 7 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG7 int + +/* Specifies the number of arguments to getservbyport_r */ +#define GETSERVBYPORT_R_ARGS 4 + +/* Specifies the size of the buffer to pass to getservbyport_r */ +#define GETSERVBYPORT_R_BUFSIZE sizeof(struct servent_data) + +/* Define to 1 if you have AF_INET6. */ +#define HAVE_AF_INET6 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ARPA_NAMESER_COMPAT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `bitncmp' function. */ +/* #undef HAVE_BITNCMP */ + +/* Define to 1 if bool is an available type. */ +#define HAVE_BOOL_T 1 + +/* Define to 1 if you have the clock_gettime function and monotonic timer. */ +#define HAVE_CLOCK_GETTIME_MONOTONIC 1 + +/* Define to 1 if you have the closesocket function. */ +/* #undef HAVE_CLOSESOCKET */ + +/* Define to 1 if you have the CloseSocket camel case function. */ +/* #undef HAVE_CLOSESOCKET_CAMEL */ + +/* Define to 1 if you have the connect function. */ +#define HAVE_CONNECT 1 + +/* define if the compiler supports basic C++11 syntax */ +/* #undef HAVE_CXX11 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ +#define HAVE_FCNTL_O_NONBLOCK 1 + +/* Define to 1 if you have the freeaddrinfo function. */ +#define HAVE_FREEADDRINFO 1 + +/* Define to 1 if you have a working getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define to 1 if the getaddrinfo function is threadsafe. */ +/* #undef HAVE_GETADDRINFO_THREADSAFE */ + +/* Define to 1 if you have the getenv function. */ +#define HAVE_GETENV 1 + +/* Define to 1 if you have the gethostbyaddr function. */ +#define HAVE_GETHOSTBYADDR 1 + +/* Define to 1 if you have the gethostbyname function. */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the gethostname function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define to 1 if you have the getnameinfo function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the getservbyport_r function. */ +#define HAVE_GETSERVBYPORT_R 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `if_indextoname' function. */ +#define HAVE_IF_INDEXTONAME 1 + +/* Define to 1 if you have a IPv6 capable working inet_net_pton function. */ +/* #undef HAVE_INET_NET_PTON */ + +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ +#define HAVE_INET_NTOP 1 + +/* Define to 1 if you have a IPv6 capable working inet_pton function. */ +#define HAVE_INET_PTON 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the ioctl function. */ +#define HAVE_IOCTL 1 + +/* Define to 1 if you have the ioctlsocket function. */ +/* #undef HAVE_IOCTLSOCKET */ + +/* Define to 1 if you have the IoctlSocket camel case function. */ +/* #undef HAVE_IOCTLSOCKET_CAMEL */ + +/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. + */ +/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ + +/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ +/* #undef HAVE_IOCTLSOCKET_FIONBIO */ + +/* Define to 1 if you have a working ioctl FIONBIO function. */ +#define HAVE_IOCTL_FIONBIO 1 + +/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ +#define HAVE_IOCTL_SIOCGIFADDR 1 + +/* Define to 1 if you have the `resolve' library (-lresolve). */ +/* #undef HAVE_LIBRESOLVE */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* if your compiler supports LL */ +#define HAVE_LL 1 + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#define HAVE_LONGLONG 1 + +/* Define to 1 if you have the malloc.h header file. */ +/* #undef HAVE_MALLOC_H */ + +/* Define to 1 if you have the memory.h header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the MSG_NOSIGNAL flag. */ +#define HAVE_MSG_NOSIGNAL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define to 1 if you have PF_INET6. */ +#define HAVE_PF_INET6 1 + +/* Define to 1 if you have the recv function. */ +#define HAVE_RECV 1 + +/* Define to 1 if you have the recvfrom function. */ +#define HAVE_RECVFROM 1 + +/* Define to 1 if you have the send function. */ +#define HAVE_SEND 1 + +/* Define to 1 if you have the setsockopt function. */ +#define HAVE_SETSOCKOPT 1 + +/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ +/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define to 1 if sig_atomic_t is an available typedef. */ +#define HAVE_SIG_ATOMIC_T 1 + +/* Define to 1 if sig_atomic_t is already defined as volatile. */ +/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ + +/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* Define to 1 if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SOCKET_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the strcmpi function. */ +/* #undef HAVE_STRCMPI */ + +/* Define to 1 if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the stricmp function. */ +/* #undef HAVE_STRICMP */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the strncasecmp function. */ +#define HAVE_STRNCASECMP 1 + +/* Define to 1 if you have the strncmpi function. */ +/* #undef HAVE_STRNCMPI */ + +/* Define to 1 if you have the strnicmp function. */ +/* #undef HAVE_STRNICMP */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STROPTS_H */ + +/* Define to 1 if you have struct addrinfo. */ +#define HAVE_STRUCT_ADDRINFO 1 + +/* Define to 1 if you have struct in6_addr. */ +#define HAVE_STRUCT_IN6_ADDR 1 + +/* Define to 1 if you have struct sockaddr_in6. */ +#define HAVE_STRUCT_SOCKADDR_IN6 1 + +/* if struct sockaddr_storage is defined */ +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define to 1 if you have the timeval struct. */ +#define HAVE_STRUCT_TIMEVAL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the windows.h header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if you have the winsock2.h header file. */ +/* #undef HAVE_WINSOCK2_H */ + +/* Define to 1 if you have the winsock.h header file. */ +/* #undef HAVE_WINSOCK_H */ + +/* Define to 1 if you have the writev function. */ +#define HAVE_WRITEV 1 + +/* Define to 1 if you have the ws2tcpip.h header file. */ +/* #undef HAVE_WS2TCPIP_H */ + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Define to 1 if you need the malloc.h header file even with stdlib.h */ +/* #undef NEED_MALLOC_H */ + +/* Define to 1 if you need the memory.h header file even with stdlib.h */ +/* #undef NEED_MEMORY_H */ + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +/* #undef NEED_REENTRANT */ + +/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ +/* #undef NEED_THREAD_SAFE */ + +/* cpu-machine-OS */ +#define OS "x86_64-unknown-openbsd6.2" + +/* Name of package */ +#define PACKAGE "c-ares" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "c-ares" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "c-ares 1.13.0" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "c-ares" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.13.0" + +/* a suitable file/device to read random data from */ +#define RANDOM_FILE "/dev/urandom" + +/* Define to the type qualifier pointed by arg 5 for recvfrom. */ +#define RECVFROM_QUAL_ARG5 + +/* Define to the type of arg 1 for recvfrom. */ +#define RECVFROM_TYPE_ARG1 int + +/* Define to the type pointed by arg 2 for recvfrom. */ +#define RECVFROM_TYPE_ARG2 void + +/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ +#define RECVFROM_TYPE_ARG2_IS_VOID 1 + +/* Define to the type of arg 3 for recvfrom. */ +#define RECVFROM_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for recvfrom. */ +#define RECVFROM_TYPE_ARG4 int + +/* Define to the type pointed by arg 5 for recvfrom. */ +#define RECVFROM_TYPE_ARG5 struct sockaddr + +/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ +/* #undef RECVFROM_TYPE_ARG5_IS_VOID */ + +/* Define to the type pointed by arg 6 for recvfrom. */ +#define RECVFROM_TYPE_ARG6 socklen_t + +/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ +/* #undef RECVFROM_TYPE_ARG6_IS_VOID */ + +/* Define to the function return type for recvfrom. */ +#define RECVFROM_TYPE_RETV ssize_t + +/* Define to the type of arg 1 for recv. */ +#define RECV_TYPE_ARG1 int + +/* Define to the type of arg 2 for recv. */ +#define RECV_TYPE_ARG2 void * + +/* Define to the type of arg 3 for recv. */ +#define RECV_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for recv. */ +#define RECV_TYPE_ARG4 int + +/* Define to the function return type for recv. */ +#define RECV_TYPE_RETV ssize_t + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to the type qualifier of arg 2 for send. */ +#define SEND_QUAL_ARG2 const + +/* Define to the type of arg 1 for send. */ +#define SEND_TYPE_ARG1 int + +/* Define to the type of arg 2 for send. */ +#define SEND_TYPE_ARG2 void * + +/* Define to the type of arg 3 for send. */ +#define SEND_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for send. */ +#define SEND_TYPE_ARG4 int + +/* Define to the function return type for send. */ +#define SEND_TYPE_RETV ssize_t + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to disable non-blocking sockets. */ +/* #undef USE_BLOCKING_SOCKETS */ + +/* Version number of package */ +#define VERSION "1.13.0" + +/* Define to avoid automatic inclusion of winsock.h */ +/* #undef WIN32_LEAN_AND_MEAN */ + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Define to 1 if OS is AIX. */ +#ifndef _ALL_SOURCE +/* # undef _ALL_SOURCE */ +#endif + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Type to use in place of in_addr_t when system does not provide it. */ +/* #undef in_addr_t */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 21b3bef691a..f3405b83465 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -7483,7 +7483,8 @@ "third_party/cares/cares/config-win32.h", "third_party/cares/cares/setup_once.h", "third_party/cares/config_darwin/ares_config.h", - "third_party/cares/config_linux/ares_config.h" + "third_party/cares/config_linux/ares_config.h", + "third_party/cares/config_openbsd/ares_config.h" ], "is_filegroup": false, "language": "c", From 2145d2cee4dfc336c0b5e7368962de4104c2537c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 12 Oct 2017 15:51:47 -0700 Subject: [PATCH 32/35] clang-format --- test/cpp/microbenchmarks/bm_fullstack_trickle.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc index 14eb3534cf5..06ae3429857 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc @@ -21,15 +21,15 @@ #include #include #include +#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/ext/transport/chttp2/transport/internal.h" +#include "src/core/lib/iomgr/timer_manager.h" #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/trickle_endpoint.h" #include "test/cpp/microbenchmarks/fullstack_context_mutators.h" #include "test/cpp/microbenchmarks/fullstack_fixtures.h" #include "test/cpp/util/test_config.h" -#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" -#include "src/core/ext/transport/chttp2/transport/internal.h" -#include "src/core/lib/iomgr/timer_manager.h" -#include "test/core/util/trickle_endpoint.h" DEFINE_bool(log, false, "Log state to CSV files"); DEFINE_int32( From 9fc49c98634bc1b1f5844e670f4bb5e1965be551 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 12 Oct 2017 15:53:36 -0700 Subject: [PATCH 33/35] Fix compilation --- src/core/lib/transport/bdp_estimator.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lib/transport/bdp_estimator.h b/src/core/lib/transport/bdp_estimator.h index a4acf30dedf..60b9fba0838 100644 --- a/src/core/lib/transport/bdp_estimator.h +++ b/src/core/lib/transport/bdp_estimator.h @@ -19,6 +19,7 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H #define GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H +#include #include #include From 1c3dd002b9c1af714dc45050f49e9fd59e384abc Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 12 Oct 2017 16:08:56 -0700 Subject: [PATCH 34/35] Be consistent with Java --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 2 +- test/core/end2end/tests/bad_ping.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 659208ccf0e..abc30022c05 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1783,7 +1783,7 @@ void grpc_chttp2_add_ping_strike(grpc_exec_ctx *exec_ctx, exec_ctx, t, grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many pings"), - GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM)); + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); } } diff --git a/test/core/end2end/tests/bad_ping.c b/test/core/end2end/tests/bad_ping.c index 56c76b70d06..34cc8e78cd8 100644 --- a/test/core/end2end/tests/bad_ping.c +++ b/test/core/end2end/tests/bad_ping.c @@ -202,7 +202,7 @@ static void test_bad_ping(grpc_end2end_test_config config) { // The connection should be closed immediately after the misbehaved pings, // the in-progress RPC should fail. - GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED); + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); validate_host_override_string("foo.test.google.fr:1234", call_details.host, config); From 451c02b8bf512a89e122b3cf3862a9709c1a5e29 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Thu, 12 Oct 2017 10:28:14 -0700 Subject: [PATCH 35/35] Fix FreeBSD Ruby and Python build --- Makefile | 2 +- build.yaml | 9 +++++---- grpc.gemspec | 3 ++- setup.py | 6 ++++-- src/c-ares/gen_build_yaml.py | 9 ++++++--- tools/run_tests/generated/sources_and_headers.json | 1 + 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 7cf412d21dc..3960d2c115b 100644 --- a/Makefile +++ b/Makefile @@ -8423,7 +8423,7 @@ PUBLIC_HEADERS_C += \ LIBARES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBARES_SRC)))) -$(LIBARES_OBJS): CPPFLAGS += -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden $(if $(subst OpenBSD,,$(SYSTEM)),,-Ithird_party/cares/config_openbsd) -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,) +$(LIBARES_OBJS): CPPFLAGS += -Ithird_party/cares -Ithird_party/cares/cares -fvisibility=hidden -D_GNU_SOURCE $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) $(if $(subst FreeBSD,,$(SYSTEM)),,-Ithird_party/cares/config_freebsd) $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst OpenBSD,,$(SYSTEM)),,-Ithird_party/cares/config_openbsd) -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,) $(LIBARES_OBJS): CFLAGS += -Wno-sign-conversion $(if $(subst Darwin,,$(SYSTEM)),,-Wno-shorten-64-to-32) $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,) $(LIBDIR)/$(CONFIG)/libares.a: $(ZLIB_DEP) $(LIBARES_OBJS) diff --git a/build.yaml b/build.yaml index 2237fe10cd8..9acd8e0bd61 100644 --- a/build.yaml +++ b/build.yaml @@ -4870,10 +4870,11 @@ defaults: ares: CFLAGS: -Wno-sign-conversion $(if $(subst Darwin,,$(SYSTEM)),,-Wno-shorten-64-to-32) $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,) - CPPFLAGS: -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) - $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden - $(if $(subst OpenBSD,,$(SYSTEM)),,-Ithird_party/cares/config_openbsd) -D_GNU_SOURCE - -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,) + CPPFLAGS: -Ithird_party/cares -Ithird_party/cares/cares -fvisibility=hidden -D_GNU_SOURCE + $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) $(if $(subst + FreeBSD,,$(SYSTEM)),,-Ithird_party/cares/config_freebsd) $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) + $(if $(subst OpenBSD,,$(SYSTEM)),,-Ithird_party/cares/config_openbsd) -DWIN32_LEAN_AND_MEAN + -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,) benchmark: CPPFLAGS: -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX boringssl: diff --git a/grpc.gemspec b/grpc.gemspec index 6b35d7a7c1d..85d2a2e393e 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1123,8 +1123,9 @@ Gem::Specification.new do |s| s.files += %w( third_party/cares/cares/config-win32.h ) s.files += %w( third_party/cares/cares/setup_once.h ) s.files += %w( third_party/cares/ares_build.h ) - s.files += %w( third_party/cares/config_linux/ares_config.h ) s.files += %w( third_party/cares/config_darwin/ares_config.h ) + s.files += %w( third_party/cares/config_freebsd/ares_config.h ) + s.files += %w( third_party/cares/config_linux/ares_config.h ) s.files += %w( third_party/cares/config_openbsd/ares_config.h ) s.files += %w( third_party/cares/cares/ares__close_sockets.c ) s.files += %w( third_party/cares/cares/ares__get_hostent.c ) diff --git a/setup.py b/setup.py index 5a85ed8545e..bf8aea6b6f2 100644 --- a/setup.py +++ b/setup.py @@ -40,10 +40,12 @@ ZLIB_INCLUDE = (os.path.join('third_party', 'zlib'),) CARES_INCLUDE = ( os.path.join('third_party', 'cares'), os.path.join('third_party', 'cares', 'cares'),) -if 'linux' in sys.platform: - CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_linux'),) if 'darwin' in sys.platform: CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_darwin'),) +if 'freebsd' in sys.platform: + CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_freebsd'),) +if 'linux' in sys.platform: + CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_linux'),) if 'openbsd' in sys.platform: CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_openbsd'),) README = os.path.join(PYTHON_STEM, 'README.rst') diff --git a/src/c-ares/gen_build_yaml.py b/src/c-ares/gen_build_yaml.py index b7707dc36da..4600d8d2241 100755 --- a/src/c-ares/gen_build_yaml.py +++ b/src/c-ares/gen_build_yaml.py @@ -29,10 +29,12 @@ try: subprocess.call("third_party/cares/cares/configure", shell=True) def config_platform(x): - if 'linux' in sys.platform: - return 'src/cares/cares/config_linux/ares_config.h' if 'darwin' in sys.platform: return 'src/cares/cares/config_darwin/ares_config.h' + if 'freebsd' in sys.platform: + return 'src/cares/cares/config_freebsd/ares_config.h' + if 'linux' in sys.platform: + return 'src/cares/cares/config_linux/ares_config.h' if 'openbsd' in sys.platform: return 'src/cares/cares/config_openbsd/ares_config.h' if not os.path.isfile('third_party/cares/cares/ares_config.h'): @@ -126,8 +128,9 @@ try: "third_party/cares/cares/config-win32.h", "third_party/cares/cares/setup_once.h", "third_party/cares/ares_build.h", - "third_party/cares/config_linux/ares_config.h", "third_party/cares/config_darwin/ares_config.h", + "third_party/cares/config_freebsd/ares_config.h", + "third_party/cares/config_linux/ares_config.h", "third_party/cares/config_openbsd/ares_config.h" ], }] diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index f3405b83465..cda7b5f5a8a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -7483,6 +7483,7 @@ "third_party/cares/cares/config-win32.h", "third_party/cares/cares/setup_once.h", "third_party/cares/config_darwin/ares_config.h", + "third_party/cares/config_freebsd/ares_config.h", "third_party/cares/config_linux/ares_config.h", "third_party/cares/config_openbsd/ares_config.h" ],