blob: fa88aca431f37beee251b4cc50be42b0126555ef [file] [log] [blame]
Yuchen Zenge6f01f62016-10-24 15:56:35 -07001/*
2 *
3 * Copyright 2016, 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 "src/core/lib/iomgr/resolve_address.h"
35
36#include <string.h>
37#include <sys/un.h>
38
39#include <grpc/support/alloc.h>
40#include <grpc/support/log.h>
41#include <grpc/support/sync.h>
42#include <grpc/support/thd.h>
43#include <grpc/support/time.h>
44#include <grpc/support/useful.h>
45#include "src/core/lib/iomgr/executor.h"
46#include "src/core/lib/iomgr/iomgr.h"
47#include "test/core/util/test_config.h"
48
49static gpr_timespec test_deadline(void) {
Robbie Shadeca7effc2017-01-17 09:14:29 -050050 return grpc_timeout_seconds_to_deadline(100);
Yuchen Zenge6f01f62016-10-24 15:56:35 -070051}
52
53typedef struct args_struct {
54 gpr_event ev;
55 grpc_resolved_addresses *addrs;
56 gpr_atm done_atm;
57 gpr_mu *mu;
58 grpc_pollset *pollset;
59 grpc_pollset_set *pollset_set;
60} args_struct;
61
62static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {}
63
64void args_init(grpc_exec_ctx *exec_ctx, args_struct *args) {
65 gpr_event_init(&args->ev);
Yuchen Zeng47de64c2017-02-22 19:04:38 -080066 args->pollset = gpr_zalloc(grpc_pollset_size());
Yuchen Zenge6f01f62016-10-24 15:56:35 -070067 grpc_pollset_init(args->pollset, &args->mu);
68 args->pollset_set = grpc_pollset_set_create();
69 grpc_pollset_set_add_pollset(exec_ctx, args->pollset_set, args->pollset);
70 args->addrs = NULL;
71}
72
73void args_finish(grpc_exec_ctx *exec_ctx, args_struct *args) {
74 GPR_ASSERT(gpr_event_wait(&args->ev, test_deadline()));
75 grpc_resolved_addresses_destroy(args->addrs);
76 grpc_pollset_set_del_pollset(exec_ctx, args->pollset_set, args->pollset);
Craig Tiller9e5ac1b2017-02-14 22:25:50 -080077 grpc_pollset_set_destroy(exec_ctx, args->pollset_set);
Yuchen Zenge6f01f62016-10-24 15:56:35 -070078 grpc_closure do_nothing_cb;
79 grpc_closure_init(&do_nothing_cb, do_nothing, NULL,
80 grpc_schedule_on_exec_ctx);
81 grpc_pollset_shutdown(exec_ctx, args->pollset, &do_nothing_cb);
82 // exec_ctx needs to be flushed before calling grpc_pollset_destroy()
83 grpc_exec_ctx_flush(exec_ctx);
84 grpc_pollset_destroy(args->pollset);
85 gpr_free(args->pollset);
86}
87
88static gpr_timespec n_sec_deadline(int seconds) {
89 return gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
90 gpr_time_from_seconds(seconds, GPR_TIMESPAN));
91}
92
93static void actually_poll(void *argsp) {
94 args_struct *args = argsp;
95 gpr_timespec deadline = n_sec_deadline(10);
96 while (true) {
97 bool done = gpr_atm_acq_load(&args->done_atm) != 0;
98 if (done) {
99 break;
100 }
101 gpr_timespec time_left =
102 gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME));
103 gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done,
104 time_left.tv_sec, time_left.tv_nsec);
105 GPR_ASSERT(gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) >= 0);
106 grpc_pollset_worker *worker = NULL;
107 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
108 gpr_mu_lock(args->mu);
109 GRPC_LOG_IF_ERROR(
110 "pollset_work",
111 grpc_pollset_work(&exec_ctx, args->pollset, &worker,
112 gpr_now(GPR_CLOCK_REALTIME), n_sec_deadline(1)));
113 gpr_mu_unlock(args->mu);
114 grpc_exec_ctx_finish(&exec_ctx);
115 }
116 gpr_event_set(&args->ev, (void *)1);
117}
118
119static void poll_pollset_until_request_done(args_struct *args) {
120 gpr_atm_rel_store(&args->done_atm, 0);
121 gpr_thd_id id;
122 gpr_thd_new(&id, actually_poll, args, NULL);
123}
124
125static void must_succeed(grpc_exec_ctx *exec_ctx, void *argsp,
126 grpc_error *err) {
127 args_struct *args = argsp;
128 GPR_ASSERT(err == GRPC_ERROR_NONE);
129 GPR_ASSERT(args->addrs != NULL);
130 GPR_ASSERT(args->addrs->naddrs > 0);
131 gpr_atm_rel_store(&args->done_atm, 1);
132}
133
134static void must_fail(grpc_exec_ctx *exec_ctx, void *argsp, grpc_error *err) {
135 args_struct *args = argsp;
136 GPR_ASSERT(err != GRPC_ERROR_NONE);
137 gpr_atm_rel_store(&args->done_atm, 1);
138}
139
140static void test_unix_socket(void) {
141 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
142 args_struct args;
143 args_init(&exec_ctx, &args);
144 poll_pollset_until_request_done(&args);
145 grpc_resolve_address(
146 &exec_ctx, "unix:/path/name", NULL, args.pollset_set,
147 grpc_closure_create(must_succeed, &args, grpc_schedule_on_exec_ctx),
148 &args.addrs);
149 args_finish(&exec_ctx, &args);
150 grpc_exec_ctx_finish(&exec_ctx);
151}
152
153static void test_unix_socket_path_name_too_long(void) {
154 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
155 args_struct args;
156 args_init(&exec_ctx, &args);
157 const char prefix[] = "unix:/path/name";
158 size_t path_name_length =
159 GPR_ARRAY_SIZE(((struct sockaddr_un *)0)->sun_path) + 6;
160 char *path_name = gpr_malloc(sizeof(char) * path_name_length);
161 memset(path_name, 'a', path_name_length);
162 memcpy(path_name, prefix, strlen(prefix) - 1);
163 path_name[path_name_length - 1] = '\0';
164
165 poll_pollset_until_request_done(&args);
166 grpc_resolve_address(
167 &exec_ctx, path_name, NULL, args.pollset_set,
168 grpc_closure_create(must_fail, &args, grpc_schedule_on_exec_ctx),
169 &args.addrs);
170 gpr_free(path_name);
171 args_finish(&exec_ctx, &args);
172 grpc_exec_ctx_finish(&exec_ctx);
173}
174
175int main(int argc, char **argv) {
176 grpc_test_init(argc, argv);
177 grpc_executor_init();
178 grpc_iomgr_init();
179 test_unix_socket();
180 test_unix_socket_path_name_too_long();
181 {
182 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
183 grpc_executor_shutdown(&exec_ctx);
184 grpc_iomgr_shutdown(&exec_ctx);
185 grpc_exec_ctx_finish(&exec_ctx);
186 }
187 return 0;
188}