Branch data Line data Source code
1 : : /*
2 : : SSSD
3 : :
4 : : Async resolver tests
5 : :
6 : : Authors:
7 : : Martin Nagy <mnagy@redhat.com>
8 : : Jakub Hrozek <jhrozek@redhat.com>
9 : :
10 : : Copyright (C) Red Hat, Inc 2009
11 : :
12 : : This program is free software; you can redistribute it and/or modify
13 : : it under the terms of the GNU General Public License as published by
14 : : the Free Software Foundation; either version 3 of the License, or
15 : : (at your option) any later version.
16 : :
17 : : This program is distributed in the hope that it will be useful,
18 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : : GNU General Public License for more details.
21 : :
22 : : You should have received a copy of the GNU General Public License
23 : : along with this program. If not, see <http://www.gnu.org/licenses/>.
24 : : */
25 : :
26 : : #include <stdlib.h>
27 : : #include <check.h>
28 : : #include <string.h>
29 : : #include <talloc.h>
30 : : #include <tevent.h>
31 : : #include <popt.h>
32 : : #include <arpa/inet.h>
33 : :
34 : : #include "tests/common.h"
35 : : #include "util/util.h"
36 : : #include "tests/common.h"
37 : :
38 : : /* Interface under test */
39 : : #include "resolv/async_resolv.h"
40 : :
41 : : #define RESOLV_DEFAULT_TIMEOUT 5
42 : :
43 : : static int use_net_test;
44 : : static char *txt_host;
45 : : static char *srv_host;
46 : :
47 : : struct resolv_test_ctx {
48 : : struct tevent_context *ev;
49 : : struct resolv_ctx *resolv;
50 : :
51 : : enum {
52 : : TESTING_HOSTNAME,
53 : : TESTING_TXT,
54 : : TESTING_SRV,
55 : : } tested_function;
56 : :
57 : : int error;
58 : : bool done;
59 : : };
60 : :
61 : 4 : static int setup_resolv_test(int timeout, struct resolv_test_ctx **ctx)
62 : : {
63 : : struct resolv_test_ctx *test_ctx;
64 : : int ret;
65 : :
66 : 4 : test_ctx = talloc_zero(global_talloc_context, struct resolv_test_ctx);
67 [ - + ]: 4 : if (test_ctx == NULL) {
68 : 0 : fail("Could not allocate memory for test context");
69 : 0 : return ENOMEM;
70 : : }
71 : :
72 : 4 : test_ctx->ev = tevent_context_init(test_ctx);
73 [ - + ]: 4 : if (test_ctx->ev == NULL) {
74 : 0 : fail("Could not init tevent context");
75 : 0 : talloc_free(test_ctx);
76 : 0 : return EFAULT;
77 : : }
78 : :
79 : 4 : ret = resolv_init(test_ctx, test_ctx->ev, timeout, &test_ctx->resolv);
80 [ - + ]: 4 : if (ret != EOK) {
81 : 0 : fail("Could not init resolv context");
82 : 0 : talloc_free(test_ctx);
83 : 0 : return ret;
84 : : }
85 : :
86 : 4 : *ctx = test_ctx;
87 : 4 : return EOK;
88 : : }
89 : :
90 : 3 : static int test_loop(struct resolv_test_ctx *data)
91 : : {
92 [ + + ]: 16 : while (!data->done)
93 : 13 : tevent_loop_once(data->ev);
94 : :
95 : 3 : return data->error;
96 : : }
97 : :
98 : 1 : START_TEST(test_copy_hostent)
99 : : {
100 : : void *ctx;
101 : : struct resolv_hostent *rhe;
102 : :
103 : 1 : char name[] = "foo.example.com";
104 : 1 : char alias_1[] = "bar.example.com";
105 : 1 : char alias_2[] = "baz.example.com";
106 : 1 : char *aliases[] = { alias_1, alias_2, NULL };
107 : 1 : struct in_addr addr_1 = { 1234 };
108 : 1 : struct in_addr addr_2 = { 5678 };
109 : 1 : int ttl_1 = 12;
110 : 1 : int ttl_2 = 34;
111 : 1 : char *addr_list[] = { (char *) &addr_2, (char *) &addr_1, NULL };
112 : 1 : struct hostent he = {
113 : : name, aliases, AF_INET,
114 : : sizeof(addr_1), addr_list
115 : : };
116 : 1 : struct ares_addrttl attl[] = { { addr_1, ttl_1 }, { addr_2, ttl_2 } };
117 : :
118 : 1 : ctx = talloc_new(global_talloc_context);
119 : 1 : fail_if(ctx == NULL);
120 : :
121 : 1 : check_leaks_push(ctx);
122 : :
123 : 1 : rhe = resolv_copy_hostent_ares(ctx, &he, AF_INET, &attl, 2);
124 : :
125 : 1 : fail_if(rhe == NULL);
126 : 1 : fail_if(strcmp(rhe->name, name));
127 : 1 : fail_if(strcmp(rhe->aliases[0], alias_1));
128 : 1 : fail_if(strcmp(rhe->aliases[1], alias_2));
129 : 1 : fail_if(rhe->aliases[2] != NULL);
130 : 1 : fail_if(rhe->family != AF_INET);
131 : 1 : fail_if(memcmp(rhe->addr_list[0]->ipaddr, &addr_1, sizeof(addr_1)));
132 : 1 : fail_if(rhe->addr_list[0]->ttl != ttl_1);
133 : 1 : fail_if(memcmp(rhe->addr_list[1]->ipaddr, &addr_2, sizeof(addr_2)));
134 : 1 : fail_if(rhe->addr_list[1]->ttl != ttl_2);
135 : 1 : fail_if(rhe->addr_list[2] != NULL);
136 : :
137 : 1 : talloc_zfree(rhe);
138 : :
139 : 1 : rhe = resolv_copy_hostent(ctx, &he);
140 : 1 : fail_if(rhe == NULL);
141 : 1 : fail_if(strcmp(rhe->name, name));
142 : 1 : fail_if(strcmp(rhe->aliases[0], alias_1));
143 : 1 : fail_if(strcmp(rhe->aliases[1], alias_2));
144 : 1 : fail_if(rhe->aliases[2] != NULL);
145 : 1 : fail_if(rhe->family != AF_INET);
146 : 1 : fail_if(memcmp(rhe->addr_list[0]->ipaddr, &addr_2, sizeof(addr_1)));
147 : 1 : fail_if(rhe->addr_list[0]->ttl != RESOLV_DEFAULT_TTL);
148 : 1 : fail_if(memcmp(rhe->addr_list[1]->ipaddr, &addr_1, sizeof(addr_2)));
149 : 1 : fail_if(rhe->addr_list[1]->ttl != RESOLV_DEFAULT_TTL);
150 : 1 : fail_if(rhe->addr_list[2] != NULL);
151 : :
152 : 1 : talloc_free(rhe);
153 : :
154 : 1 : check_leaks_pop(ctx);
155 : : }
156 : 1 : END_TEST
157 : :
158 : 1 : static void test_ip_addr(struct tevent_req *req)
159 : : {
160 : : int recv_status;
161 : : int status;
162 : : struct resolv_hostent *rhostent;
163 : : int i;
164 : 1 : struct resolv_test_ctx *test_ctx = tevent_req_callback_data(req,
165 : : struct resolv_test_ctx);
166 : :
167 : 1 : test_ctx->done = true;
168 : :
169 : 1 : recv_status = resolv_gethostbyname_recv(req, test_ctx,
170 : : &status, NULL, &rhostent);
171 : 1 : talloc_zfree(req);
172 [ - + ]: 1 : if (recv_status != EOK) {
173 [ # # ][ # # ]: 0 : DEBUG(2, ("resolv_gethostbyname_recv failed: %d\n", recv_status));
[ # # ][ # # ]
[ # # ]
174 : 0 : test_ctx->error = recv_status;
175 : 1 : return;
176 : : }
177 [ + - ][ - + ]: 1 : DEBUG(7, ("resolv_gethostbyname_recv status: %d\n", status));
[ # # ][ # # ]
[ # # ]
178 : :
179 : 1 : test_ctx->error = ENOENT;
180 [ + + ]: 2 : for (i = 0; rhostent->addr_list[i]; i++) {
181 : : char addr_buf[256];
182 : 1 : inet_ntop(rhostent->family,
183 : 1 : rhostent->addr_list[i]->ipaddr,
184 : : addr_buf, sizeof(addr_buf));
185 : :
186 [ + - ]: 1 : if (strcmp(addr_buf, "127.0.0.1") == 0) {
187 : 1 : test_ctx->error = EOK;
188 : : }
189 : : }
190 : 1 : talloc_free(rhostent);
191 : : }
192 : :
193 : 1 : START_TEST(test_resolv_ip_addr)
194 : : {
195 : : struct resolv_test_ctx *test_ctx;
196 : 1 : int ret = EOK;
197 : : struct tevent_req *req;
198 : 1 : const char *hostname = "127.0.0.1";
199 : :
200 : 1 : ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
201 [ - + ]: 1 : if (ret != EOK) {
202 : 0 : fail("Could not set up test");
203 : 1 : return;
204 : : }
205 : :
206 : 1 : check_leaks_push(test_ctx);
207 : 1 : req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
208 : 1 : test_ctx->resolv, hostname, IPV4_ONLY,
209 : : default_host_dbs);
210 [ + - ][ - + ]: 1 : DEBUG(7, ("Sent resolv_gethostbyname\n"));
[ # # ][ # # ]
[ # # ]
211 [ - + ]: 1 : if (req == NULL) {
212 : 0 : ret = ENOMEM;
213 : : }
214 : :
215 [ + - ]: 1 : if (ret == EOK) {
216 : 1 : tevent_req_set_callback(req, test_ip_addr, test_ctx);
217 : 1 : ret = test_loop(test_ctx);
218 : : }
219 : :
220 : 1 : check_leaks_pop(test_ctx);
221 : 1 : fail_unless(ret == EOK);
222 : :
223 : 1 : talloc_zfree(test_ctx);
224 : : }
225 : : END_TEST
226 : :
227 : 0 : static void test_localhost(struct tevent_req *req)
228 : : {
229 : : int recv_status;
230 : : int status;
231 : : struct resolv_hostent *rhostent;
232 : : int i;
233 : 0 : struct resolv_test_ctx *test_ctx = tevent_req_callback_data(req,
234 : : struct resolv_test_ctx);
235 : :
236 : 0 : test_ctx->done = true;
237 : :
238 : 0 : recv_status = resolv_gethostbyname_recv(req, test_ctx,
239 : : &status, NULL, &rhostent);
240 : 0 : talloc_zfree(req);
241 [ # # ]: 0 : if (recv_status != EOK) {
242 [ # # ][ # # ]: 0 : DEBUG(2, ("resolv_gethostbyname_recv failed: %d\n", recv_status));
[ # # ][ # # ]
[ # # ]
243 : 0 : test_ctx->error = recv_status;
244 : 0 : return;
245 : : }
246 [ # # ][ # # ]: 0 : DEBUG(7, ("resolv_gethostbyname_recv status: %d\n", status));
[ # # ][ # # ]
[ # # ]
247 : :
248 : 0 : test_ctx->error = ENOENT;
249 [ # # ]: 0 : for (i = 0; rhostent->addr_list[i]; i++) {
250 : : char addr_buf[256];
251 : 0 : inet_ntop(rhostent->family, rhostent->addr_list[i]->ipaddr,
252 : : addr_buf, sizeof(addr_buf));
253 : :
254 : : /* test that localhost resolves to 127.0.0.1 or ::1 */
255 [ # # ][ # # ]: 0 : if (strcmp(addr_buf, "127.0.0.1") == 0 || strcmp(addr_buf, "::1") == 0) {
[ # # ][ # # ]
[ # # ]
256 : 0 : test_ctx->error = EOK;
257 : : }
258 : : }
259 : 0 : talloc_free(rhostent);
260 : : }
261 : :
262 : 0 : START_TEST(test_resolv_localhost)
263 : : {
264 : : struct resolv_test_ctx *test_ctx;
265 : 0 : int ret = EOK;
266 : : struct tevent_req *req;
267 : 0 : const char *hostname = "localhost.localdomain";
268 : :
269 : 0 : ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
270 [ # # ]: 0 : if (ret != EOK) {
271 : 0 : fail("Could not set up test");
272 : 0 : return;
273 : : }
274 : :
275 : 0 : check_leaks_push(test_ctx);
276 : 0 : req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
277 : 0 : test_ctx->resolv, hostname, IPV4_FIRST,
278 : : default_host_dbs);
279 [ # # ][ # # ]: 0 : DEBUG(7, ("Sent resolv_gethostbyname\n"));
[ # # ][ # # ]
[ # # ]
280 [ # # ]: 0 : if (req == NULL) {
281 : 0 : ret = ENOMEM;
282 : : }
283 : :
284 [ # # ]: 0 : if (ret == EOK) {
285 : 0 : tevent_req_set_callback(req, test_localhost, test_ctx);
286 : 0 : ret = test_loop(test_ctx);
287 : : }
288 : :
289 : 0 : check_leaks_pop(test_ctx);
290 : 0 : fail_unless(ret == EOK);
291 : :
292 : 0 : talloc_zfree(test_ctx);
293 : : }
294 : : END_TEST
295 : :
296 : 0 : static void test_negative(struct tevent_req *req)
297 : : {
298 : : int recv_status;
299 : : int status;
300 : : struct resolv_hostent *hostent;
301 : : struct resolv_test_ctx *test_ctx;
302 : :
303 : 0 : test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx);
304 : 0 : test_ctx->done = true;
305 : :
306 : 0 : recv_status = resolv_gethostbyname_recv(req, test_ctx,
307 : : &status, NULL, &hostent);
308 : 0 : talloc_zfree(req);
309 [ # # ]: 0 : if (recv_status == EOK) {
310 [ # # ][ # # ]: 0 : DEBUG(7, ("resolv_gethostbyname_recv succeeded in a negative test\n"));
[ # # ][ # # ]
[ # # ]
311 : 0 : return;
312 : : }
313 : :
314 : 0 : test_ctx->error = status;
315 [ # # ][ # # ]: 0 : DEBUG(2, ("resolv_gethostbyname_recv status: %d: %s\n", status, resolv_strerror(status)));
[ # # ][ # # ]
[ # # ]
316 : : }
317 : :
318 : 0 : START_TEST(test_resolv_negative)
319 : : {
320 : 0 : int ret = EOK;
321 : : struct tevent_req *req;
322 : 0 : const char *hostname = "sssd.foo";
323 : : struct resolv_test_ctx *test_ctx;
324 : :
325 : 0 : ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
326 [ # # ]: 0 : if (ret != EOK) {
327 : 0 : fail("Could not set up test");
328 : 0 : return;
329 : : }
330 : :
331 : 0 : check_leaks_push(test_ctx);
332 : 0 : req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
333 : 0 : test_ctx->resolv, hostname, IPV4_FIRST,
334 : : default_host_dbs);
335 [ # # ][ # # ]: 0 : DEBUG(7, ("Sent resolv_gethostbyname\n"));
[ # # ][ # # ]
[ # # ]
336 [ # # ]: 0 : if (req == NULL) {
337 : 0 : ret = ENOMEM;
338 : : }
339 : :
340 [ # # ]: 0 : if (ret == EOK) {
341 : 0 : tevent_req_set_callback(req, test_negative, test_ctx);
342 : 0 : ret = test_loop(test_ctx);
343 : : }
344 : :
345 : 0 : check_leaks_pop(test_ctx);
346 : :
347 : 0 : fail_unless(ret != EOK);
348 : 0 : fail_unless(test_ctx->error == ARES_ENOTFOUND);
349 : 0 : talloc_zfree(test_ctx);
350 : : }
351 : : END_TEST
352 : :
353 : 0 : static void test_internet(struct tevent_req *req)
354 : : {
355 : : int recv_status;
356 : : int status;
357 : : struct resolv_test_ctx *test_ctx;
358 : : void *tmp_ctx;
359 : 0 : struct resolv_hostent *rhostent = NULL;
360 : 0 : struct ares_txt_reply *txt_replies = NULL, *txtptr;
361 : 0 : struct ares_srv_reply *srv_replies = NULL, *srvptr;
362 : : int i;
363 : :
364 : 0 : test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx);
365 : :
366 : 0 : test_ctx->done = true;
367 : :
368 : 0 : tmp_ctx = talloc_new(test_ctx);
369 : 0 : check_leaks_push(tmp_ctx);
370 : :
371 [ # # # # ]: 0 : switch (test_ctx->tested_function) {
372 : : case TESTING_HOSTNAME:
373 : 0 : recv_status = resolv_gethostbyname_recv(req, tmp_ctx,
374 : : &status, NULL, &rhostent);
375 [ # # ]: 0 : test_ctx->error = (rhostent->name == NULL) ? ENOENT : EOK;
376 [ # # ]: 0 : if (test_ctx->error == EOK) {
377 : : char addr_buf[256];
378 [ # # ]: 0 : for (i=0; rhostent->addr_list[i]; i++) {
379 : 0 : inet_ntop(rhostent->family,
380 : 0 : rhostent->addr_list[i]->ipaddr,
381 : : addr_buf, sizeof(addr_buf));
382 [ # # ][ # # ]: 0 : DEBUG(2, ("Found address %s with TTL %d\n",
[ # # ][ # # ]
[ # # ]
383 : : addr_buf, rhostent->addr_list[i]->ttl));
384 : : }
385 : : }
386 : : break;
387 : : case TESTING_TXT:
388 : 0 : recv_status = resolv_gettxt_recv(tmp_ctx, req, &status, NULL,
389 : : &txt_replies);
390 [ # # ]: 0 : test_ctx->error = (txt_replies == NULL) ? ENOENT : EOK;
391 [ # # ]: 0 : for (txtptr = txt_replies; txtptr != NULL; txtptr = txtptr->next) {
392 [ # # ][ # # ]: 0 : DEBUG(2, ("TXT Record: %s\n", txtptr->txt));
[ # # ][ # # ]
[ # # ]
393 : : }
394 : : break;
395 : : case TESTING_SRV:
396 : 0 : recv_status = resolv_getsrv_recv(tmp_ctx, req, &status, NULL,
397 : : &srv_replies);
398 [ # # ]: 0 : test_ctx->error = (srv_replies == NULL) ? ENOENT : EOK;
399 [ # # ]: 0 : for (srvptr = srv_replies; srvptr != NULL; srvptr = srvptr->next) {
400 [ # # ][ # # ]: 0 : DEBUG(2, ("SRV Record: %d %d %d %s\n", srvptr->weight,
[ # # ][ # # ]
[ # # ]
401 : : srvptr->priority, srvptr->port,
402 : : srvptr->host));
403 : : }
404 : : break;
405 : : default:
406 : : recv_status = EINVAL;
407 : : break;
408 : : }
409 : 0 : talloc_zfree(req);
410 : 0 : fail_if(recv_status != EOK, "The recv function failed: %d", recv_status);
411 [ # # ][ # # ]: 0 : DEBUG(7, ("recv status: %d\n", status));
[ # # ][ # # ]
[ # # ]
412 : :
413 [ # # ]: 0 : if (rhostent != NULL) {
414 : 0 : talloc_free(rhostent);
415 [ # # ]: 0 : } else if (txt_replies != NULL) {
416 : 0 : talloc_free(txt_replies);
417 [ # # ]: 0 : } else if (srv_replies != NULL) {
418 : 0 : talloc_free(srv_replies);
419 : : }
420 : 0 : check_leaks_pop(tmp_ctx);
421 : 0 : }
422 : :
423 : 0 : START_TEST(test_resolv_internet)
424 : : {
425 : 0 : int ret = EOK;
426 : : struct tevent_req *req;
427 : 0 : const char *hostname = "redhat.com";
428 : : struct resolv_test_ctx *test_ctx;
429 : :
430 : 0 : ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
431 [ # # ]: 0 : if (ret != EOK) {
432 : 0 : fail("Could not set up test");
433 : 0 : return;
434 : : }
435 : 0 : test_ctx->tested_function = TESTING_HOSTNAME;
436 : :
437 : 0 : check_leaks_push(test_ctx);
438 : 0 : req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
439 : 0 : test_ctx->resolv, hostname, IPV4_FIRST,
440 : : default_host_dbs);
441 [ # # ][ # # ]: 0 : DEBUG(7, ("Sent resolv_gethostbyname\n"));
[ # # ][ # # ]
[ # # ]
442 [ # # ]: 0 : if (req == NULL) {
443 : 0 : ret = ENOMEM;
444 : : }
445 : :
446 [ # # ]: 0 : if (ret == EOK) {
447 : 0 : tevent_req_set_callback(req, test_internet, test_ctx);
448 : 0 : ret = test_loop(test_ctx);
449 : : }
450 : :
451 : 0 : fail_unless(ret == EOK);
452 : 0 : check_leaks_pop(test_ctx);
453 : 0 : talloc_zfree(test_ctx);
454 : : }
455 : : END_TEST
456 : :
457 : 0 : START_TEST(test_resolv_internet_txt)
458 : : {
459 : : int ret;
460 : : struct tevent_req *req;
461 : : struct resolv_test_ctx *test_ctx;
462 : :
463 : 0 : ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
464 : 0 : fail_if(ret != EOK, "Could not set up test");
465 : 0 : test_ctx->tested_function = TESTING_TXT;
466 : :
467 : 0 : check_leaks_push(test_ctx);
468 : :
469 : 0 : req = resolv_gettxt_send(test_ctx, test_ctx->ev, test_ctx->resolv, txt_host);
470 : 0 : fail_if(req == NULL, "Function resolv_gettxt_send failed");
471 : :
472 : 0 : tevent_req_set_callback(req, test_internet, test_ctx);
473 : 0 : ret = test_loop(test_ctx);
474 : 0 : fail_unless(ret == EOK);
475 : :
476 : 0 : check_leaks_pop(test_ctx);
477 : :
478 : 0 : talloc_zfree(test_ctx);
479 : : }
480 : 0 : END_TEST
481 : :
482 : 0 : START_TEST(test_resolv_internet_srv)
483 : : {
484 : : int ret;
485 : : struct tevent_req *req;
486 : : struct resolv_test_ctx *test_ctx;
487 : :
488 : 0 : ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
489 : 0 : fail_if(ret != EOK, "Could not set up test");
490 : 0 : test_ctx->tested_function = TESTING_SRV;
491 : :
492 : 0 : check_leaks_push(test_ctx);
493 : :
494 : 0 : req = resolv_getsrv_send(test_ctx, test_ctx->ev, test_ctx->resolv, srv_host);
495 : 0 : fail_if(req == NULL, "Function resolv_getsrv_send failed");
496 : :
497 : 0 : tevent_req_set_callback(req, test_internet, test_ctx);
498 : 0 : ret = test_loop(test_ctx);
499 : 0 : fail_unless(ret == EOK);
500 : :
501 : 0 : check_leaks_pop(test_ctx);
502 : :
503 : 0 : talloc_zfree(test_ctx);
504 : : }
505 : 0 : END_TEST
506 : :
507 : 1 : static void resolv_free_context(struct tevent_context *ev,
508 : : struct tevent_timer *te,
509 : : struct timeval t, void *ptr)
510 : : {
511 : 1 : struct resolv_ctx *rctx = talloc_get_type(ptr, struct resolv_ctx);
512 [ + - ][ - + ]: 1 : DEBUG(7, ("freeing the context\n"));
[ # # ][ # # ]
[ # # ]
513 : :
514 : 1 : talloc_free(rctx);
515 : 1 : }
516 : :
517 : 2 : static void resolv_free_done(struct tevent_context *ev,
518 : : struct tevent_timer *te,
519 : : struct timeval t, void *ptr)
520 : : {
521 : 2 : struct resolv_test_ctx *tctx = talloc_get_type(ptr, struct resolv_test_ctx);
522 [ + - ][ - + ]: 2 : DEBUG(7, ("marking test as done\n"));
[ # # ][ # # ]
[ # # ]
523 : :
524 : 2 : tctx->error = EOK;
525 : 2 : tctx->done = true;
526 : 2 : }
527 : :
528 : 1 : START_TEST(test_resolv_free_context)
529 : : {
530 : 1 : int ret = EOK;
531 : : struct tevent_req *req;
532 : 1 : const char *hostname = "redhat.com";
533 : : struct resolv_test_ctx *test_ctx;
534 : : struct tevent_timer *free_timer, *terminate_timer;
535 : : struct timeval free_tv, terminate_tv;
536 : :
537 : 1 : ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
538 [ - + ]: 1 : if (ret != EOK) {
539 : 0 : fail("Could not set up test");
540 : 1 : return;
541 : : }
542 : :
543 : 1 : req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
544 : 1 : test_ctx->resolv, hostname, IPV4_FIRST,
545 : : default_host_dbs);
546 [ + - ][ - + ]: 1 : DEBUG(7, ("Sent resolv_gethostbyname\n"));
[ # # ][ # # ]
[ # # ]
547 [ - + ]: 1 : if (req == NULL) {
548 : 0 : fail("Error calling resolv_gethostbyname_send");
549 : : goto done;
550 : : }
551 : :
552 : 1 : gettimeofday(&free_tv, NULL);
553 : 1 : free_tv.tv_sec += 1;
554 : 1 : free_tv.tv_usec = 0;
555 : 1 : terminate_tv.tv_sec = free_tv.tv_sec + 1;
556 : 1 : terminate_tv.tv_usec = 0;
557 : :
558 : 1 : free_timer = tevent_add_timer(test_ctx->ev, test_ctx, free_tv, resolv_free_context, test_ctx->resolv);
559 [ - + ]: 1 : if (free_timer == NULL) {
560 : 0 : fail("Error calling tevent_add_timer");
561 : : goto done;
562 : : }
563 : :
564 : 1 : terminate_timer = tevent_add_timer(test_ctx->ev, test_ctx, terminate_tv, resolv_free_done, test_ctx);
565 [ - + ]: 1 : if (terminate_timer == NULL) {
566 : 0 : fail("Error calling tevent_add_timer");
567 : : goto done;
568 : : }
569 : :
570 : 1 : ret = test_loop(test_ctx);
571 : 1 : fail_unless(ret == EOK);
572 : :
573 : : done:
574 : 1 : talloc_zfree(test_ctx);
575 : : }
576 : : END_TEST
577 : :
578 : 1 : static void resolv_free_req(struct tevent_context *ev,
579 : : struct tevent_timer *te,
580 : : struct timeval t, void *ptr)
581 : : {
582 : 1 : struct tevent_req *req = talloc_get_type(ptr, struct tevent_req);
583 [ + - ][ - + ]: 1 : DEBUG(7, ("freeing the request\n"));
[ # # ][ # # ]
[ # # ]
584 : :
585 : 1 : talloc_free(req);
586 : 1 : }
587 : :
588 : 1 : START_TEST(test_resolv_sort_srv_reply)
589 : : {
590 : : int ret;
591 : 1 : struct ares_srv_reply *replies = NULL;
592 : 1 : struct ares_srv_reply *r, *prev = NULL;
593 : : struct resolv_test_ctx *test_ctx;
594 : 1 : int num_replies = 3;
595 : : int i;
596 : :
597 : 1 : ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
598 [ - + ]: 1 : if (ret != EOK) {
599 : 0 : fail("Could not set up test");
600 : 1 : return;
601 : : }
602 : :
603 : 1 : check_leaks_push(test_ctx);
604 : :
605 : : /* prepare linked list with reversed values */
606 [ + + ]: 4 : for (i = 0; i<num_replies; i++) {
607 : 3 : r = talloc_zero(test_ctx, struct ares_srv_reply);
608 : 3 : fail_if(r == NULL);
609 : 3 : r->priority = num_replies-i;
610 : 3 : r->weight = i;
611 : :
612 [ + + ]: 3 : if (!replies) {
613 : 1 : replies = r;
614 : 1 : prev = r;
615 : : } else {
616 : 2 : prev->next = r;
617 : 2 : prev = prev->next;
618 : : }
619 : : }
620 : :
621 : : /* do the sort */
622 : 1 : ret = resolv_sort_srv_reply(test_ctx, &replies);
623 : 1 : fail_if(ret != EOK);
624 : :
625 : : /* check if the list is sorted */
626 : 1 : prev = NULL;
627 [ + + ]: 4 : for (i = 1, r = replies; r; r=r->next, i++) {
628 : 3 : talloc_zfree(prev);
629 : 3 : prev = r;
630 : 3 : fail_unless(r->priority == i);
631 : : }
632 : 1 : talloc_zfree(prev);
633 : :
634 : : /* check if the list is complete */
635 : 1 : fail_unless(i-1 == num_replies);
636 : :
637 : : /* test if the weighting algorithm runs..not much do
638 : : * deterministically test here since it is based on
639 : : * random weight-selection */
640 : 1 : replies = NULL;
641 [ + + ]: 4 : for (i = 0; i<num_replies; i++) {
642 : 3 : r = talloc_zero(test_ctx, struct ares_srv_reply);
643 : 3 : fail_if(r == NULL);
644 : 3 : r->priority = i % 2 + 1;
645 : 3 : r->weight = i;
646 : :
647 [ + + ]: 3 : if (!replies) {
648 : 1 : replies = r;
649 : 1 : prev = r;
650 : : } else {
651 : 2 : prev->next = r;
652 : 2 : prev = prev->next;
653 : : }
654 : : }
655 : :
656 : : /* do the sort */
657 : 1 : ret = resolv_sort_srv_reply(test_ctx, &replies);
658 : 1 : fail_if(ret != EOK);
659 : :
660 : : /* clean up */
661 : 1 : prev = NULL;
662 [ + + ]: 4 : for (i = 1, r = replies; r; r=r->next, i++) {
663 : 3 : talloc_zfree(prev);
664 : 3 : prev = r;
665 : : }
666 : 1 : talloc_zfree(prev);
667 : :
668 : :
669 : : /* check for leaks */
670 : 1 : check_leaks_pop(test_ctx);
671 : 1 : talloc_zfree(test_ctx);
672 : : }
673 : : END_TEST
674 : :
675 : 1 : START_TEST(test_resolv_free_req)
676 : : {
677 : 1 : int ret = EOK;
678 : : struct tevent_req *req;
679 : 1 : const char *hostname = "redhat.com";
680 : : struct resolv_test_ctx *test_ctx;
681 : : struct tevent_timer *free_timer, *terminate_timer;
682 : : struct timeval free_tv, terminate_tv;
683 : :
684 : 1 : ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
685 [ - + ]: 1 : if (ret != EOK) {
686 : 0 : fail("Could not set up test");
687 : 1 : return;
688 : : }
689 : :
690 : 1 : check_leaks_push(test_ctx);
691 : 1 : req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
692 : 1 : test_ctx->resolv, hostname, IPV4_FIRST,
693 : : default_host_dbs);
694 [ + - ][ - + ]: 1 : DEBUG(7, ("Sent resolv_gethostbyname\n"));
[ # # ][ # # ]
[ # # ]
695 [ - + ]: 1 : if (req == NULL) {
696 : 0 : fail("Error calling resolv_gethostbyname_send");
697 : : goto done;
698 : : }
699 : :
700 : 1 : gettimeofday(&free_tv, NULL);
701 : 1 : free_tv.tv_sec += 1;
702 : 1 : free_tv.tv_usec = 0;
703 : 1 : terminate_tv.tv_sec = free_tv.tv_sec + 1;
704 : 1 : terminate_tv.tv_usec = 0;
705 : :
706 : 1 : free_timer = tevent_add_timer(test_ctx->ev, test_ctx, free_tv, resolv_free_req, req);
707 [ - + ]: 1 : if (free_timer == NULL) {
708 : 0 : fail("Error calling tevent_add_timer");
709 : : goto done;
710 : : }
711 : :
712 : 1 : terminate_timer = tevent_add_timer(test_ctx->ev, test_ctx, terminate_tv, resolv_free_done, test_ctx);
713 [ - + ]: 1 : if (terminate_timer == NULL) {
714 : 0 : fail("Error calling tevent_add_timer");
715 : : goto done;
716 : : }
717 : :
718 : 1 : ret = test_loop(test_ctx);
719 : 1 : check_leaks_pop(test_ctx);
720 : 1 : fail_unless(ret == EOK);
721 : :
722 : : done:
723 : 1 : talloc_zfree(test_ctx);
724 : : }
725 : : END_TEST
726 : :
727 : 0 : static void test_timeout(struct tevent_req *req)
728 : : {
729 : : int recv_status;
730 : : int status;
731 : : struct resolv_test_ctx *test_ctx;
732 : : TALLOC_CTX *tmp_ctx;
733 : 0 : struct resolv_hostent *rhostent = NULL;
734 : :
735 : 0 : test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx);
736 : :
737 : 0 : test_ctx->done = true;
738 : :
739 : 0 : tmp_ctx = talloc_new(test_ctx);
740 : 0 : check_leaks_push(tmp_ctx);
741 : :
742 : 0 : fail_unless(test_ctx->tested_function == TESTING_HOSTNAME);
743 : 0 : recv_status = resolv_gethostbyname_recv(req, tmp_ctx,
744 : : &status, NULL, &rhostent);
745 : 0 : talloc_zfree(req);
746 : 0 : fail_unless(recv_status == ETIMEDOUT);
747 : 0 : fail_unless(status == ARES_ETIMEOUT);
748 : 0 : check_leaks_pop(tmp_ctx);
749 : 0 : talloc_free(tmp_ctx);
750 : 0 : }
751 : :
752 : 0 : START_TEST(test_resolv_timeout)
753 : : {
754 : : struct resolv_test_ctx *test_ctx;
755 : : errno_t ret;
756 : : struct tevent_req *req;
757 : 0 : const char *hostname = "redhat.com";
758 : :
759 : 0 : ret = setup_resolv_test(0, &test_ctx);
760 [ # # ]: 0 : if (ret != EOK) {
761 : 0 : fail("Could not set up test");
762 : 0 : return;
763 : : }
764 : :
765 : 0 : test_ctx->tested_function = TESTING_HOSTNAME;
766 : :
767 : 0 : req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
768 : : test_ctx->resolv, hostname, IPV4_FIRST,
769 : : default_host_dbs);
770 [ # # ][ # # ]: 0 : DEBUG(7, ("Sent resolv_gethostbyname\n"));
[ # # ][ # # ]
[ # # ]
771 [ # # ]: 0 : if (req == NULL) {
772 : 0 : ret = ENOMEM;
773 : : }
774 : :
775 [ # # ]: 0 : if (ret == EOK) {
776 : 0 : tevent_req_set_callback(req, test_timeout, test_ctx);
777 : 0 : ret = test_loop(test_ctx);
778 : : }
779 : :
780 : 0 : fail_unless(ret == EOK);
781 : 0 : talloc_zfree(test_ctx);
782 : : }
783 : : END_TEST
784 : :
785 : 6 : Suite *create_resolv_suite(void)
786 : : {
787 : 6 : Suite *s = suite_create("resolv");
788 : :
789 : 6 : TCase *tc_resolv = tcase_create("RESOLV Tests");
790 : :
791 : 6 : tcase_add_checked_fixture(tc_resolv, leak_check_setup, leak_check_teardown);
792 : : /* Do some testing */
793 : 6 : tcase_add_test(tc_resolv, test_copy_hostent);
794 : 6 : tcase_add_test(tc_resolv, test_resolv_ip_addr);
795 : 6 : tcase_add_test(tc_resolv, test_resolv_sort_srv_reply);
796 [ - + ]: 6 : if (use_net_test) {
797 : 0 : tcase_add_test(tc_resolv, test_resolv_internet);
798 : 0 : tcase_add_test(tc_resolv, test_resolv_negative);
799 : 0 : tcase_add_test(tc_resolv, test_resolv_localhost);
800 : 0 : tcase_add_test(tc_resolv, test_resolv_timeout);
801 [ # # ]: 0 : if (txt_host != NULL) {
802 : 0 : tcase_add_test(tc_resolv, test_resolv_internet_txt);
803 : : }
804 [ # # ]: 0 : if (srv_host != NULL) {
805 : 0 : tcase_add_test(tc_resolv, test_resolv_internet_srv);
806 : : }
807 : : }
808 : 6 : tcase_add_test(tc_resolv, test_resolv_free_context);
809 : 6 : tcase_add_test(tc_resolv, test_resolv_free_req);
810 : :
811 : : /* Add all test cases to the test suite */
812 : 6 : suite_add_tcase(s, tc_resolv);
813 : :
814 : 6 : return s;
815 : : }
816 : :
817 : 6 : int main(int argc, const char *argv[])
818 : : {
819 : : int opt;
820 : : poptContext pc;
821 : : int failure_count;
822 : : Suite *resolv_suite;
823 : : SRunner *sr;
824 : 6 : int debug = 0;
825 : :
826 : 6 : struct poptOption long_options[] = {
827 : : POPT_AUTOHELP
828 : : { "debug-level", 'd', POPT_ARG_INT, &debug, 0, "Set debug level", NULL },
829 : : { "use-net-test", 'n', POPT_ARG_NONE, 0, 'n', "Run tests that need an active internet connection", NULL },
830 : : { "txt-host", 't', POPT_ARG_STRING, 0, 't', "Specify the host used for TXT record testing", NULL },
831 : : { "srv-host", 's', POPT_ARG_STRING, 0, 's', "Specify the host used for SRV record testing", NULL },
832 : : POPT_TABLEEND
833 : : };
834 : :
835 : : /* Set debug level to invalid value so we can deside if -d 0 was used. */
836 : 6 : debug_level = SSSDBG_INVALID;
837 : :
838 : 6 : pc = poptGetContext(argv[0], argc, argv, long_options, 0);
839 [ - + ]: 6 : while((opt = poptGetNextOpt(pc)) != -1) {
840 [ # # # # ]: 0 : switch(opt) {
841 : : case 'n':
842 : 0 : use_net_test = 1;
843 : 0 : break;
844 : : case 't':
845 : 0 : txt_host = poptGetOptArg(pc);
846 : 0 : break;
847 : : case 's':
848 : 0 : srv_host = poptGetOptArg(pc);
849 : 0 : break;
850 : : default:
851 : 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
852 : : poptBadOption(pc, 0), poptStrerror(opt));
853 : 0 : poptPrintUsage(pc, stderr, 0);
854 : : return 1;
855 : : }
856 : : }
857 : 6 : poptFreeContext(pc);
858 : :
859 [ + - ]: 6 : DEBUG_INIT(debug);
860 : :
861 [ + - ]: 6 : if (!use_net_test) {
862 : 6 : printf("Network tests disabled. Rerun with the \"-n\" "
863 : : "option to run the full suite of tests\n");
864 : : }
865 : :
866 : 6 : tests_set_cwd();
867 : :
868 : 6 : resolv_suite = create_resolv_suite();
869 : 6 : sr = srunner_create(resolv_suite);
870 : : /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
871 : 6 : srunner_run_all(sr, CK_ENV);
872 : 1 : failure_count = srunner_ntests_failed(sr);
873 : 1 : srunner_free(sr);
874 : 1 : return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE);
875 : : }
876 : :
|