diff options
author | nnoble <nnoble@google.com> | 2014-12-05 15:37:39 -0800 |
---|---|---|
committer | Nicolas Noble <nnoble@google.com> | 2014-12-05 16:00:44 -0800 |
commit | 0c475f0ad78e5848438e1a690b826fe0b6eb26fe (patch) | |
tree | be51d7426861d387109899e8190a3912bd8dc2fc /test/core | |
parent | 03dc30e76e2a241e921df429b5b4e078bb295067 (diff) |
Updating moe_db.txt with the latest equivalence since the ruby import changed the exported structure.
Change on 2014/12/01 by nnoble <nnoble@google.com>
-------------
new [] file for grpc testing.
Change on 2014/12/02 by donnadionne <donnadionne@google.com>
-------------
Fix unfinished calls in thread_stress_test.
Previously we had an early return if we cancelled a stream part way through a
message. Correct this, so that half close and full close signals are propagated
up the stack correctly so that higher level state machines can see the
termination.
Change on 2014/12/02 by ctiller <ctiller@google.com>
-------------
Remove dependency on internal C code.
Change on 2014/12/02 by ctiller <ctiller@google.com>
-------------
Turn off the flaky bit from thread_stress_test.
Change on 2014/12/02 by ctiller <ctiller@google.com>
-------------
Add test cases of empty request/response, request streaming, response streaming, and half duplex streaming.
Bring up the GFE/ESF for mannual test:
[] build java/com/google/net/[]/testing/integration/hexa:server_components_env
[]-bin/java/com/google/net/[]/testing/integration/hexa/server_components_env --manual --rpc_port=25000 --use_autobahn
Change on 2014/12/02 by chenw <chenw@google.com>
-------------
Make echo/server.c and fling/server.c shutdown cleanly on SIGINT, and update
the relevant tests to exercise this mechanism.
Now "[] coverage" and the memory leak detector are able to see into the
server processes.
Change on 2014/12/02 by pmarks <pmarks@google.com>
-------------
Allow the # of channels to be configurable in this performance test. The threads will use the channels in statically-defined round-robin order (not based on when RPCs complete on any channel). The interesting cases are #channels=1 or #channels=#threads (we previously only had the latter case)
Change on 2014/12/02 by vpai <vpai@google.com>
-------------
Fixed a typo and reworded a comment.
Change on 2014/12/02 by gnezdo <gnezdo@google.com>
-------------
Require the grpc_call in this ClientContext to be NULL before allowing set_call to be invoked. Otherwise, it's an indication of a leak somewhere.
Change on 2014/12/02 by vpai <vpai@google.com>
-------------
Correctly return status other than ok and add a test for it.
Change on 2014/12/02 by yangg <yangg@google.com>
-------------
Better C++ guards for grpc_security.h
Change on 2014/12/02 by nnoble <nnoble@google.com>
-------------
Use nullptr instead of NULL for consistency.
Change on 2014/12/02 by vpai <vpai@google.com>
-------------
Updates the ruby gRPC service class to require the serialization method to be
a static method
- this brings it inline with the proto3 ruby API
- it adds a monkey patch to allow existing proto (beefcake) to continue working.
Change on 2014/12/02 by temiola <temiola@google.com>
-------------
Adding a buildable unit to the blue print file.
Added the buildable unit as its name will be usesd as tap project id.
This test will fail right away in tap until tests are actually added.
Change on 2014/12/02 by donnadionne <donnadionne@google.com>
-------------
Move interop ESF C++ server from Java to grpc directory.
Tests passed:
[] test javatests/com/google/net/[]/testing/integration/hexa/...
[] test net/grpc/testing/interop/esf_server/...
Change on 2014/12/02 by chenw <chenw@google.com>
-------------
Return a lame channel as opposed to NULL when secure channel creation fails.
- Looks like we're going to need something similar server-side.
- I changed the prototype of the lame client channel factory to take an
explicit void as I think this is better practice in C. Let me know if you
disagree and I will revert these changes.
Change on 2014/12/02 by jboeuf <jboeuf@google.com>
-------------
Putting ALPN support where it belongs.
Change on 2014/12/02 by jboeuf <jboeuf@google.com>
-------------
GOAWAY send path.
Sends a GOAWAY frame when shutting down.
This is not read and understood yet.
Change on 2014/12/03 by ctiller <ctiller@google.com>
-------------
Adds support for secure channels and servers.
- wraps new C apis (credentials, server_credentials) and Server#add_secure_http_port
- adds tests to ensure credentials and server credentials can be created
- updates client_server_spec to run the client_server wrapper layer end-to-end tests using a secure channel
Change on 2014/12/03 by temiola <temiola@google.com>
-------------
Fix existing issues regarding out of order events.
At the client side, using pluck as the client_metadata_read can happen anytime after invoke.
At the server side, allow halfclose_ok and rpc_end to come in reverse order.
Change on 2014/12/03 by yangg <yangg@google.com>
-------------
Don't track coverage of tests.
Change on 2014/12/03 by ctiller <ctiller@google.com>
-------------
Change UnaryCall to conform standard test requirement of LargeUnaryCall.
Change on 2014/12/03 by yangg <yangg@google.com>
-------------
updating alpn version to h2-15 ensure all interop are on the same version and working.
Java and go are not ready for h2-16 yet.
Change on 2014/12/03 by donnadionne <donnadionne@google.com>
-------------
Add config to bring echo server in [].
This is used to test production GFE as its bckend.
Change on 2014/12/03 by chenw <chenw@google.com>
-------------
In preparation for fixing shutdown race issues, change em to take ownership of
the file descriptor. Add an API to grpc_tcp to take an already created
grpc_em_fd object, and change tcp_client to use that API.
This is needed because otherwise an em user's close() of the file descriptor
may race with libevent internals. That's not an issue yet because destroy()
frees the events inline, but that can't be done safely if there is a concurrent
poller.
Change on 2014/12/03 by klempner <klempner@google.com>
-------------
Fixing TAP opensource build
We don't want to compile and run C++ tests in the C target.
Change on 2014/12/03 by nnoble <nnoble@google.com>
-------------
Move and separate interop tests by languages.
Small fixes to the test runner.
Improving logging.
Change on 2014/12/03 by donnadionne <donnadionne@google.com>
-------------
Fixing the opensource build:
-) The C/C++ split wasn't done up to the 'dep' target level
-) The alpn.c file was missing from build.json
Change on 2014/12/03 by nnoble <nnoble@google.com>
-------------
Adding blue print files after projects exist
Change on 2014/12/03 by donnadionne <donnadionne@google.com>
-------------
Refactor StreamContext using the new completion_queue_pluck API.
The dedicated the poller thread has been removed.
This CL keeps the current behavior to make it short. There is one following to
make it usable for both client and server.
The tags for pluck is based on the address of this StreamContext object for potential debug use.
The Read/Write and Wait cannot be called concurrently now and this might need to be fixed.
Change on 2014/12/03 by yangg <yangg@google.com>
-------------
Binary encoding utilities.
Support base64 encoding, HPACK static huffman encoding, and doing both at once.
Change on 2014/12/03 by ctiller <ctiller@google.com>
-------------
Enforce Makefile regeneration in presubmits.
Change on 2014/12/03 by ctiller <ctiller@google.com>
-------------
Make CloseSend() send a real zero-length control message to indicate EOS.
Change on 2014/12/03 by zhaoq <zhaoq@google.com>
-------------
Prefer to create dualstack sockets for TCP clients and servers, with automatic
fallback for environments where IPV6_V6ONLY can't be turned off.
Change on 2014/12/03 by pmarks <pmarks@google.com>
-------------
Add opensource path to build targets.
Ensure that MOE is going to run.
Change on 2014/12/03 by ctiller <ctiller@google.com>
-------------
Add PingPong test case. Delete FullDuplex test case. The latter is not specified for client in
https://docs.google.com/document/d/1dwrPpIu5EqiKVsquZfoOqTj7vP8fa1i49gornJo50Qw/edit#
Change on 2014/12/03 by chenw <chenw@google.com>
-------------
Make generate_projects.sh check out the generated targets.
Change on 2014/12/03 by ctiller <ctiller@google.com>
-------------
rspec cleanup
- stops declaring specs within the GRPC module
- splits Bidi streaming specs into a separate test suite
adding tests in the GRPC module was a mistake, it pollutes the module and can
affect other tests that run later by the test runner
the bidi tests are currently flaky, having them run in their own test suite
allows having two separate continuous builds (once ruby gRPC is on GitHub),
one that includes bidi where we tolerate flakiness, and another that does not,
where there should be no flakiness at all
Change on 2014/12/03 by temiola <temiola@google.com>
-------------
Adding support for composite and IAM credentials.
- For now, we don't do any checks on credentials compatibility in the
composite credentials. Maybe we'll add that later.
- Refactored the end to end security tests so that we always use the public API
(except for the fake security context which is not exposed).
Change on 2014/12/03 by jboeuf <jboeuf@google.com>
-------------
Make GPR library buildable in Visual Studio 2013.
Change on 2014/12/04 by jtattermusch <jtattermusch@google.com>
-------------
Adds codegen for ruby
This is being added now that ruby's proto and grpc apis are defined and stable
Change on 2014/12/04 by temiola <temiola@google.com>
-------------
Prevent NewStream() from sending negative or 0 timeout.
Change on 2014/12/04 by zhaoq <zhaoq@google.com>
-------------
Add a grpc_sockaddr_to_string() function, and use it when logging bind
failures. Also improve const-correctness in some earlier code.
I'm not certain whether inet_ntop() will need any platform-specific
implementations, but for now the compiler offers no complaints.
Demo:
$ []-bin/net/grpc/c/echo_server 1.2.3.4:80
... tcp_server.c:139] bind addr=[::ffff:1.2.3.4]:80: Permission denied
Change on 2014/12/04 by pmarks <pmarks@google.com>
-------------
Refactoring - moves c wrapped classes to a submodule Google::RPC::Core
- this allows for an explicit rule when reading through gRPC ruby code for telling
when an object is pure ruby or wrapped C
Change on 2014/12/04 by temiola <temiola@google.com>
-------------
Fixes the bidi_call
[]
Change on 2014/12/04 by temiola <temiola@google.com>
-------------
Fixing dev build when activating surface traces.
Change on 2014/12/04 by nnoble <nnoble@google.com>
-------------
Updates the tests to reflect that fact that some Credentials compose works.
Change on 2014/12/04 by temiola <temiola@google.com>
-------------
Making the generate_project_test actually do something.
Change on 2014/12/04 by nnoble <nnoble@google.com>
-------------
Rename "esf_server" to "[]4_server". Delete "test_sever" from Java directory.
Change on 2014/12/04 by chenw <chenw@google.com>
-------------
Added PHP client interop tests. Tested large_unary against the C++ server.
Change on 2014/12/04 by mlumish <mlumish@google.com>
-------------
Refactor grpc_create_dualstack_socket() by pulling the setsockopt into its own
function. This separates the magic test flag from the real fallback logic.
Change on 2014/12/04 by pmarks <pmarks@google.com>
-------------
Fixes the type of the constant used for test cert hostname
Change on 2014/12/04 by temiola <temiola@google.com>
-------------
Disabling these tests as they're causing flakiness.
Change on 2014/12/04 by ctiller <ctiller@google.com>
-------------
Change intptr --> uintptr.
Handles the case where a void* turns into a negative number, which then gets
hashed into a negative bucket and segfaults.
Change on 2014/12/04 by ctiller <ctiller@google.com>
-------------
Add a test fixture to force parsers to handle one byte at a time.
This should expand coverage and hopefully prevent errors at some point (it
seems to pass out of the box for now though).
Change on 2014/12/04 by ctiller <ctiller@google.com>
-------------
The code generator isn't +x.
Change on 2014/12/04 by ctiller <ctiller@google.com>
-------------
Updates math_client and math_server to allow construction using crednetials
By:
- Extending rpc_server constructor so that it takes a credentials keyword param
- Extending client_stub constructor so that it takes a credentials keyword param
Change on 2014/12/04 by temiola <temiola@google.com>
-------------
Format output a little more nicely.
Print each line of output separately - previously logging.info was truncating this at some maximum length, and logs were getting lost.
Change on 2014/12/04 by ctiller <ctiller@google.com>
-------------
Up timeout for this test.
Under TSAN, if we process one byte at a time, this timeout can be reached - and I think this is the cause of the following flake:
[]
Change on 2014/12/05 by ctiller <ctiller@google.com>
-------------
Adding more error logging for ssl.
Change on 2014/12/05 by jboeuf <jboeuf@google.com>
-------------
Read path for goaway.
Still need to add hooks to deprecate a channel on the client side when goaway
is received.
Change on 2014/12/05 by ctiller <ctiller@google.com>
-------------
Separate accept() into server_accept() and server_end_of_initial_metadata().
This allows servers to initiate reads before finishing writing metadata.
Change on 2014/12/05 by ctiller <ctiller@google.com>
-------------
Fix for breakage 11512317 - adding missing test files.
Change on 2014/12/05 by nnoble <nnoble@google.com>
-------------
grpc c++ server side streaming support.
This is based on [] There is a lot of room to clean up the internal implementation which may require refactoring of CompletionQueue. The current cl serves as a working implementation with the missing interfaces.
The sample generated files are included and will be removed before submitting.
Change on 2014/12/05 by yangg <yangg@google.com>
-------------
Changed to the latest timeout format again (search "grpc-timeout" in [] for the spec).
Change on 2014/12/05 by zhaoq <zhaoq@google.com>
-------------
Fixing opensource build.
Change on 2014/12/05 by nnoble <nnoble@google.com>
-------------
Making absolutely sure we can do the moe export by adding a sh_test for it.
Change on 2014/12/05 by nnoble <nnoble@google.com>
-------------
Change :scheme psuedo-header from "grpc" to "http" or "https".
Change on 2014/12/05 by zhaoq <zhaoq@google.com>
-------------
Add server credential wrapping for c++ server. It only wraps ssl and []2 for now.
The ServerCredentials class and the factory class are in a similar fashion as
client side wrapping. The difference is the factory method returns shared_ptr
instead of unique_ptr as the server builder needs to keep a reference to it for
actually creating the server later.
The integration will happen in a following cl.
Change on 2014/12/05 by yangg <yangg@google.com>
-------------
Fixed bugs in new_grpc_docker_builder.sh
Change on 2014/12/05 by mlumish <mlumish@google.com>
-------------
In secure endpoint, hold a refcount for the life of a write callback if the
write does not complete immediately.
Change on 2014/12/05 by klempner <klempner@google.com>
-------------
Add migration support to MOE and have TAP verify it doesn't break.
Migration support allows mirroring commits from [] into the git repo, instead of just a dump of the current source.
Change on 2014/12/05 by ejona <ejona@google.com>
-------------
Change initial window size to 65535 according http2 draft 15.
Change on 2014/12/05 by zhaoq <zhaoq@google.com>
-------------
Re-enable the flaky cases in dualstack_socket_test, with additional logging to
help track down the problem if it surfaces again.
This also seems like a good opportunity to make grpc_socket_utils a separate
library, as it's not really specific to TCP.
Example output:
logspam: [], 26570) resolved 2 addrs in 37ms:
logspam: [0] [::1]:26570
logspam: [1] 127.0.0.1:26570
Change on 2014/12/05 by pmarks <pmarks@google.com>
-------------
Opensource build fixes.
-) A function that has a return type should actually return something.
-) Don't pass unsigned chars to strlen and strncmp.
Change on 2014/12/05 by nnoble <nnoble@google.com>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=81458281
Diffstat (limited to 'test/core')
21 files changed, 1090 insertions, 70 deletions
diff --git a/test/core/echo/echo_test.c b/test/core/echo/echo_test.c index c699f1e83e..bbce9da846 100644 --- a/test/core/echo/echo_test.c +++ b/test/core/echo/echo_test.c @@ -99,8 +99,10 @@ int main(int argc, char **argv) { if (WEXITSTATUS(status)) return WEXITSTATUS(status); } /* wait for server */ - printf("checking server\n"); - if (waitpid(svr, &status, WNOHANG) != 0) return 2; - kill(svr, SIGKILL); + printf("waiting for server\n"); + kill(svr, SIGINT); + if (waitpid(svr, &status, 0) == -1) return 2; + if (!WIFEXITED(status)) return 4; + if (WEXITSTATUS(status)) return WEXITSTATUS(status); return 0; } diff --git a/test/core/echo/server.c b/test/core/echo/server.c index 77383f838e..d80b55e76d 100644 --- a/test/core/echo/server.c +++ b/test/core/echo/server.c @@ -33,6 +33,7 @@ #include <grpc/grpc.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -48,6 +49,7 @@ static grpc_completion_queue *cq; static grpc_server *server; +static int got_sigint = 0; static const grpc_status status_ok = {GRPC_STATUS_OK, NULL}; @@ -79,10 +81,14 @@ static void assert_read_ok(call_state *s, grpc_byte_buffer *b) { grpc_byte_buffer_reader_destroy(bb_reader); } +static void sigint_handler(int x) { got_sigint = 1; } + int main(int argc, char **argv) { grpc_event *ev; char *addr; call_state *s; + int shutdown_started = 0; + int shutdown_finished = 0; grpc_test_init(argc, argv); @@ -104,16 +110,29 @@ int main(int argc, char **argv) { request_call(); - for (;;) { - ev = grpc_completion_queue_next(cq, gpr_inf_future); - GPR_ASSERT(ev); + signal(SIGINT, sigint_handler); + while (!shutdown_finished) { + if (got_sigint && !shutdown_started) { + gpr_log(GPR_INFO, "Shutting down due to SIGINT"); + grpc_server_shutdown(server); + grpc_completion_queue_shutdown(cq); + shutdown_started = 1; + } + 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 */ - grpc_call_accept(ev->call, cq, s, GRPC_WRITE_BUFFER_HINT); - GPR_ASSERT(grpc_call_start_read(ev->call, s) == GRPC_CALL_OK); - request_call(); + if (ev->call != NULL) { + /* initial ops are already started in request_call */ + grpc_call_accept(ev->call, cq, s, GRPC_WRITE_BUFFER_HINT); + GPR_ASSERT(grpc_call_start_read(ev->call, s) == GRPC_CALL_OK); + request_call(); + } else { + GPR_ASSERT(shutdown_started); + gpr_free(s); + } break; case GRPC_WRITE_ACCEPTED: GPR_ASSERT(ev->data.write_accepted == GRPC_OP_OK); @@ -137,12 +156,18 @@ int main(int argc, char **argv) { gpr_free(s); } break; + case GRPC_QUEUE_SHUTDOWN: + GPR_ASSERT(shutdown_started); + shutdown_finished = 1; + break; default: - abort(); + GPR_ASSERT(0); } grpc_event_finish(ev); } + grpc_server_destroy(server); + grpc_completion_queue_destroy(cq); grpc_shutdown(); return 0; diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c new file mode 100644 index 0000000000..fd679661a1 --- /dev/null +++ b/test/core/end2end/dualstack_socket_test.c @@ -0,0 +1,202 @@ +/* + * + * 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 "src/core/endpoint/socket_utils.h" +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/host_port.h> +#include <grpc/support/log.h> +#include "test/core/end2end/cq_verifier.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +/* This test exercises IPv4, IPv6, and dualstack sockets in various ways. */ + +static void *tag(gpr_intptr i) { return (void *)i; } + +static gpr_timespec ms_from_now(int ms) { + return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_MS * ms)); +} + +static void drain_cq(grpc_completion_queue *cq) { + grpc_event *ev; + grpc_completion_type type; + do { + ev = grpc_completion_queue_next(cq, ms_from_now(5000)); + GPR_ASSERT(ev); + type = ev->type; + grpc_event_finish(ev); + gpr_log(GPR_INFO, "Drained event type %d", type); + } while (type != GRPC_QUEUE_SHUTDOWN); +} + +void test_connect(const char *server_host, const char *client_host, int port, + int expect_ok) { + const grpc_status send_status = {GRPC_STATUS_UNIMPLEMENTED, "xyz"}; + const grpc_status cancelled_status = {GRPC_STATUS_CANCELLED, NULL}; + char *client_hostport; + char *server_hostport; + grpc_channel *client; + grpc_server *server; + grpc_completion_queue *client_cq; + grpc_completion_queue *server_cq; + grpc_call *c; + grpc_call *s; + cq_verifier *v_client; + cq_verifier *v_server; + gpr_timespec deadline; + + gpr_join_host_port(&client_hostport, client_host, port); + gpr_join_host_port(&server_hostport, server_host, port); + gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)", + server_hostport, client_hostport, expect_ok ? "success" : "failure"); + + /* Create server. */ + server_cq = grpc_completion_queue_create(); + server = grpc_server_create(server_cq, NULL); + GPR_ASSERT(grpc_server_add_http2_port(server, server_hostport)); + grpc_server_start(server); + gpr_free(server_hostport); + v_server = cq_verifier_create(server_cq); + + /* Create client. */ + client_cq = grpc_completion_queue_create(); + client = grpc_channel_create(client_hostport, NULL); + gpr_free(client_hostport); + v_client = cq_verifier_create(client_cq); + + if (expect_ok) { + /* Normal deadline, shouldn't be reached. */ + deadline = ms_from_now(60000); + } else { + /* Give up faster when failure is expected. + BUG: Setting this to 1000 reveals a memory leak (b/18608927). */ + deadline = ms_from_now(1500); + } + + /* Send a trivial request. */ + c = grpc_channel_create_call(client, "/foo", "test.google.com", deadline); + GPR_ASSERT(c); + + GPR_ASSERT(GRPC_CALL_OK == + grpc_call_start_invoke(c, client_cq, tag(1), tag(2), tag(3), 0)); + if (expect_ok) { + /* Check for a successful request. */ + cq_expect_invoke_accepted(v_client, tag(1), GRPC_OP_OK); + cq_verify(v_client); + + GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done(c, tag(4))); + cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK); + cq_verify(v_client); + + GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(server, tag(100))); + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com", + deadline, NULL); + cq_verify(v_server); + + GPR_ASSERT(GRPC_CALL_OK == grpc_call_accept(s, server_cq, tag(102), 0)); + cq_expect_client_metadata_read(v_client, tag(2), NULL); + cq_verify(v_client); + + GPR_ASSERT(GRPC_CALL_OK == + grpc_call_start_write_status(s, send_status, tag(5))); + cq_expect_finished_with_status(v_client, tag(3), send_status, NULL); + cq_verify(v_client); + + cq_expect_finish_accepted(v_server, tag(5), GRPC_OP_OK); + cq_verify(v_server); + cq_expect_finished(v_server, tag(102), NULL); + cq_verify(v_server); + + grpc_call_destroy(c); + grpc_call_destroy(s); + } else { + /* Check for a failed connection. */ + cq_expect_invoke_accepted(v_client, tag(1), GRPC_OP_ERROR); + cq_expect_client_metadata_read(v_client, tag(2), NULL); + cq_expect_finished_with_status(v_client, tag(3), cancelled_status, NULL); + cq_verify(v_client); + + grpc_call_destroy(c); + } + + cq_verifier_destroy(v_client); + cq_verifier_destroy(v_server); + + /* Destroy client. */ + grpc_channel_destroy(client); + grpc_completion_queue_shutdown(client_cq); + drain_cq(client_cq); + grpc_completion_queue_destroy(client_cq); + + /* Destroy server. */ + grpc_server_shutdown(server); + grpc_server_destroy(server); + grpc_completion_queue_shutdown(server_cq); + drain_cq(server_cq); + grpc_completion_queue_destroy(server_cq); +} + +int main(int argc, char **argv) { + int i; + int port = grpc_pick_unused_port_or_die(); + + grpc_test_init(argc, argv); + grpc_init(); + + for (i = 0; i <= 1; i++) { + /* For coverage, test with and without dualstack sockets. */ + grpc_forbid_dualstack_sockets_for_testing = i; + + /* :: and 0.0.0.0 are handled identically. */ + test_connect("::", "127.0.0.1", port, 1); + test_connect("::", "::1", port, 1); + test_connect("::", "::ffff:127.0.0.1", port, 1); + test_connect("::", "localhost", port, 1); + test_connect("0.0.0.0", "127.0.0.1", port, 1); + test_connect("0.0.0.0", "::1", port, 1); + test_connect("0.0.0.0", "::ffff:127.0.0.1", port, 1); + test_connect("0.0.0.0", "localhost", port, 1); + + /* These only work when the families agree. */ + test_connect("::1", "::1", port, 1); + test_connect("::1", "127.0.0.1", port, 0); + test_connect("127.0.0.1", "127.0.0.1", port, 1); + test_connect("127.0.0.1", "::1", port, 0); + + } + + grpc_shutdown(); + + return 0; +} diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c index a1f29de4dd..aaca56336f 100644 --- a/test/core/end2end/fixtures/chttp2_fake_security.c +++ b/test/core/end2end/fixtures/chttp2_fake_security.c @@ -47,7 +47,6 @@ #include "test/core/util/port.h" #include "test/core/end2end/data/ssl_test_data.h" - static grpc_em em; typedef struct fullstack_secure_fixture_data { @@ -124,7 +123,6 @@ int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); - grpc_init(); grpc_em_init(&em); diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c index 2dd3ce9a26..57c9141d95 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c @@ -47,7 +47,6 @@ #include "test/core/util/port.h" #include "test/core/end2end/data/ssl_test_data.h" - static grpc_em em; typedef struct fullstack_secure_fixture_data { @@ -131,7 +130,6 @@ int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); - grpc_init(); grpc_em_init(&em); diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c index 22720c5b5f..8d5585312a 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c @@ -47,7 +47,6 @@ #include "test/core/util/port.h" #include "test/core/end2end/data/ssl_test_data.h" - static grpc_em em; typedef struct fullstack_secure_fixture_data { @@ -70,6 +69,15 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( return f; } +static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f, + grpc_channel_args *client_args, + grpc_credentials *creds) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + f->client = grpc_secure_channel_create(creds, ffd->localaddr, client_args); + GPR_ASSERT(f->client != NULL); + grpc_credentials_release(creds); +} + static void chttp2_init_server_secure_fullstack( grpc_end2end_test_fixture *f, grpc_channel_args *server_args, grpc_server_credentials *server_creds) { @@ -89,23 +97,21 @@ void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack( grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { - /* TODO(jboeuf): Replace with composite credentials when those are - implemented. */ - grpc_channel_security_context *client_ctx = NULL; - fullstack_secure_fixture_data *ffd = f->fixture_data; - grpc_ssl_config config; - grpc_credentials *oauth2 = + grpc_credentials *ssl_creds = grpc_ssl_credentials_create( + test_ca_cert, test_ca_cert_size, NULL, 0, NULL, 0); + grpc_credentials *oauth2_creds = grpc_fake_oauth2_credentials_create("Bearer aaslkfjs424535asdf", 1); - memset(&config, 0, sizeof(grpc_ssl_config)); - config.pem_root_certs = test_ca_cert; - config.pem_root_certs_size = test_ca_cert_size; - GPR_ASSERT(grpc_ssl_channel_security_context_create( - oauth2, &config, "foo.test.google.com", &client_ctx) == - GRPC_SECURITY_OK); - f->client = grpc_secure_channel_create_internal(ffd->localaddr, client_args, - client_ctx); - grpc_security_context_unref(&client_ctx->base); - grpc_credentials_unref(oauth2); + grpc_credentials *ssl_oauth2_creds = + grpc_composite_credentials_create(ssl_creds, oauth2_creds); + grpc_arg ssl_name_override = {GRPC_ARG_STRING, + GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, + {"foo.test.google.com"}}; + grpc_channel_args *new_client_args = + grpc_channel_args_copy_and_add(client_args, &ssl_name_override); + chttp2_init_client_secure_fullstack(f, new_client_args, ssl_oauth2_creds); + grpc_channel_args_destroy(new_client_args); + grpc_credentials_release(ssl_creds); + grpc_credentials_release(oauth2_creds); } static void chttp2_init_server_simple_ssl_secure_fullstack( @@ -131,7 +137,6 @@ int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); - grpc_init(); grpc_em_init(&em); diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c new file mode 100644 index 0000000000..9287364c48 --- /dev/null +++ b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c @@ -0,0 +1,169 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +#include "src/core/channel/client_channel.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/channel/http_filter.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/eventmanager/em.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/client.h" +#include "src/core/surface/server.h" +#include "src/core/surface/surface_em.h" +#include "src/core/transport/chttp2_transport.h" +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/sync.h> +#include <grpc/support/thd.h> +#include <grpc/support/useful.h> +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +static void create_sockets(int sv[2]) { + int flags; + GPR_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); + flags = fcntl(sv[0], F_GETFL, 0); + GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0); + flags = fcntl(sv[1], F_GETFL, 0); + GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0); +} + +/* chttp2 transport that is immediately available (used for testing + connected_channel without a client_channel */ + +static grpc_transport_setup_result server_setup_transport( + void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { + grpc_end2end_test_fixture *f = ts; + static grpc_channel_filter const *extra_filters[] = {&grpc_http_server_filter, + &grpc_http_filter}; + return grpc_server_setup_transport(f->server, transport, extra_filters, + GPR_ARRAY_SIZE(extra_filters), mdctx); +} + +typedef struct { + grpc_end2end_test_fixture *f; + grpc_channel_args *client_args; +} sp_client_setup; + +static grpc_transport_setup_result client_setup_transport( + void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { + sp_client_setup *cs = ts; + + const grpc_channel_filter *filters[] = {&grpc_client_surface_filter, + &grpc_connected_channel_filter}; + size_t nfilters = sizeof(filters) / sizeof(*filters); + grpc_channel *channel = grpc_channel_create_from_filters( + filters, nfilters, cs->client_args, mdctx, 1); + + cs->f->client = channel; + + return grpc_connected_channel_bind_transport( + grpc_channel_get_channel_stack(channel), transport); +} + +typedef struct socketpair_fixture_data { int sv[2]; } socketpair_fixture_data; + +static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( + grpc_channel_args *client_args, grpc_channel_args *server_args) { + socketpair_fixture_data *sfd = gpr_malloc(sizeof(socketpair_fixture_data)); + + grpc_end2end_test_fixture f; + f.fixture_data = sfd; + f.client_cq = grpc_completion_queue_create(); + f.server_cq = grpc_completion_queue_create(); + f.server = grpc_server_create_from_filters(f.server_cq, NULL, 0, server_args); + f.client = NULL; + + create_sockets(sfd->sv); + + return f; +} + +static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, + grpc_channel_args *client_args) { + socketpair_fixture_data *sfd = f->fixture_data; + grpc_endpoint *cli_tcp; + sp_client_setup cs; + cs.client_args = client_args; + cs.f = f; + cli_tcp = grpc_tcp_create_dbg(sfd->sv[0], grpc_surface_em(), 1); + grpc_create_chttp2_transport(client_setup_transport, &cs, client_args, + cli_tcp, NULL, 0, grpc_mdctx_create(), 1); + GPR_ASSERT(f->client); +} + +static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, + grpc_channel_args *server_args) { + socketpair_fixture_data *sfd = f->fixture_data; + grpc_endpoint *svr_tcp; + svr_tcp = grpc_tcp_create_dbg(sfd->sv[1], grpc_surface_em(), 1); + grpc_create_chttp2_transport(server_setup_transport, f, server_args, svr_tcp, + NULL, 0, grpc_mdctx_create(), 0); +} + +static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture *f) { + gpr_free(f->fixture_data); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/socketpair_one_byte_at_a_time", 0, chttp2_create_fixture_socketpair, + chttp2_init_client_socketpair, chttp2_init_server_socketpair, + chttp2_tear_down_socketpair}, +}; + +int main(int argc, char **argv) { + size_t i; + + grpc_test_init(argc, argv); + grpc_init(); + + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(configs[i]); + } + + grpc_shutdown(); + + return 0; +} diff --git a/test/core/end2end/gen_build_json.py b/test/core/end2end/gen_build_json.py index 0bcccbeae4..a333621493 100755 --- a/test/core/end2end/gen_build_json.py +++ b/test/core/end2end/gen_build_json.py @@ -1,3 +1,8 @@ +#!/usr/bin/python + +"""Generates the appropriate build.json data for all the end2end tests.""" + + import simplejson END2END_FIXTURES = [ @@ -6,6 +11,7 @@ END2END_FIXTURES = [ 'chttp2_simple_ssl_fullstack', 'chttp2_simple_ssl_with_oauth2_fullstack', 'chttp2_socket_pair', + 'chttp2_socket_pair_one_byte_at_a_time', ] diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c index 7a3cab3f82..57214242c0 100644 --- a/test/core/end2end/tests/invoke_large_request.c +++ b/test/core/end2end/tests/invoke_large_request.c @@ -64,13 +64,11 @@ static gpr_timespec n_seconds_time(int n) { return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); } -static gpr_timespec five_seconds_time() { return n_seconds_time(5); } - static void drain_cq(grpc_completion_queue *cq) { grpc_event *ev; grpc_completion_type type; do { - ev = grpc_completion_queue_next(cq, five_seconds_time()); + ev = grpc_completion_queue_next(cq, n_seconds_time(5)); GPR_ASSERT(ev); type = ev->type; grpc_event_finish(ev); @@ -115,7 +113,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { gpr_slice request_payload_slice = large_slice(); grpc_byte_buffer *request_payload = grpc_byte_buffer_create(&request_payload_slice, 1); - gpr_timespec deadline = five_seconds_time(); + gpr_timespec deadline = n_seconds_time(10); grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_metadata_and_payload.c index 4cb5679c6b..f828ebb8e7 100644 --- a/test/core/end2end/tests/request_response_with_metadata_and_payload.c +++ b/test/core/end2end/tests/request_response_with_metadata_and_payload.c @@ -153,11 +153,13 @@ static void test_request_response_with_metadata_and_payload( deadline, "key1", "val1", "key2", "val2", NULL); cq_verify(v_server); + grpc_call_server_accept(s, f.server_cq, tag(102)); + /* add multiple metadata */ GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata(s, &meta3, 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata(s, &meta4, 0)); - grpc_call_accept(s, f.server_cq, tag(102), 0); + grpc_call_server_end_initial_metadata(s, 0); GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_read(s, tag(5))); cq_expect_read(v_server, tag(5), gpr_slice_from_copied_string("hello world")); diff --git a/test/core/endpoint/socket_utils_test.c b/test/core/endpoint/socket_utils_test.c new file mode 100644 index 0000000000..ef6ac32c22 --- /dev/null +++ b/test/core/endpoint/socket_utils_test.c @@ -0,0 +1,232 @@ +/* + * + * 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 "src/core/endpoint/socket_utils.h" + +#include <errno.h> +#include <netinet/in.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/port_platform.h> +#include "test/core/util/test_config.h" + +static struct sockaddr_in make_addr4(const gpr_uint8 *data, size_t data_len) { + struct sockaddr_in addr4; + memset(&addr4, 0, sizeof(addr4)); + addr4.sin_family = AF_INET; + GPR_ASSERT(data_len == sizeof(addr4.sin_addr.s_addr)); + memcpy(&addr4.sin_addr.s_addr, data, data_len); + addr4.sin_port = htons(12345); + return addr4; +} + +static struct sockaddr_in6 make_addr6(const gpr_uint8 *data, size_t data_len) { + struct sockaddr_in6 addr6; + memset(&addr6, 0, sizeof(addr6)); + addr6.sin6_family = AF_INET6; + GPR_ASSERT(data_len == sizeof(addr6.sin6_addr.s6_addr)); + memcpy(&addr6.sin6_addr.s6_addr, data, data_len); + addr6.sin6_port = htons(12345); + return addr6; +} + +static const gpr_uint8 kMapped[] = {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0xff, 0xff, 192, 0, 2, 1}; +static const gpr_uint8 kNotQuiteMapped[] = {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0xff, 0xfe, 192, 0, 2, 99}; +static const gpr_uint8 kIPv4[] = {192, 0, 2, 1}; +static const gpr_uint8 kIPv6[] = {0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1}; + +static void test_sockaddr_is_v4mapped() { + struct sockaddr_in input4; + struct sockaddr_in6 input6; + struct sockaddr_in output4; + struct sockaddr_in expect4; + + gpr_log(GPR_INFO, "%s", __FUNCTION__); + + /* v4mapped input should succeed. */ + input6 = make_addr6(kMapped, sizeof(kMapped)); + GPR_ASSERT(grpc_sockaddr_is_v4mapped((const struct sockaddr *)&input6, NULL)); + GPR_ASSERT( + grpc_sockaddr_is_v4mapped((const struct sockaddr *)&input6, &output4)); + expect4 = make_addr4(kIPv4, sizeof(kIPv4)); + GPR_ASSERT(memcmp(&expect4, &output4, sizeof(expect4)) == 0); + + /* Non-v4mapped input should fail. */ + input6 = make_addr6(kNotQuiteMapped, sizeof(kNotQuiteMapped)); + GPR_ASSERT( + !grpc_sockaddr_is_v4mapped((const struct sockaddr *)&input6, NULL)); + GPR_ASSERT( + !grpc_sockaddr_is_v4mapped((const struct sockaddr *)&input6, &output4)); + /* Output is unchanged. */ + GPR_ASSERT(memcmp(&expect4, &output4, sizeof(expect4)) == 0); + + /* Plain IPv4 input should also fail. */ + input4 = make_addr4(kIPv4, sizeof(kIPv4)); + GPR_ASSERT( + !grpc_sockaddr_is_v4mapped((const struct sockaddr *)&input4, NULL)); +} + +static void test_sockaddr_to_v4mapped() { + struct sockaddr_in input4; + struct sockaddr_in6 input6; + struct sockaddr_in6 output6; + struct sockaddr_in6 expect6; + + gpr_log(GPR_INFO, "%s", __FUNCTION__); + + /* IPv4 input should succeed. */ + input4 = make_addr4(kIPv4, sizeof(kIPv4)); + GPR_ASSERT( + grpc_sockaddr_to_v4mapped((const struct sockaddr *)&input4, &output6)); + expect6 = make_addr6(kMapped, sizeof(kMapped)); + GPR_ASSERT(memcmp(&expect6, &output6, sizeof(output6)) == 0); + + /* IPv6 input should fail. */ + input6 = make_addr6(kIPv6, sizeof(kIPv6)); + GPR_ASSERT( + !grpc_sockaddr_to_v4mapped((const struct sockaddr *)&input6, &output6)); + /* Output is unchanged. */ + GPR_ASSERT(memcmp(&expect6, &output6, sizeof(output6)) == 0); + + /* Already-v4mapped input should also fail. */ + input6 = make_addr6(kMapped, sizeof(kMapped)); + GPR_ASSERT( + !grpc_sockaddr_to_v4mapped((const struct sockaddr *)&input6, &output6)); +} + +static void test_sockaddr_is_wildcard() { + struct sockaddr_in wild4; + struct sockaddr_in6 wild6; + struct sockaddr_in6 wild_mapped; + struct sockaddr dummy; + int port; + + gpr_log(GPR_INFO, "%s", __FUNCTION__); + + /* Generate wildcards. */ + grpc_sockaddr_make_wildcards(555, &wild4, &wild6); + GPR_ASSERT( + grpc_sockaddr_to_v4mapped((const struct sockaddr *)&wild4, &wild_mapped)); + + /* Test 0.0.0.0:555 */ + port = -1; + GPR_ASSERT(grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild4, &port)); + GPR_ASSERT(port == 555); + memset(&wild4.sin_addr.s_addr, 0xbd, 1); + GPR_ASSERT( + !grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild4, &port)); + + /* Test [::]:555 */ + port = -1; + GPR_ASSERT(grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild6, &port)); + GPR_ASSERT(port == 555); + memset(&wild6.sin6_addr.s6_addr, 0xbd, 1); + GPR_ASSERT( + !grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild6, &port)); + + /* Test [::ffff:0.0.0.0]:555 */ + port = -1; + GPR_ASSERT( + grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild_mapped, &port)); + GPR_ASSERT(port == 555); + memset(&wild_mapped.sin6_addr.s6_addr, 0xbd, 1); + GPR_ASSERT( + !grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild_mapped, &port)); + + /* Test AF_UNSPEC. */ + port = -1; + memset(&dummy, 0, sizeof(dummy)); + GPR_ASSERT(!grpc_sockaddr_is_wildcard(&dummy, &port)); + GPR_ASSERT(port == -1); +} + +static void expect_sockaddr_str(const char *expected, void *addr, + int normalize) { + int result; + char *str; + gpr_log(GPR_INFO, " expect_sockaddr_str(%s)", expected); + result = grpc_sockaddr_to_string(&str, (struct sockaddr *)addr, normalize); + GPR_ASSERT(str != NULL); + GPR_ASSERT(result == strlen(str)); + GPR_ASSERT(strcmp(expected, str) == 0); + gpr_free(str); +} + +static void test_sockaddr_to_string() { + struct sockaddr_in input4; + struct sockaddr_in6 input6; + struct sockaddr dummy; + + gpr_log(GPR_INFO, "%s", __FUNCTION__); + + errno = 0xDEADBEEF; + + input4 = make_addr4(kIPv4, sizeof(kIPv4)); + expect_sockaddr_str("192.0.2.1:12345", &input4, 0); + expect_sockaddr_str("192.0.2.1:12345", &input4, 1); + + input6 = make_addr6(kIPv6, sizeof(kIPv6)); + expect_sockaddr_str("[2001:db8::1]:12345", &input6, 0); + expect_sockaddr_str("[2001:db8::1]:12345", &input6, 1); + + input6 = make_addr6(kMapped, sizeof(kMapped)); + expect_sockaddr_str("[::ffff:192.0.2.1]:12345", &input6, 0); + expect_sockaddr_str("192.0.2.1:12345", &input6, 1); + + input6 = make_addr6(kNotQuiteMapped, sizeof(kNotQuiteMapped)); + expect_sockaddr_str("[::fffe:c000:263]:12345", &input6, 0); + expect_sockaddr_str("[::fffe:c000:263]:12345", &input6, 1); + + memset(&dummy, 0, sizeof(dummy)); + dummy.sa_family = 999; + expect_sockaddr_str("(sockaddr family=999)", &dummy, 0); + expect_sockaddr_str("(sockaddr family=999)", &dummy, 1); + + GPR_ASSERT(errno == 0xDEADBEEF); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + + test_sockaddr_is_v4mapped(); + test_sockaddr_to_v4mapped(); + test_sockaddr_is_wildcard(); + test_sockaddr_to_string(); + + return 0; +} diff --git a/test/core/endpoint/tcp_server_test.c b/test/core/endpoint/tcp_server_test.c index 10e2c36df1..62089152d0 100644 --- a/test/core/endpoint/tcp_server_test.c +++ b/test/core/endpoint/tcp_server_test.c @@ -80,7 +80,7 @@ static void test_no_op_with_port() { memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; GPR_ASSERT( - grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)) >= 0); + grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr))); grpc_tcp_server_destroy(s); } @@ -93,7 +93,7 @@ static void test_no_op_with_port_and_start() { memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; GPR_ASSERT( - grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)) >= 0); + grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr))); grpc_tcp_server_start(s, on_connect, NULL); @@ -101,7 +101,7 @@ static void test_no_op_with_port_and_start() { } static void test_connect(int n) { - struct sockaddr_in addr; + struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); int svrfd, clifd; grpc_tcp_server *s = grpc_tcp_server_create(&em); @@ -114,12 +114,13 @@ static void test_connect(int n) { gpr_mu_lock(&mu); memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - svrfd = grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len); - GPR_ASSERT(svrfd >= 0); + addr.ss_family = AF_INET; + GPR_ASSERT(grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len)); + svrfd = grpc_tcp_server_get_fd(s, 0); + GPR_ASSERT(svrfd >= 0); GPR_ASSERT(getsockname(svrfd, (struct sockaddr *)&addr, &addr_len) == 0); - GPR_ASSERT(addr_len == sizeof(addr)); + GPR_ASSERT(addr_len <= sizeof(addr)); grpc_tcp_server_start(s, on_connect, NULL); @@ -127,7 +128,7 @@ static void test_connect(int n) { deadline = gpr_time_add(gpr_now(), gpr_time_from_micros(10000000)); nconnects_before = nconnects; - clifd = socket(AF_INET, SOCK_STREAM, 0); + clifd = socket(addr.ss_family, SOCK_STREAM, 0); GPR_ASSERT(clifd >= 0); GPR_ASSERT(connect(clifd, (struct sockaddr *)&addr, addr_len) == 0); diff --git a/test/core/eventmanager/em_pipe_test.c b/test/core/eventmanager/em_pipe_test.c index 5411142c89..f2414c42b1 100644 --- a/test/core/eventmanager/em_pipe_test.c +++ b/test/core/eventmanager/em_pipe_test.c @@ -73,7 +73,6 @@ typedef struct { void write_shutdown_cb(void *arg, /*async_pipe*/ enum grpc_em_cb_status status) { async_pipe *ap = arg; - close(ap->fd[1]); grpc_em_fd_destroy(&ap->write_em_fd); } @@ -110,7 +109,6 @@ void write_cb(void *arg, /*async_pipe*/ enum grpc_em_cb_status status) { void read_shutdown_cb(void *arg, /*async_pipe*/ enum grpc_em_cb_status status) { async_pipe *ap = arg; - close(ap->fd[0]); grpc_em_fd_destroy(&ap->read_em_fd); pthread_mutex_lock(&ap->mu); if (ap->done == 0) { diff --git a/test/core/eventmanager/em_test.c b/test/core/eventmanager/em_test.c index fceabff533..274edc3231 100644 --- a/test/core/eventmanager/em_test.c +++ b/test/core/eventmanager/em_test.c @@ -138,7 +138,6 @@ static void session_read_cb(void *arg, /*session*/ ssize_t read_total = 0; if (status == GRPC_CALLBACK_CANCELLED) { - close(fd); session_shutdown_cb(arg, GRPC_CALLBACK_SUCCESS); return; } @@ -181,7 +180,6 @@ static void listen_shutdown_cb(void *arg /*server*/, enum grpc_em_cb_status status) { server *sv = arg; - close(grpc_em_fd_get(&sv->em_fd)); grpc_em_fd_destroy(&sv->em_fd); gpr_mu_lock(&sv->mu); @@ -527,7 +525,6 @@ void test_grpc_em_fd_notify_timeout() { GPR_ASSERT(gpr_event_get(&ev) == (void *)1); grpc_em_fd_destroy(&em_fd); grpc_em_destroy(&em); - close(sv[0]); close(sv[1]); } diff --git a/test/core/fling/fling_stream_test.c b/test/core/fling/fling_stream_test.c index 14a31eb26e..a24240ef1d 100644 --- a/test/core/fling/fling_stream_test.c +++ b/test/core/fling/fling_stream_test.c @@ -96,8 +96,10 @@ int main(int argc, char **argv) { 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); + printf("waiting for server\n"); + kill(svr, SIGINT); + if (waitpid(svr, &status, 0) == -1) return 2; + if (!WIFEXITED(status)) return 4; + if (WEXITSTATUS(status)) return WEXITSTATUS(status); return 0; } diff --git a/test/core/fling/fling_test.c b/test/core/fling/fling_test.c index e5e63f9076..c6b369518c 100644 --- a/test/core/fling/fling_test.c +++ b/test/core/fling/fling_test.c @@ -96,8 +96,10 @@ int main(int argc, char **argv) { 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); + printf("waiting for server\n"); + kill(svr, SIGINT); + if (waitpid(svr, &status, 0) == -1) return 2; + if (!WIFEXITED(status)) return 4; + if (WEXITSTATUS(status)) return WEXITSTATUS(status); return 0; } diff --git a/test/core/fling/server.c b/test/core/fling/server.c index 7a5d89598d..c35bab5789 100644 --- a/test/core/fling/server.c +++ b/test/core/fling/server.c @@ -50,7 +50,7 @@ static grpc_completion_queue *cq; static grpc_server *server; -static int done = 0; +static int got_sigint = 0; static const grpc_status status_ok = {GRPC_STATUS_OK, NULL}; @@ -65,13 +65,15 @@ static void request_call() { grpc_server_request_call(server, s); } -static void sigint_handler(int x) { done = 1; } +static void sigint_handler(int x) { got_sigint = 1; } int main(int argc, char **argv) { grpc_event *ev; call_state *s; char *addr_buf = NULL; gpr_cmdline *cl; + int shutdown_started = 0; + int shutdown_finished = 0; int secure = 0; char *addr = NULL; @@ -109,23 +111,34 @@ int main(int argc, char **argv) { grpc_profiler_start("server.prof"); signal(SIGINT, sigint_handler); - while (!done) { + while (!shutdown_finished) { + if (got_sigint && !shutdown_started) { + gpr_log(GPR_INFO, "Shutting down due to SIGINT"); + grpc_server_shutdown(server); + grpc_completion_queue_shutdown(cq); + shutdown_started = 1; + } 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; + if (ev->call != NULL) { + /* 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(); } else { - s->flags = GRPC_WRITE_BUFFER_HINT; + GPR_ASSERT(shutdown_started); + gpr_free(s); } - 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); @@ -147,13 +160,19 @@ int main(int argc, char **argv) { gpr_free(s); } break; + case GRPC_QUEUE_SHUTDOWN: + GPR_ASSERT(shutdown_started); + shutdown_finished = 1; + break; default: - abort(); + GPR_ASSERT(0); } grpc_event_finish(ev); } grpc_profiler_stop(); + grpc_server_destroy(server); + grpc_completion_queue_destroy(cq); grpc_shutdown(); return 0; } diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c index 260b39b4d8..7eca8442b4 100644 --- a/test/core/security/credentials_test.c +++ b/test/core/security/credentials_test.c @@ -40,6 +40,17 @@ #include <string.h> +static const char test_iam_authorization_token[] = "blahblahblhahb"; +static const char test_iam_authority_selector[] = "respectmyauthoritah"; +static const char test_oauth2_bearer_token[] = + "Bearer blaaslkdjfaslkdfasdsfasf"; +static const unsigned char test_root_cert[] = {0xDE, 0xAD, 0xBE, 0xEF}; + +typedef struct { + const char *key; + const char *value; +} expected_md; + static grpc_httpcli_response http_response(int status, char *body) { grpc_httpcli_response response; memset(&response, 0, sizeof(grpc_httpcli_response)); @@ -154,6 +165,126 @@ static void test_compute_engine_creds_parsing_missing_token_lifetime(void) { grpc_mdctx_orphan(ctx); } +static void check_metadata(expected_md *expected, grpc_mdelem **md_elems, + size_t num_md) { + size_t i; + for (i = 0; i < num_md; i++) { + size_t j; + for (j = 0; j < num_md; j++) { + if (0 == gpr_slice_str_cmp(md_elems[j]->key->slice, expected[i].key)) { + GPR_ASSERT(0 == gpr_slice_str_cmp(md_elems[j]->value->slice, + expected[i].value)); + break; + } + } + if (j == num_md) { + gpr_log(GPR_ERROR, "key %s not found", expected[i].key); + GPR_ASSERT(0); + } + } +} + +static void check_iam_metadata(void *user_data, grpc_mdelem **md_elems, + size_t num_md, grpc_credentials_status status) { + grpc_credentials *c = (grpc_credentials *)user_data; + expected_md emd[] = { + {GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, test_iam_authorization_token}, + {GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, test_iam_authority_selector}}; + GPR_ASSERT(status == GRPC_CREDENTIALS_OK); + GPR_ASSERT(num_md == 2); + check_metadata(emd, md_elems, num_md); + grpc_credentials_unref(c); +} + +static void test_iam_creds(void) { + grpc_credentials *creds = grpc_iam_credentials_create( + test_iam_authorization_token, test_iam_authority_selector); + GPR_ASSERT(grpc_credentials_has_request_metadata(creds)); + GPR_ASSERT(grpc_credentials_has_request_metadata_only(creds)); + grpc_credentials_get_request_metadata(creds, check_iam_metadata, creds); +} + +static void check_ssl_oauth2_composite_metadata( + void *user_data, grpc_mdelem **md_elems, size_t num_md, + grpc_credentials_status status) { + grpc_credentials *c = (grpc_credentials *)user_data; + expected_md emd[] = { + {GRPC_AUTHORIZATION_METADATA_KEY, test_oauth2_bearer_token}}; + GPR_ASSERT(status == GRPC_CREDENTIALS_OK); + GPR_ASSERT(num_md == 1); + check_metadata(emd, md_elems, num_md); + grpc_credentials_unref(c); +} + +static void test_ssl_oauth2_composite_creds(void) { + grpc_credentials *ssl_creds = grpc_ssl_credentials_create( + test_root_cert, sizeof(test_root_cert), NULL, 0, NULL, 0); + const grpc_credentials_array *creds_array; + grpc_credentials *oauth2_creds = + grpc_fake_oauth2_credentials_create(test_oauth2_bearer_token, 0); + grpc_credentials *composite_creds = + grpc_composite_credentials_create(ssl_creds, oauth2_creds); + grpc_credentials_unref(ssl_creds); + grpc_credentials_unref(oauth2_creds); + GPR_ASSERT(!strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)); + GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds)); + GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds)); + creds_array = grpc_composite_credentials_get_credentials(composite_creds); + GPR_ASSERT(creds_array->num_creds == 2); + GPR_ASSERT( + !strcmp(creds_array->creds_array[0]->type, GRPC_CREDENTIALS_TYPE_SSL)); + GPR_ASSERT( + !strcmp(creds_array->creds_array[1]->type, GRPC_CREDENTIALS_TYPE_OAUTH2)); + grpc_credentials_get_request_metadata( + composite_creds, check_ssl_oauth2_composite_metadata, composite_creds); +} + +static void check_ssl_oauth2_iam_composite_metadata( + void *user_data, grpc_mdelem **md_elems, size_t num_md, + grpc_credentials_status status) { + grpc_credentials *c = (grpc_credentials *)user_data; + expected_md emd[] = { + {GRPC_AUTHORIZATION_METADATA_KEY, test_oauth2_bearer_token}, + {GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, test_iam_authorization_token}, + {GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, test_iam_authority_selector}}; + GPR_ASSERT(status == GRPC_CREDENTIALS_OK); + GPR_ASSERT(num_md == 3); + check_metadata(emd, md_elems, num_md); + grpc_credentials_unref(c); +} + +static void test_ssl_oauth2_iam_composite_creds(void) { + grpc_credentials *ssl_creds = grpc_ssl_credentials_create( + test_root_cert, sizeof(test_root_cert), NULL, 0, NULL, 0); + const grpc_credentials_array *creds_array; + grpc_credentials *oauth2_creds = + grpc_fake_oauth2_credentials_create(test_oauth2_bearer_token, 0); + grpc_credentials *aux_creds = + grpc_composite_credentials_create(ssl_creds, oauth2_creds); + grpc_credentials *iam_creds = grpc_iam_credentials_create( + test_iam_authorization_token, test_iam_authority_selector); + grpc_credentials *composite_creds = + grpc_composite_credentials_create(aux_creds, iam_creds); + grpc_credentials_unref(ssl_creds); + grpc_credentials_unref(oauth2_creds); + grpc_credentials_unref(aux_creds); + grpc_credentials_unref(iam_creds); + GPR_ASSERT(!strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)); + GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds)); + GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds)); + creds_array = grpc_composite_credentials_get_credentials(composite_creds); + GPR_ASSERT(creds_array->num_creds == 3); + GPR_ASSERT( + !strcmp(creds_array->creds_array[0]->type, GRPC_CREDENTIALS_TYPE_SSL)); + GPR_ASSERT( + !strcmp(creds_array->creds_array[1]->type, GRPC_CREDENTIALS_TYPE_OAUTH2)); + GPR_ASSERT( + !strcmp(creds_array->creds_array[2]->type, GRPC_CREDENTIALS_TYPE_IAM)); + grpc_credentials_get_request_metadata(composite_creds, + check_ssl_oauth2_iam_composite_metadata, + composite_creds); +} + int main(int argc, char **argv) { grpc_test_init(argc, argv); test_compute_engine_creds_parsing_ok(); @@ -163,5 +294,8 @@ int main(int argc, char **argv) { test_compute_engine_creds_parsing_missing_token(); test_compute_engine_creds_parsing_missing_token_type(); test_compute_engine_creds_parsing_missing_token_lifetime(); + test_iam_creds(); + test_ssl_oauth2_composite_creds(); + test_ssl_oauth2_iam_composite_creds(); return 0; } diff --git a/test/core/transport/chttp2/alpn_test.c b/test/core/transport/chttp2/alpn_test.c new file mode 100644 index 0000000000..65b7af8683 --- /dev/null +++ b/test/core/transport/chttp2/alpn_test.c @@ -0,0 +1,56 @@ +/* + * + * 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 "src/core/transport/chttp2/alpn.h" + +#include <grpc/support/log.h> +#include "test/core/util/test_config.h" + +static void test_alpn_success(void) { + const char *version = GRPC_CHTTP2_ALPN_VERSION; + GPR_ASSERT(grpc_chttp2_is_alpn_version_supported(version, strlen(version))); + GPR_ASSERT(grpc_chttp2_is_alpn_version_supported("h2-15", 5)); + GPR_ASSERT(grpc_chttp2_is_alpn_version_supported("h2-14", 5)); +} + +static void test_alpn_failure(void) { + GPR_ASSERT(!grpc_chttp2_is_alpn_version_supported("h2-155", 6)); + GPR_ASSERT(!grpc_chttp2_is_alpn_version_supported("h1-15", 5)); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + test_alpn_success(); + test_alpn_failure(); + return 0; +} diff --git a/test/core/transport/chttp2/bin_encoder_test.c b/test/core/transport/chttp2/bin_encoder_test.c new file mode 100644 index 0000000000..d2400e7854 --- /dev/null +++ b/test/core/transport/chttp2/bin_encoder_test.c @@ -0,0 +1,169 @@ +/* + * + * 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 "src/core/transport/chttp2/bin_encoder.h" +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string.h> + +static int all_ok = 1; + +static void expect_slice_eq(gpr_slice expected, gpr_slice slice, char *debug, + int line) { + if (0 != gpr_slice_cmp(slice, expected)) { + char *hs = gpr_hexdump((const char *)GPR_SLICE_START_PTR(slice), + GPR_SLICE_LENGTH(slice), GPR_HEXDUMP_PLAINTEXT); + char *he = gpr_hexdump((const char *)GPR_SLICE_START_PTR(expected), + GPR_SLICE_LENGTH(expected), GPR_HEXDUMP_PLAINTEXT); + gpr_log(GPR_ERROR, "FAILED:%d: %s\ngot: %s\nwant: %s", line, debug, hs, + he); + gpr_free(hs); + gpr_free(he); + all_ok = 0; + } + gpr_slice_unref(expected); + gpr_slice_unref(slice); +} + +static gpr_slice B64(const char *s) { + gpr_slice ss = gpr_slice_from_copied_string(s); + gpr_slice out = grpc_chttp2_base64_encode(ss); + gpr_slice_unref(ss); + return out; +} + +static gpr_slice HUFF(const char *s) { + gpr_slice ss = gpr_slice_from_copied_string(s); + gpr_slice out = grpc_chttp2_huffman_compress(ss); + gpr_slice_unref(ss); + return out; +} + +#define EXPECT_SLICE_EQ(expected, slice) \ + expect_slice_eq( \ + gpr_slice_from_copied_buffer(expected, sizeof(expected) - 1), slice, \ + #slice, __LINE__); + +static void expect_combined_equiv(const char *s, size_t len, int line) { + gpr_slice input = gpr_slice_from_copied_buffer(s, len); + gpr_slice base64 = grpc_chttp2_base64_encode(input); + gpr_slice expect = grpc_chttp2_huffman_compress(base64); + gpr_slice got = grpc_chttp2_base64_encode_and_huffman_compress(input); + if (0 != gpr_slice_cmp(expect, got)) { + char *t = gpr_hexdump((const char *)GPR_SLICE_START_PTR(input), + GPR_SLICE_LENGTH(input), GPR_HEXDUMP_PLAINTEXT); + char *e = gpr_hexdump((const char *)GPR_SLICE_START_PTR(expect), + GPR_SLICE_LENGTH(expect), GPR_HEXDUMP_PLAINTEXT); + char *g = gpr_hexdump((const char *)GPR_SLICE_START_PTR(got), + GPR_SLICE_LENGTH(got), GPR_HEXDUMP_PLAINTEXT); + gpr_log(GPR_ERROR, "FAILED:%d:\ntest: %s\ngot: %s\nwant: %s", t, g, e); + gpr_free(t); + gpr_free(e); + gpr_free(g); + } + gpr_slice_unref(input); + gpr_slice_unref(base64); + gpr_slice_unref(expect); + gpr_slice_unref(got); +} + +#define EXPECT_COMBINED_EQUIV(x) \ + expect_combined_equiv(x, sizeof(x) - 1, __LINE__) + +int main(int argc, char **argv) { + /* Base64 test vectors from RFC 4648, with padding removed */ + /* BASE64("") = "" */ + EXPECT_SLICE_EQ("", B64("")); + /* BASE64("f") = "Zg" */ + EXPECT_SLICE_EQ("Zg", B64("f")); + /* BASE64("fo") = "Zm8" */ + EXPECT_SLICE_EQ("Zm8", B64("fo")); + /* BASE64("foo") = "Zm9v" */ + EXPECT_SLICE_EQ("Zm9v", B64("foo")); + /* BASE64("foob") = "Zm9vYg" */ + EXPECT_SLICE_EQ("Zm9vYg", B64("foob")); + /* BASE64("fooba") = "Zm9vYmE" */ + EXPECT_SLICE_EQ("Zm9vYmE", B64("fooba")); + /* BASE64("foobar") = "Zm9vYmFy" */ + EXPECT_SLICE_EQ("Zm9vYmFy", B64("foobar")); + + /* Huffman encoding tests */ + EXPECT_SLICE_EQ("\xf1\xe3\xc2\xe5\xf2\x3a\x6b\xa0\xab\x90\xf4\xff", + HUFF("www.example.com")); + EXPECT_SLICE_EQ("\xa8\xeb\x10\x64\x9c\xbf", HUFF("no-cache")); + EXPECT_SLICE_EQ("\x25\xa8\x49\xe9\x5b\xa9\x7d\x7f", HUFF("custom-key")); + EXPECT_SLICE_EQ("\x25\xa8\x49\xe9\x5b\xb8\xe8\xb4\xbf", HUFF("custom-value")); + EXPECT_SLICE_EQ("\xae\xc3\x77\x1a\x4b", HUFF("private")); + EXPECT_SLICE_EQ( + "\xd0\x7a\xbe\x94\x10\x54\xd4\x44\xa8\x20\x05\x95\x04\x0b\x81\x66\xe0\x82" + "\xa6\x2d\x1b\xff", + HUFF("Mon, 21 Oct 2013 20:13:21 GMT")); + EXPECT_SLICE_EQ( + "\x9d\x29\xad\x17\x18\x63\xc7\x8f\x0b\x97\xc8\xe9\xae\x82\xae\x43\xd3", + HUFF("https://www.example.com")); + + /* Various test vectors for combined encoding */ + EXPECT_COMBINED_EQUIV(""); + EXPECT_COMBINED_EQUIV("f"); + EXPECT_COMBINED_EQUIV("fo"); + EXPECT_COMBINED_EQUIV("foo"); + EXPECT_COMBINED_EQUIV("foob"); + EXPECT_COMBINED_EQUIV("fooba"); + EXPECT_COMBINED_EQUIV("foobar"); + EXPECT_COMBINED_EQUIV("www.example.com"); + EXPECT_COMBINED_EQUIV("no-cache"); + EXPECT_COMBINED_EQUIV("custom-key"); + EXPECT_COMBINED_EQUIV("custom-value"); + EXPECT_COMBINED_EQUIV("private"); + EXPECT_COMBINED_EQUIV("Mon, 21 Oct 2013 20:13:21 GMT"); + EXPECT_COMBINED_EQUIV("https://www.example.com"); + EXPECT_COMBINED_EQUIV( + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" + "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" + "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" + "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" + "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" + "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" + "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"); + + return all_ok ? 0 : 1; +} diff --git a/test/core/transport/transport_end2end_tests.c b/test/core/transport/transport_end2end_tests.c index ce6fbcf91d..49ce645a64 100644 --- a/test/core/transport/transport_end2end_tests.c +++ b/test/core/transport/transport_end2end_tests.c @@ -466,8 +466,13 @@ static void recv_batch(void *user_data, grpc_transport *transport, static void close_transport(void *user_data, grpc_transport *transport) {} +static void recv_goaway(void *user_data, grpc_transport *transport, + grpc_status_code status, gpr_slice debug) { + gpr_slice_unref(debug); +} + static grpc_transport_callbacks transport_callbacks = { - alloc_recv_buffer, create_stream, recv_batch, close_transport}; + alloc_recv_buffer, create_stream, recv_batch, recv_goaway, close_transport}; /* Helper for tests to create a stream. Arguments: |