diff options
author | 2016-10-07 09:55:35 -0700 | |
---|---|---|
committer | 2016-10-07 09:55:35 -0700 | |
commit | 2c287ca750c114c7230e57a1231d7e22863ab53d (patch) | |
tree | 2c74c603ba071ccb3c0ab64e2494d28f641d2cac /test/core | |
parent | eebb129fd39c050a9d3b325fcd89df8aadb09218 (diff) |
UV tests pass on linux
Diffstat (limited to 'test/core')
-rwxr-xr-x | test/core/bad_client/gen_build_yaml.py | 1 | ||||
-rw-r--r-- | test/core/end2end/cq_verifier.c | 46 | ||||
-rw-r--r-- | test/core/end2end/cq_verifier_uv.c | 7 | ||||
-rwxr-xr-x | test/core/end2end/gen_build_yaml.py | 38 | ||||
-rw-r--r-- | test/core/util/port_server_client.c | 2 | ||||
-rw-r--r-- | test/core/util/port_uv.c | 69 |
6 files changed, 128 insertions, 35 deletions
diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index fb86525b1a..32ab3f2137 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -83,6 +83,7 @@ def main(): 'secure': 'no', 'src': ['test/core/bad_client/tests/%s.c' % t], 'vs_proj_dir': 'test', + 'exclude_iomgrs': ['uv'], 'deps': [ 'bad_client_test', 'grpc_test_util_unsecure', diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 9e6c0a4f4c..1f42d3457e 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -32,7 +32,6 @@ */ #include "test/core/end2end/cq_verifier.h" -#include "test/core/end2end/cq_verifier_internal.h" #include <stdarg.h> #include <stdio.h> @@ -60,15 +59,35 @@ typedef struct metadata { /* details what we expect to find on a single event - and forms a linked list to detail other expectations */ -struct expectation { +typedef struct expectation { struct expectation *next; const char *file; int line; grpc_completion_type type; void *tag; int success; +} expectation; + +/* the verifier itself */ +struct cq_verifier { + /* bound completion queue */ + grpc_completion_queue *cq; + /* start of expectation list */ + expectation *first_expectation; }; +cq_verifier *cq_verifier_create(grpc_completion_queue *cq) { + cq_verifier *v = gpr_malloc(sizeof(cq_verifier)); + v->cq = cq; + v->first_expectation = NULL; + return v; +} + +void cq_verifier_destroy(cq_verifier *v) { + cq_verify(v); + gpr_free(v); +} + static int has_metadata(const grpc_metadata *md, size_t count, const char *key, const char *value) { size_t i; @@ -178,7 +197,7 @@ static void expectation_to_strvec(gpr_strvec *buf, expectation *e) { static void expectations_to_strvec(gpr_strvec *buf, cq_verifier *v) { expectation *e; - for (e = cq_verifier_get_first_expectation(v); e != NULL; e = e->next) { + for (e = v->first_expectation; e != NULL; e = e->next) { expectation_to_strvec(buf, e); gpr_strvec_add(buf, gpr_strdup("\n")); } @@ -198,19 +217,19 @@ static void fail_no_event_received(cq_verifier *v) { } void cq_verify(cq_verifier *v) { - int timeout_seconds = 10; - while (cq_verifier_get_first_expectation(v) != NULL) { - grpc_event ev = cq_verifier_next_event(v, timeout_seconds); + const gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); + while (v->first_expectation != NULL) { + grpc_event ev = grpc_completion_queue_next(v->cq, deadline, NULL); if (ev.type == GRPC_QUEUE_TIMEOUT) { fail_no_event_received(v); break; } expectation *e; expectation *prev = NULL; - for (e = cq_verifier_get_first_expectation(v); e != NULL; e = e->next) { + for (e = v->first_expectation; e != NULL; e = e->next) { if (e->tag == ev.tag) { verify_matches(e, &ev); - if (e == cq_verifier_get_first_expectation(v)) cq_verifier_set_first_expectation(v, e->next); + if (e == v->first_expectation) v->first_expectation = e->next; if (prev != NULL) prev->next = e->next; gpr_free(e); break; @@ -234,11 +253,14 @@ void cq_verify(cq_verifier *v) { } void cq_verify_empty_timeout(cq_verifier *v, int timeout_sec) { + gpr_timespec deadline = + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(timeout_sec, GPR_TIMESPAN)); grpc_event ev; - GPR_ASSERT(cq_verifier_get_first_expectation(v) == NULL && "expectation queue must be empty"); + GPR_ASSERT(v->first_expectation == NULL && "expectation queue must be empty"); - ev = cq_verifier_next_event(v, timeout_sec); + ev = grpc_completion_queue_next(v->cq, deadline, NULL); if (ev.type != GRPC_QUEUE_TIMEOUT) { char *s = grpc_event_string(&ev); gpr_log(GPR_ERROR, "unexpected event (expected nothing): %s", s); @@ -257,8 +279,8 @@ static void add(cq_verifier *v, const char *file, int line, e->line = line; e->tag = tag; e->success = success; - e->next = cq_verifier_get_first_expectation(v); - cq_verifier_set_first_expectation(v, e); + e->next = v->first_expectation; + v->first_expectation = e; } void cq_expect_completion(cq_verifier *v, const char *file, int line, void *tag, diff --git a/test/core/end2end/cq_verifier_uv.c b/test/core/end2end/cq_verifier_uv.c index 329dacf97e..74ac673f20 100644 --- a/test/core/end2end/cq_verifier_uv.c +++ b/test/core/end2end/cq_verifier_uv.c @@ -38,6 +38,7 @@ #include <uv.h> #include <grpc/support/alloc.h> +#include <grpc/support/log.h> #include "test/core/end2end/cq_verifier_internal.h" @@ -65,7 +66,7 @@ cq_verifier *cq_verifier_create(grpc_completion_queue *cq) { return v; } -void timer_close_cb(uv_handle_t *handle) { +static void timer_close_cb(uv_handle_t *handle) { handle->data = (void *)TIMER_CLOSED; } @@ -86,12 +87,12 @@ void cq_verifier_set_first_expectation(cq_verifier *v, expectation *e) { v->first_expectation = e; } -void timer_run_cb(uv_timer_t *timer) { +static void timer_run_cb(uv_timer_t *timer) { timer->data = (void *)TIMER_TRIGGERED; } grpc_event cq_verifier_next_event(cq_verifier *v, int timeout_seconds) { -uint64_t timeout_ms = timeout_seconds < 0 ? 0 : (uint64_t)timeout_seconds * 1000; + uint64_t timeout_ms = timeout_seconds < 0 ? 0 : (uint64_t)timeout_seconds * 1000; grpc_event ev; v->timer.data = (void *)TIMER_STARTED; uv_timer_start(&v->timer, timer_run_cb, timeout_ms, 0); diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index c2040c00d8..3ea827f67e 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -44,14 +44,15 @@ default_unsecure_fixture_options = FixtureOptions( True, False, True, False, ['windows', 'linux', 'mac', 'posix'], True, False, [], []) socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace(fullstack=False, dns_resolver=False) default_secure_fixture_options = default_unsecure_fixture_options._replace(secure=True) -uds_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, platforms=['linux', 'mac', 'posix']) +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']) + dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv']) # maps fixture name to whether it requires the security library END2END_FIXTURES = { 'h2_compress': default_unsecure_fixture_options, + 'h2_census': default_unsecure_fixture_options, 'h2_load_reporting': default_unsecure_fixture_options, 'h2_fakesec': default_secure_fixture_options._replace(ci_mac=False), @@ -60,26 +61,29 @@ END2END_FIXTURES = { 'h2_full+pipe': default_unsecure_fixture_options._replace( platforms=['linux'], exclude_iomgrs=['uv']), 'h2_full+trace': default_unsecure_fixture_options._replace(tracing=True), - 'h2_http_proxy': default_unsecure_fixture_options._replace(ci_mac=False), - 'h2_oauth2': default_secure_fixture_options._replace(ci_mac=False), - 'h2_proxy': default_unsecure_fixture_options._replace(includes_proxy=True, - ci_mac=False), + 'h2_http_proxy': default_unsecure_fixture_options._replace( + ci_mac=False, exclude_iomgrs=['uv']), + 'h2_oauth2': default_secure_fixture_options._replace( + ci_mac=False, exclude_iomgrs=['uv']), + 'h2_proxy': default_unsecure_fixture_options._replace( + includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']), 'h2_sockpair_1byte': socketpair_unsecure_fixture_options._replace( - ci_mac=False, exclude_configs=['msan']), - 'h2_sockpair': socketpair_unsecure_fixture_options._replace(ci_mac=False), + ci_mac=False, exclude_configs=['msan'], exclude_iomgrs=['uv']), + 'h2_sockpair': socketpair_unsecure_fixture_options._replace( + ci_mac=False, exclude_iomgrs=['uv']), 'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace( - ci_mac=False, tracing=True), + ci_mac=False, tracing=True, 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), + 'h2_ssl_proxy': default_secure_fixture_options._replace( + includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']), 'h2_uds': uds_fixture_options, } TestOptions = collections.namedtuple( 'TestOptions', - 'needs_fullstack needs_dns proxyable secure traceable cpu_cost') -default_test_options = TestOptions(False, False, True, False, True, 1.0) + 'needs_fullstack needs_dns proxyable secure traceable cpu_cost exclude_iomgrs') +default_test_options = TestOptions(False, False, True, False, True, 1.0, []) connectivity_test_options = default_test_options._replace(needs_fullstack=True) LOWCPU = 0.1 @@ -96,8 +100,8 @@ END2END_TESTS = { 'cancel_in_a_vacuum': default_test_options._replace(cpu_cost=LOWCPU), 'cancel_with_status': default_test_options._replace(cpu_cost=LOWCPU), 'compressed_payload': default_test_options._replace(proxyable=False), - 'connectivity': connectivity_test_options._replace(proxyable=False, - cpu_cost=LOWCPU), + 'connectivity': connectivity_test_options._replace( + proxyable=False, cpu_cost=LOWCPU, exclude_iomgrs=['uv']), 'default_host': default_test_options._replace(needs_fullstack=True, needs_dns=True), 'disappearing_server': connectivity_test_options, @@ -246,6 +250,8 @@ def main(): 'name': '%s_test' % f, 'args': [t], 'exclude_configs': [], + 'exclude_iomgrs': list(set(END2END_FIXTURES[f].exclude_iomgrs) | + set(END2END_TESTS[t].exclude_iomgrs)), 'platforms': END2END_FIXTURES[f].platforms, 'ci_platforms': (END2END_FIXTURES[f].platforms if END2END_FIXTURES[f].ci_mac else without( @@ -261,6 +267,8 @@ def main(): 'name': '%s_nosec_test' % f, 'args': [t], 'exclude_configs': END2END_FIXTURES[f].exclude_configs, + 'exclude_iomgrs': list(set(END2END_FIXTURES[f].exclude_iomgrs) | + set(END2END_TESTS[t].exclude_iomgrs)), 'platforms': END2END_FIXTURES[f].platforms, 'ci_platforms': (END2END_FIXTURES[f].platforms if END2END_FIXTURES[f].ci_mac else without( diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c index d4a11c1e93..a5c8c49650 100644 --- a/test/core/util/port_server_client.c +++ b/test/core/util/port_server_client.c @@ -80,7 +80,7 @@ void grpc_free_port_using_server(char *server, int port) { grpc_httpcli_response rsp; freereq pr; char *path; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_RUN_INNER_LOOP; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_closure *shutdown_closure; grpc_init(); diff --git a/test/core/util/port_uv.c b/test/core/util/port_uv.c index e6d37caf98..cab31b3f4e 100644 --- a/test/core/util/port_uv.c +++ b/test/core/util/port_uv.c @@ -35,13 +35,75 @@ #include "test/core/util/test_config.h" #if defined(GRPC_UV) && defined(GRPC_TEST_PICK_PORT) +#include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include "src/core/lib/support/env.h" #include "test/core/util/port.h" +#include "test/core/util/port_server_client.h" + +// Almost everything in this file has been copied from port_posix.c + +static int *chosen_ports = NULL; +static size_t num_chosen_ports = 0; + +static int free_chosen_port(int port) { + size_t i; + int found = 0; + size_t found_at = 0; + char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); + /* Find the port and erase it from the list, then tell the server it can be + freed. */ + for (i = 0; i < num_chosen_ports; i++) { + if (chosen_ports[i] == port) { + GPR_ASSERT(found == 0); + found = 1; + found_at = i; + } + } + if (found) { + chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1]; + num_chosen_ports--; + if (env) { + grpc_free_port_using_server(env, port); + } + } + gpr_free(env); + return found; +} + +static void free_chosen_ports(void) { + char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); + if (env != NULL) { + size_t i; + for (i = 0; i < num_chosen_ports; i++) { + grpc_free_port_using_server(env, chosen_ports[i]); + } + gpr_free(env); + } + + gpr_free(chosen_ports); +} + +static void chose_port(int port) { + if (chosen_ports == NULL) { + atexit(free_chosen_ports); + } + num_chosen_ports++; + chosen_ports = gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports); + chosen_ports[num_chosen_ports - 1] = port; +} int grpc_pick_unused_port(void) { - // Temporary implementation - return 4242; + // Currently only works with the port server + char *env = gpr_getenv("GRPC_TEST_PORT_SERVER"); + GPR_ASSERT(env); + int port = grpc_pick_port_using_server(env); + gpr_free(env); + if (port != 0) { + chose_port(port); + } + return port; } int grpc_pick_unused_port_or_die(void) { @@ -51,8 +113,7 @@ int grpc_pick_unused_port_or_die(void) { } void grpc_recycle_unused_port(int port) { - // Temporary implementation - (void)port; + GPR_ASSERT(free_chosen_port(port)); } #endif /* GRPC_UV && GRPC_TEST_PICK_PORT */ |