LCOV - code coverage report
Current view: top level - test/core/end2end - dualstack_socket_test.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 178 183 97.3 %
Date: 2015-10-10 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2015, Google Inc.
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are
       8             :  * met:
       9             :  *
      10             :  *     * Redistributions of source code must retain the above copyright
      11             :  * notice, this list of conditions and the following disclaimer.
      12             :  *     * Redistributions in binary form must reproduce the above
      13             :  * copyright notice, this list of conditions and the following disclaimer
      14             :  * in the documentation and/or other materials provided with the
      15             :  * distribution.
      16             :  *     * Neither the name of Google Inc. nor the names of its
      17             :  * contributors may be used to endorse or promote products derived from
      18             :  * this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      23             :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      24             :  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      25             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      26             :  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      30             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             :  *
      32             :  */
      33             : 
      34             : #include <string.h>
      35             : 
      36             : #include <grpc/grpc.h>
      37             : #include <grpc/support/alloc.h>
      38             : #include <grpc/support/host_port.h>
      39             : #include <grpc/support/log.h>
      40             : #include <grpc/support/string_util.h>
      41             : 
      42             : #include "src/core/support/string.h"
      43             : #include "src/core/iomgr/resolve_address.h"
      44             : #include "src/core/iomgr/socket_utils_posix.h"
      45             : 
      46             : #include "test/core/end2end/cq_verifier.h"
      47             : #include "test/core/util/port.h"
      48             : #include "test/core/util/test_config.h"
      49             : 
      50             : /* This test exercises IPv4, IPv6, and dualstack sockets in various ways. */
      51             : 
      52         416 : static void *tag(gpr_intptr i) { return (void *)i; }
      53             : 
      54         116 : static gpr_timespec ms_from_now(int ms) {
      55         116 :   return GRPC_TIMEOUT_MILLIS_TO_DEADLINE(ms);
      56             : }
      57             : 
      58          58 : static void drain_cq(grpc_completion_queue *cq) {
      59             :   grpc_event ev;
      60             :   do {
      61          58 :     ev = grpc_completion_queue_next(cq, ms_from_now(5000), NULL);
      62          58 :   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
      63          58 : }
      64             : 
      65          22 : static void do_nothing(void *ignored) {}
      66             : 
      67          58 : void test_connect(const char *server_host, const char *client_host, int port,
      68             :                   int expect_ok) {
      69             :   char *client_hostport;
      70             :   char *server_hostport;
      71             :   grpc_channel *client;
      72             :   grpc_server *server;
      73             :   grpc_completion_queue *cq;
      74             :   grpc_call *c;
      75             :   grpc_call *s;
      76             :   cq_verifier *cqv;
      77             :   gpr_timespec deadline;
      78             :   int got_port;
      79             :   grpc_op ops[6];
      80             :   grpc_op *op;
      81             :   grpc_metadata_array initial_metadata_recv;
      82             :   grpc_metadata_array trailing_metadata_recv;
      83             :   grpc_metadata_array request_metadata_recv;
      84             :   grpc_status_code status;
      85             :   grpc_call_error error;
      86          58 :   char *details = NULL;
      87          58 :   size_t details_capacity = 0;
      88          58 :   int was_cancelled = 2;
      89             :   grpc_call_details call_details;
      90             :   char *peer;
      91             : 
      92          58 :   if (port == 0) {
      93          58 :     port = grpc_pick_unused_port_or_die();
      94             :   }
      95             : 
      96          58 :   gpr_join_host_port(&server_hostport, server_host, port);
      97             : 
      98          58 :   grpc_metadata_array_init(&initial_metadata_recv);
      99          58 :   grpc_metadata_array_init(&trailing_metadata_recv);
     100          58 :   grpc_metadata_array_init(&request_metadata_recv);
     101          58 :   grpc_call_details_init(&call_details);
     102             : 
     103             :   /* Create server. */
     104          58 :   cq = grpc_completion_queue_create(NULL);
     105          58 :   server = grpc_server_create(NULL, NULL);
     106          58 :   grpc_server_register_completion_queue(server, cq, NULL);
     107          58 :   GPR_ASSERT((got_port = grpc_server_add_insecure_http2_port(
     108             :                   server, server_hostport)) > 0);
     109          58 :   if (port == 0) {
     110           0 :     port = got_port;
     111             :   } else {
     112          58 :     GPR_ASSERT(port == got_port);
     113             :   }
     114          58 :   grpc_server_start(server);
     115          58 :   cqv = cq_verifier_create(cq);
     116             : 
     117             :   /* Create client. */
     118          58 :   if (client_host[0] == 'i') {
     119             :     /* for ipv4:/ipv6: addresses, concatenate the port to each of the parts */
     120             :     size_t i;
     121             :     gpr_slice uri_slice;
     122             :     gpr_slice_buffer uri_parts;
     123             :     char **hosts_with_port;
     124             : 
     125          22 :     uri_slice =
     126          22 :         gpr_slice_new((char *)client_host, strlen(client_host), do_nothing);
     127          22 :     gpr_slice_buffer_init(&uri_parts);
     128          22 :     gpr_slice_split(uri_slice, ",", &uri_parts);
     129          22 :     hosts_with_port = gpr_malloc(sizeof(char *) * uri_parts.count);
     130          50 :     for (i = 0; i < uri_parts.count; i++) {
     131          28 :       char *uri_part_str = gpr_dump_slice(uri_parts.slices[i], GPR_DUMP_ASCII);
     132          28 :       gpr_asprintf(&hosts_with_port[i], "%s:%d", uri_part_str, port);
     133          28 :       gpr_free(uri_part_str);
     134             :     }
     135          22 :     client_hostport = gpr_strjoin_sep((const char **)hosts_with_port,
     136             :                                       uri_parts.count, ",", NULL);
     137          50 :     for (i = 0; i < uri_parts.count; i++) {
     138          28 :       gpr_free(hosts_with_port[i]);
     139             :     }
     140          22 :     gpr_free(hosts_with_port);
     141          22 :     gpr_slice_buffer_destroy(&uri_parts);
     142          22 :     gpr_slice_unref(uri_slice);
     143             :   } else {
     144          36 :     gpr_join_host_port(&client_hostport, client_host, port);
     145             :   }
     146          58 :   client = grpc_insecure_channel_create(client_hostport, NULL, NULL);
     147             : 
     148          58 :   gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)",
     149             :           server_hostport, client_hostport, expect_ok ? "success" : "failure");
     150             : 
     151          58 :   gpr_free(client_hostport);
     152          58 :   gpr_free(server_hostport);
     153             : 
     154          58 :   if (expect_ok) {
     155             :     /* Normal deadline, shouldn't be reached. */
     156          46 :     deadline = ms_from_now(60000);
     157             :   } else {
     158             :     /* Give up faster when failure is expected.
     159             :        BUG: Setting this to 1000 reveals a memory leak (b/18608927). */
     160          12 :     deadline = ms_from_now(1500);
     161             :   }
     162             : 
     163             :   /* Send a trivial request. */
     164          58 :   c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
     165             :                                "/foo", "foo.test.google.fr", deadline, NULL);
     166          58 :   GPR_ASSERT(c);
     167             : 
     168          58 :   op = ops;
     169          58 :   op->op = GRPC_OP_SEND_INITIAL_METADATA;
     170          58 :   op->data.send_initial_metadata.count = 0;
     171          58 :   op->flags = 0;
     172          58 :   op->reserved = NULL;
     173          58 :   op++;
     174          58 :   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
     175          58 :   op->flags = 0;
     176          58 :   op->reserved = NULL;
     177          58 :   op++;
     178          58 :   op->op = GRPC_OP_RECV_INITIAL_METADATA;
     179          58 :   op->data.recv_initial_metadata = &initial_metadata_recv;
     180          58 :   op->flags = 0;
     181          58 :   op->reserved = NULL;
     182          58 :   op++;
     183          58 :   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
     184          58 :   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
     185          58 :   op->data.recv_status_on_client.status = &status;
     186          58 :   op->data.recv_status_on_client.status_details = &details;
     187          58 :   op->data.recv_status_on_client.status_details_capacity = &details_capacity;
     188          58 :   op->flags = 0;
     189          58 :   op->reserved = NULL;
     190          58 :   op++;
     191          58 :   error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
     192          58 :   GPR_ASSERT(GRPC_CALL_OK == error);
     193             : 
     194          58 :   if (expect_ok) {
     195             :     /* Check for a successful request. */
     196          46 :     error = grpc_server_request_call(server, &s, &call_details,
     197             :                                      &request_metadata_recv, cq, cq, tag(101));
     198          46 :     GPR_ASSERT(GRPC_CALL_OK == error);
     199          46 :     cq_expect_completion(cqv, tag(101), 1);
     200          46 :     cq_verify(cqv);
     201             : 
     202          46 :     op = ops;
     203          46 :     op->op = GRPC_OP_SEND_INITIAL_METADATA;
     204          46 :     op->data.send_initial_metadata.count = 0;
     205          46 :     op->flags = 0;
     206          46 :     op++;
     207          46 :     op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
     208          46 :     op->data.send_status_from_server.trailing_metadata_count = 0;
     209          46 :     op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
     210          46 :     op->data.send_status_from_server.status_details = "xyz";
     211          46 :     op->flags = 0;
     212          46 :     op++;
     213          46 :     op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
     214          46 :     op->data.recv_close_on_server.cancelled = &was_cancelled;
     215          46 :     op->flags = 0;
     216          46 :     op++;
     217          46 :     error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
     218          46 :     GPR_ASSERT(GRPC_CALL_OK == error);
     219             : 
     220          46 :     cq_expect_completion(cqv, tag(102), 1);
     221          46 :     cq_expect_completion(cqv, tag(1), 1);
     222          46 :     cq_verify(cqv);
     223             : 
     224          46 :     peer = grpc_call_get_peer(c);
     225          46 :     gpr_log(GPR_DEBUG, "got peer: '%s'", peer);
     226          46 :     gpr_free(peer);
     227             : 
     228          46 :     GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
     229          46 :     GPR_ASSERT(0 == strcmp(details, "xyz"));
     230          46 :     GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
     231          46 :     GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
     232          46 :     GPR_ASSERT(was_cancelled == 1);
     233             : 
     234          46 :     grpc_call_destroy(s);
     235             :   } else {
     236             :     /* Check for a failed connection. */
     237          12 :     cq_expect_completion(cqv, tag(1), 1);
     238          12 :     cq_verify(cqv);
     239             : 
     240          12 :     GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED);
     241             :   }
     242             : 
     243          58 :   grpc_call_destroy(c);
     244             : 
     245          58 :   cq_verifier_destroy(cqv);
     246             : 
     247             :   /* Destroy client. */
     248          58 :   grpc_channel_destroy(client);
     249             : 
     250             :   /* Destroy server. */
     251          58 :   grpc_server_shutdown_and_notify(server, cq, tag(1000));
     252          58 :   GPR_ASSERT(grpc_completion_queue_pluck(cq, tag(1000),
     253             :                                          GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5),
     254             :                                          NULL).type == GRPC_OP_COMPLETE);
     255          58 :   grpc_server_destroy(server);
     256          58 :   grpc_completion_queue_shutdown(cq);
     257          58 :   drain_cq(cq);
     258          58 :   grpc_completion_queue_destroy(cq);
     259             : 
     260          58 :   grpc_metadata_array_destroy(&initial_metadata_recv);
     261          58 :   grpc_metadata_array_destroy(&trailing_metadata_recv);
     262          58 :   grpc_metadata_array_destroy(&request_metadata_recv);
     263             : 
     264          58 :   grpc_call_details_destroy(&call_details);
     265          58 :   gpr_free(details);
     266          58 : }
     267             : 
     268           2 : int external_dns_works(const char *host) {
     269           2 :   grpc_resolved_addresses *res = grpc_blocking_resolve_address(host, "80");
     270           2 :   if (res != NULL) {
     271           2 :     grpc_resolved_addresses_destroy(res);
     272           2 :     return 1;
     273             :   }
     274           0 :   return 0;
     275             : }
     276             : 
     277           1 : int main(int argc, char **argv) {
     278           1 :   int do_ipv6 = 1;
     279             : 
     280           1 :   grpc_test_init(argc, argv);
     281           1 :   grpc_init();
     282             : 
     283           1 :   if (!grpc_ipv6_loopback_available()) {
     284           0 :     gpr_log(GPR_INFO, "Can't bind to ::1.  Skipping IPv6 tests.");
     285           0 :     do_ipv6 = 0;
     286             :   }
     287             : 
     288             :   /* For coverage, test with and without dualstack sockets. */
     289           4 :   for (grpc_forbid_dualstack_sockets_for_testing = 0;
     290           3 :        grpc_forbid_dualstack_sockets_for_testing <= 1;
     291           2 :        grpc_forbid_dualstack_sockets_for_testing++) {
     292             :     /* :: and 0.0.0.0 are handled identically. */
     293           2 :     test_connect("::", "127.0.0.1", 0, 1);
     294           2 :     test_connect("::", "::ffff:127.0.0.1", 0, 1);
     295           2 :     test_connect("::", "ipv4:127.0.0.1", 0, 1);
     296           2 :     test_connect("::", "ipv6:[::ffff:127.0.0.1]", 0, 1);
     297           2 :     test_connect("::", "localhost", 0, 1);
     298           2 :     test_connect("0.0.0.0", "127.0.0.1", 0, 1);
     299           2 :     test_connect("0.0.0.0", "::ffff:127.0.0.1", 0, 1);
     300           2 :     test_connect("0.0.0.0", "ipv4:127.0.0.1", 0, 1);
     301           2 :     test_connect("0.0.0.0", "ipv4:127.0.0.1,127.0.0.2,127.0.0.3", 0, 1);
     302           2 :     test_connect("0.0.0.0", "ipv6:[::ffff:127.0.0.1],[::ffff:127.0.0.2]", 0, 1);
     303           2 :     test_connect("0.0.0.0", "localhost", 0, 1);
     304           2 :     if (do_ipv6) {
     305           2 :       test_connect("::", "::1", 0, 1);
     306           2 :       test_connect("0.0.0.0", "::1", 0, 1);
     307           2 :       test_connect("::", "ipv6:[::1]", 0, 1);
     308           2 :       test_connect("0.0.0.0", "ipv6:[::1]", 0, 1);
     309             :     }
     310             : 
     311             :     /* These only work when the families agree. */
     312           2 :     test_connect("127.0.0.1", "127.0.0.1", 0, 1);
     313           2 :     test_connect("127.0.0.1", "ipv4:127.0.0.1", 0, 1);
     314           2 :     if (do_ipv6) {
     315           2 :       test_connect("::1", "::1", 0, 1);
     316           2 :       test_connect("::1", "127.0.0.1", 0, 0);
     317           2 :       test_connect("127.0.0.1", "::1", 0, 0);
     318           2 :       test_connect("::1", "ipv6:[::1]", 0, 1);
     319           2 :       test_connect("::1", "ipv4:127.0.0.1", 0, 0);
     320           2 :       test_connect("127.0.0.1", "ipv6:[::1]", 0, 0);
     321             :     }
     322             : 
     323           2 :     if (!external_dns_works("loopback46.unittest.grpc.io")) {
     324           0 :       gpr_log(GPR_INFO, "Skipping tests that depend on *.unittest.grpc.io.");
     325             :     } else {
     326           2 :       test_connect("loopback46.unittest.grpc.io", "loopback4.unittest.grpc.io",
     327             :                    0, 1);
     328           2 :       test_connect("loopback4.unittest.grpc.io", "loopback46.unittest.grpc.io",
     329             :                    0, 1);
     330           2 :       if (do_ipv6) {
     331           2 :         test_connect("loopback46.unittest.grpc.io",
     332             :                      "loopback6.unittest.grpc.io", 0, 1);
     333           2 :         test_connect("loopback6.unittest.grpc.io",
     334             :                      "loopback46.unittest.grpc.io", 0, 1);
     335           2 :         test_connect("loopback4.unittest.grpc.io", "loopback6.unittest.grpc.io",
     336             :                      0, 0);
     337           2 :         test_connect("loopback6.unittest.grpc.io", "loopback4.unittest.grpc.io",
     338             :                      0, 0);
     339             :       }
     340             :     }
     341             :   }
     342             : 
     343           1 :   grpc_shutdown();
     344             : 
     345           1 :   return 0;
     346             : }

Generated by: LCOV version 1.10