Code

5579e3647b5f19d36990e4f56a81a9fd3d8f1780
[sysdb.git] / t / frontend / sock_test.c
1 /*
2  * SysDB - t/frontend/sock_test.c
3  * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
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
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
28 #include "frontend/sock.h"
29 #include "libsysdb_test.h"
31 #include <check.h>
33 #include <stdio.h>
34 #include <stdlib.h>
36 #include <unistd.h>
38 #include <pthread.h>
40 /*
41  * private variables
42  */
44 static sdb_fe_socket_t *sock;
46 static void
47 setup(void)
48 {
49         sock = sdb_fe_sock_create();
50         fail_unless(sock != NULL,
51                         "sdb_fe_sock_create() = NULL; expected frontend sock object");
52 } /* setup */
54 static void
55 teardown(void)
56 {
57         sdb_fe_sock_destroy(sock);
58         sock = NULL;
59 } /* teardown */
61 static void
62 sock_listen(char *tmp_file)
63 {
64         char sock_addr[strlen("unix:") + L_tmpnam + 1];
65         char *filename;
67         int check;
69         filename = tmpnam(tmp_file);
70         fail_unless(filename != NULL,
71                         "INTERNAL ERROR: tmpnam() = NULL; expected: a string");
73         sprintf(sock_addr, "unix:%s", tmp_file);
74         check = sdb_fe_sock_add_listener(sock, sock_addr);
75         fail_unless(check == 0,
76                         "sdb_fe_sock_add_listener(%s) = %i; expected: 0",
77                         sock_addr, check);
78 } /* conn */
80 /*
81  * parallel testing
82  */
84 static void *
85 sock_handler(void *data)
86 {
87         sdb_fe_loop_t *loop = data;
88         int check;
90         check = sdb_fe_sock_listen_and_serve(sock, loop);
91         fail_unless(check == 0,
92                         "sdb_fe_sock_listen_and_serve() = %i; "
93                         "expected: 0 (after adding listener)", check);
94         return NULL;
95 } /* sock_handler */
97 /*
98  * tests
99  */
101 START_TEST(test_listen_and_serve)
103         sdb_fe_loop_t loop = SDB_FE_LOOP_INIT;
105         char tmp_file[L_tmpnam];
106         int check;
108         pthread_t thr;
110         check = sdb_fe_sock_listen_and_serve(sock, &loop);
111         fail_unless(check < 0,
112                         "sdb_fe_sock_listen_and_serve() = %i; "
113                         "expected: <0 (before adding listeners)", check);
115         sock_listen(tmp_file);
117         loop.do_loop = 1;
118         check = pthread_create(&thr, /* attr = */ NULL, sock_handler, &loop);
119         fail_unless(check == 0,
120                         "INTERNAL ERROR: pthread_create() = %i; expected: 0", check);
122         /* wait for the socket to appear */
123         while (access(tmp_file, F_OK)) {
124                 struct timespec ts = { 0, 100000000 };
125                 nanosleep(&ts, NULL);
126         }
128         loop.do_loop = 0;
129         pthread_join(thr, NULL);
131         unlink(tmp_file);
133         /* should do nothing and not report errors */
134         check = sdb_fe_sock_listen_and_serve(sock, &loop);
135         fail_unless(check == 0,
136                         "sdb_fe_sock_listen_and_serve() = %i; "
137                         "expected: <0 (do_loop == 0)", check);
138         fail_unless(access(tmp_file, F_OK),
139                         "sdb_fe_sock_listen_and_serve() recreated socket "
140                         "(do_loop == 0)");
142 END_TEST
144 Suite *
145 fe_sock_suite(void)
147         Suite *s = suite_create("frontend::sock");
148         TCase *tc;
150         tc = tcase_create("core");
151         tcase_add_checked_fixture(tc, setup, teardown);
152         tcase_add_test(tc, test_listen_and_serve);
153         suite_add_tcase(s, tc);
155         return s;
156 } /* util_unixsock_suite */
158 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */