diff options
author | Nicolas Noble <nnoble@google.com> | 2014-11-26 16:33:03 -0800 |
---|---|---|
committer | Nicolas Noble <nnoble@google.com> | 2014-11-26 16:33:03 -0800 |
commit | b7ebd3b8c6fe39f99c40b10c1b563e4adb607b6c (patch) | |
tree | c1decf819492d455ec81cd471942c5516138f825 /test/core/fling | |
parent | 0e905e63db21bcdd85d3d1af051fcdc5bb5caa38 (diff) |
Initial import.
Diffstat (limited to 'test/core/fling')
-rw-r--r-- | test/core/fling/client.c | 196 | ||||
-rw-r--r-- | test/core/fling/fling_stream_test.c | 103 | ||||
-rw-r--r-- | test/core/fling/fling_test.c | 103 | ||||
-rw-r--r-- | test/core/fling/server.c | 159 |
4 files changed, 561 insertions, 0 deletions
diff --git a/test/core/fling/client.c b/test/core/fling/client.c new file mode 100644 index 0000000000..cc661c34c5 --- /dev/null +++ b/test/core/fling/client.c @@ -0,0 +1,196 @@ +/* + * + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <grpc/grpc.h> + +#include <stdio.h> +#include <string.h> + +#include <grpc/support/cmdline.h> +#include <grpc/support/histogram.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> +#include <grpc/support/useful.h> +#include "test/core/util/grpc_profiler.h" +#include "test/core/util/test_config.h" + +static gpr_histogram *histogram; +static grpc_byte_buffer *the_buffer; +static grpc_channel *channel; +static grpc_completion_queue *cq; +static grpc_call *call; + +static void init_ping_pong_request() {} + +static void step_ping_pong_request() { + call = grpc_channel_create_call(channel, "/Reflector/reflectUnary", + "localhost", gpr_inf_future); + GPR_ASSERT(grpc_call_start_invoke(call, cq, (void *)1, (void *)1, (void *)1, + GRPC_WRITE_BUFFER_HINT) == GRPC_CALL_OK); + grpc_event_finish(grpc_completion_queue_next(cq, gpr_inf_future)); + GPR_ASSERT(grpc_call_start_write(call, the_buffer, (void *)1, + GRPC_WRITE_BUFFER_HINT) == GRPC_CALL_OK); + grpc_event_finish(grpc_completion_queue_next(cq, gpr_inf_future)); + GPR_ASSERT(grpc_call_start_read(call, (void *)1) == GRPC_CALL_OK); + GPR_ASSERT(grpc_call_writes_done(call, (void *)1) == GRPC_CALL_OK); + grpc_event_finish(grpc_completion_queue_next(cq, gpr_inf_future)); + grpc_event_finish(grpc_completion_queue_next(cq, gpr_inf_future)); + grpc_event_finish(grpc_completion_queue_next(cq, gpr_inf_future)); + grpc_event_finish(grpc_completion_queue_next(cq, gpr_inf_future)); + grpc_call_destroy(call); + call = NULL; +} + +static void init_ping_pong_stream() { + call = grpc_channel_create_call(channel, "/Reflector/reflectStream", + "localhost", gpr_inf_future); + GPR_ASSERT(grpc_call_start_invoke(call, cq, (void *)1, (void *)1, (void *)1, + 0) == GRPC_CALL_OK); + grpc_event_finish(grpc_completion_queue_next(cq, gpr_inf_future)); + grpc_event_finish(grpc_completion_queue_next(cq, gpr_inf_future)); +} + +static void step_ping_pong_stream() { + GPR_ASSERT(grpc_call_start_write(call, the_buffer, (void *)1, 0) == + GRPC_CALL_OK); + GPR_ASSERT(grpc_call_start_read(call, (void *)1) == GRPC_CALL_OK); + grpc_event_finish(grpc_completion_queue_next(cq, gpr_inf_future)); + grpc_event_finish(grpc_completion_queue_next(cq, gpr_inf_future)); +} + +static double now() { + gpr_timespec tv = gpr_now(); + return 1e9 * tv.tv_sec + tv.tv_nsec; +} + +typedef struct { + const char *name; + void (*init)(); + void (*do_one_step)(); +} scenario; + +static const scenario scenarios[] = { + {"ping-pong-request", init_ping_pong_request, step_ping_pong_request}, + {"ping-pong-stream", init_ping_pong_stream, step_ping_pong_stream}, +}; + +int main(int argc, char **argv) { + gpr_slice slice = gpr_slice_from_copied_string("x"); + double start, stop; + int i; + + char *fake_argv[1]; + + int payload_size = 1; + int done; + int secure = 0; + char *target = "localhost:443"; + gpr_cmdline *cl; + char *scenario_name = "ping-pong-request"; + scenario sc = {NULL}; + + GPR_ASSERT(argc >= 1); + fake_argv[0] = argv[0]; + grpc_test_init(1, fake_argv); + + grpc_init(); + + cl = gpr_cmdline_create("fling client"); + gpr_cmdline_add_int(cl, "payload_size", "Size of the payload to send", + &payload_size); + gpr_cmdline_add_string(cl, "target", "Target host:port", &target); + gpr_cmdline_add_flag(cl, "secure", "Run with security?", &secure); + gpr_cmdline_add_string(cl, "scenario", "Scenario", &scenario_name); + gpr_cmdline_parse(cl, argc, argv); + gpr_cmdline_destroy(cl); + + for (i = 0; i < GPR_ARRAY_SIZE(scenarios); i++) { + if (0 == strcmp(scenarios[i].name, scenario_name)) { + sc = scenarios[i]; + } + } + if (!sc.name) { + fprintf(stderr, "unsupported scenario '%s'. Valid are:", scenario_name); + for (i = 0; i < GPR_ARRAY_SIZE(scenarios); i++) { + fprintf(stderr, " %s", scenarios[i].name); + } + return 1; + } + + channel = grpc_channel_create(target, NULL); + cq = grpc_completion_queue_create(); + the_buffer = grpc_byte_buffer_create(&slice, payload_size); + histogram = gpr_histogram_create(0.01, 60e9); + sc.init(); + + for (i = 0; i < 1000; i++) { + sc.do_one_step(); + } + + gpr_log(GPR_INFO, "start profiling"); + grpc_profiler_start("client.prof"); + for (i = 0; i < 100000; i++) { + start = now(); + sc.do_one_step(); + stop = now(); + gpr_histogram_add(histogram, stop - start); + } + grpc_profiler_stop(); + + if (call) { + grpc_call_destroy(call); + } + + grpc_channel_destroy(channel); + grpc_completion_queue_shutdown(cq); + done = 0; + while (!done) { + grpc_event *ev = grpc_completion_queue_next(cq, gpr_inf_future); + done = (ev->type == GRPC_QUEUE_SHUTDOWN); + grpc_event_finish(ev); + } + grpc_completion_queue_destroy(cq); + grpc_byte_buffer_destroy(the_buffer); + gpr_slice_unref(slice); + + gpr_log(GPR_INFO, "latency (50/95/99/99.9): %f/%f/%f/%f", + gpr_histogram_percentile(histogram, 50), + gpr_histogram_percentile(histogram, 95), + gpr_histogram_percentile(histogram, 99), + gpr_histogram_percentile(histogram, 99.9)); + gpr_histogram_destroy(histogram); + + grpc_shutdown(); + + return 0; +} diff --git a/test/core/fling/fling_stream_test.c b/test/core/fling/fling_stream_test.c new file mode 100644 index 0000000000..14a31eb26e --- /dev/null +++ b/test/core/fling/fling_stream_test.c @@ -0,0 +1,103 @@ +/* + * + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define _POSIX_SOURCE +#include <unistd.h> +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/host_port.h> +#include <grpc/support/string.h> +#include "test/core/util/port.h" + +int main(int argc, char **argv) { + char *me = argv[0]; + char *lslash = strrchr(me, '/'); + char root[1024]; + int port = grpc_pick_unused_port_or_die(); + char *args[10]; + int status; + pid_t svr, cli; + /* figure out where we are */ + if (lslash) { + memcpy(root, me, lslash - me); + root[lslash - me] = 0; + } else { + strcpy(root, "."); + } + /* start the server */ + svr = fork(); + if (svr == 0) { + gpr_asprintf(&args[0], "%s/fling_server", root); + args[1] = "--bind"; + gpr_join_host_port(&args[2], "::", port); + args[3] = "--no-secure"; + args[4] = 0; + execv(args[0], args); + + gpr_free(args[0]); + gpr_free(args[2]); + return 1; + } + /* wait a little */ + sleep(2); + /* start the client */ + cli = fork(); + if (cli == 0) { + gpr_asprintf(&args[0], "%s/fling_client", root); + args[1] = "--target"; + gpr_join_host_port(&args[2], "127.0.0.1", port); + args[3] = "--scenario=ping-pong-stream"; + args[4] = "--no-secure"; + args[5] = 0; + execv(args[0], args); + + gpr_free(args[0]); + gpr_free(args[2]); + return 1; + } + /* wait for completion */ + printf("waiting for client\n"); + if (waitpid(cli, &status, 0) == -1) return 2; + if (!WIFEXITED(status)) return 4; + if (WEXITSTATUS(status)) return WEXITSTATUS(status); + printf("checking server\n"); + if (waitpid(svr, &status, WNOHANG) != 0) return 2; + kill(svr, SIGKILL); + return 0; +} diff --git a/test/core/fling/fling_test.c b/test/core/fling/fling_test.c new file mode 100644 index 0000000000..e5e63f9076 --- /dev/null +++ b/test/core/fling/fling_test.c @@ -0,0 +1,103 @@ +/* + * + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define _POSIX_SOURCE +#include <unistd.h> +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/host_port.h> +#include <grpc/support/string.h> +#include "test/core/util/port.h" + +int main(int argc, char **argv) { + char *me = argv[0]; + char *lslash = strrchr(me, '/'); + char root[1024]; + int port = grpc_pick_unused_port_or_die(); + char *args[10]; + int status; + pid_t svr, cli; + /* figure out where we are */ + if (lslash) { + memcpy(root, me, lslash - me); + root[lslash - me] = 0; + } else { + strcpy(root, "."); + } + /* start the server */ + svr = fork(); + if (svr == 0) { + gpr_asprintf(&args[0], "%s/fling_server", root); + args[1] = "--bind"; + gpr_join_host_port(&args[2], "::", port); + args[3] = "--no-secure"; + args[4] = 0; + execv(args[0], args); + + gpr_free(args[0]); + gpr_free(args[2]); + return 1; + } + /* wait a little */ + sleep(2); + /* start the client */ + cli = fork(); + if (cli == 0) { + gpr_asprintf(&args[0], "%s/fling_client", root); + args[1] = "--target"; + gpr_join_host_port(&args[2], "127.0.0.1", port); + args[3] = "--scenario=ping-pong-request"; + args[4] = "--no-secure"; + args[5] = 0; + execv(args[0], args); + + gpr_free(args[0]); + gpr_free(args[2]); + return 1; + } + /* wait for completion */ + printf("waiting for client\n"); + if (waitpid(cli, &status, 0) == -1) return 2; + if (!WIFEXITED(status)) return 4; + if (WEXITSTATUS(status)) return WEXITSTATUS(status); + printf("checking server\n"); + if (waitpid(svr, &status, WNOHANG) != 0) return 2; + kill(svr, SIGKILL); + return 0; +} diff --git a/test/core/fling/server.c b/test/core/fling/server.c new file mode 100644 index 0000000000..7a5d89598d --- /dev/null +++ b/test/core/fling/server.c @@ -0,0 +1,159 @@ +/* + * + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <grpc/grpc.h> + +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "test/core/util/grpc_profiler.h" +#include "test/core/util/test_config.h" +#include <grpc/support/alloc.h> +#include <grpc/support/cmdline.h> +#include <grpc/support/host_port.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> +#include "test/core/util/port.h" + +static grpc_completion_queue *cq; +static grpc_server *server; +static int done = 0; + +static const grpc_status status_ok = {GRPC_STATUS_OK, NULL}; + +typedef struct { + gpr_refcount pending_ops; + gpr_uint32 flags; +} call_state; + +static void request_call() { + call_state *s = gpr_malloc(sizeof(call_state)); + gpr_ref_init(&s->pending_ops, 2); + grpc_server_request_call(server, s); +} + +static void sigint_handler(int x) { done = 1; } + +int main(int argc, char **argv) { + grpc_event *ev; + call_state *s; + char *addr_buf = NULL; + gpr_cmdline *cl; + + int secure = 0; + char *addr = NULL; + + char *fake_argv[1]; + + GPR_ASSERT(argc >= 1); + fake_argv[0] = argv[0]; + grpc_test_init(1, fake_argv); + + grpc_init(); + srand(clock()); + + cl = gpr_cmdline_create("fling server"); + gpr_cmdline_add_string(cl, "bind", "Bind host:port", &addr); + gpr_cmdline_add_flag(cl, "secure", "Run with security?", &secure); + gpr_cmdline_parse(cl, argc, argv); + gpr_cmdline_destroy(cl); + + if (addr == NULL) { + gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die()); + addr = addr_buf; + } + gpr_log(GPR_INFO, "creating server on: %s", addr); + + cq = grpc_completion_queue_create(); + server = grpc_server_create(cq, NULL); + GPR_ASSERT(grpc_server_add_http2_port(server, addr)); + grpc_server_start(server); + + gpr_free(addr_buf); + addr = addr_buf = NULL; + + request_call(); + + grpc_profiler_start("server.prof"); + signal(SIGINT, sigint_handler); + while (!done) { + ev = grpc_completion_queue_next( + cq, gpr_time_add(gpr_now(), gpr_time_from_micros(1000000))); + if (!ev) continue; + s = ev->tag; + switch (ev->type) { + case GRPC_SERVER_RPC_NEW: + /* initial ops are already started in request_call */ + if (0 == strcmp(ev->data.server_rpc_new.method, + "/Reflector/reflectStream")) { + s->flags = 0; + } else { + s->flags = GRPC_WRITE_BUFFER_HINT; + } + grpc_call_accept(ev->call, cq, s, s->flags); + GPR_ASSERT(grpc_call_start_read(ev->call, s) == GRPC_CALL_OK); + request_call(); + break; + case GRPC_WRITE_ACCEPTED: + GPR_ASSERT(ev->data.write_accepted == GRPC_OP_OK); + GPR_ASSERT(grpc_call_start_read(ev->call, s) == GRPC_CALL_OK); + break; + case GRPC_READ: + if (ev->data.read) { + GPR_ASSERT(grpc_call_start_write(ev->call, ev->data.read, s, + s->flags) == GRPC_CALL_OK); + } else { + GPR_ASSERT(grpc_call_start_write_status(ev->call, status_ok, s) == + GRPC_CALL_OK); + } + break; + case GRPC_FINISH_ACCEPTED: + case GRPC_FINISHED: + if (gpr_unref(&s->pending_ops)) { + grpc_call_destroy(ev->call); + gpr_free(s); + } + break; + default: + abort(); + } + grpc_event_finish(ev); + } + grpc_profiler_stop(); + + grpc_shutdown(); + return 0; +} |