]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - lib/libnv/tests/nvlist_send_recv_test.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / lib / libnv / tests / nvlist_send_recv_test.c
1 /*-
2  * Copyright (c) 2013 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Pawel Jakub Dawidek under sponsorship from
6  * the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <sys/wait.h>
35
36 #include <err.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <unistd.h>
42
43 #include <nv.h>
44
45 static int ntest = 1;
46
47 #define CHECK(expr)     do {                                            \
48         if ((expr))                                                     \
49                 printf("ok # %d %s:%u\n", ntest, __FILE__, __LINE__);   \
50         else                                                            \
51                 printf("not ok # %d %s:%u\n", ntest, __FILE__, __LINE__);\
52         ntest++;                                                        \
53 } while (0)
54
55 #define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF)
56
57 static void
58 child(int sock)
59 {
60         nvlist_t *nvl;
61         nvlist_t *empty;
62
63         nvl = nvlist_create(0);
64         empty = nvlist_create(0);
65
66         nvlist_add_bool(nvl, "nvlist/bool/true", true);
67         nvlist_add_bool(nvl, "nvlist/bool/false", false);
68         nvlist_add_number(nvl, "nvlist/number/0", 0);
69         nvlist_add_number(nvl, "nvlist/number/1", 1);
70         nvlist_add_number(nvl, "nvlist/number/-1", -1);
71         nvlist_add_number(nvl, "nvlist/number/UINT64_MAX", UINT64_MAX);
72         nvlist_add_number(nvl, "nvlist/number/INT64_MIN", INT64_MIN);
73         nvlist_add_number(nvl, "nvlist/number/INT64_MAX", INT64_MAX);
74         nvlist_add_string(nvl, "nvlist/string/", "");
75         nvlist_add_string(nvl, "nvlist/string/x", "x");
76         nvlist_add_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz");
77         nvlist_add_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO", STDERR_FILENO);
78         nvlist_add_binary(nvl, "nvlist/binary/x", "x", 1);
79         nvlist_add_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz"));
80         nvlist_move_nvlist(nvl, "nvlist/nvlist/empty", empty);
81         nvlist_add_nvlist(nvl, "nvlist/nvlist", nvl);
82
83         nvlist_send(sock, nvl);
84
85         nvlist_destroy(nvl);
86 }
87
88 static void
89 parent(int sock)
90 {
91         nvlist_t *nvl;
92         const nvlist_t *cnvl, *empty;
93         const char *name, *cname;
94         void *cookie, *ccookie;
95         int type, ctype;
96         size_t size;
97
98         nvl = nvlist_recv(sock);
99         CHECK(nvlist_error(nvl) == 0);
100         if (nvlist_error(nvl) != 0)
101                 err(1, "nvlist_recv() failed");
102
103         cookie = NULL;
104
105         name = nvlist_next(nvl, &type, &cookie);
106         CHECK(name != NULL);
107         CHECK(type == NV_TYPE_BOOL);
108         CHECK(strcmp(name, "nvlist/bool/true") == 0);
109         CHECK(nvlist_get_bool(nvl, name) == true);
110
111         name = nvlist_next(nvl, &type, &cookie);
112         CHECK(name != NULL);
113         CHECK(type == NV_TYPE_BOOL);
114         CHECK(strcmp(name, "nvlist/bool/false") == 0);
115         CHECK(nvlist_get_bool(nvl, name) == false);
116
117         name = nvlist_next(nvl, &type, &cookie);
118         CHECK(name != NULL);
119         CHECK(type == NV_TYPE_NUMBER);
120         CHECK(strcmp(name, "nvlist/number/0") == 0);
121         CHECK(nvlist_get_number(nvl, name) == 0);
122
123         name = nvlist_next(nvl, &type, &cookie);
124         CHECK(name != NULL);
125         CHECK(type == NV_TYPE_NUMBER);
126         CHECK(strcmp(name, "nvlist/number/1") == 0);
127         CHECK(nvlist_get_number(nvl, name) == 1);
128
129         name = nvlist_next(nvl, &type, &cookie);
130         CHECK(name != NULL);
131         CHECK(type == NV_TYPE_NUMBER);
132         CHECK(strcmp(name, "nvlist/number/-1") == 0);
133         CHECK((int)nvlist_get_number(nvl, name) == -1);
134
135         name = nvlist_next(nvl, &type, &cookie);
136         CHECK(name != NULL);
137         CHECK(type == NV_TYPE_NUMBER);
138         CHECK(strcmp(name, "nvlist/number/UINT64_MAX") == 0);
139         CHECK(nvlist_get_number(nvl, name) == UINT64_MAX);
140
141         name = nvlist_next(nvl, &type, &cookie);
142         CHECK(name != NULL);
143         CHECK(type == NV_TYPE_NUMBER);
144         CHECK(strcmp(name, "nvlist/number/INT64_MIN") == 0);
145         CHECK((int64_t)nvlist_get_number(nvl, name) == INT64_MIN);
146
147         name = nvlist_next(nvl, &type, &cookie);
148         CHECK(name != NULL);
149         CHECK(type == NV_TYPE_NUMBER);
150         CHECK(strcmp(name, "nvlist/number/INT64_MAX") == 0);
151         CHECK((int64_t)nvlist_get_number(nvl, name) == INT64_MAX);
152
153         name = nvlist_next(nvl, &type, &cookie);
154         CHECK(name != NULL);
155         CHECK(type == NV_TYPE_STRING);
156         CHECK(strcmp(name, "nvlist/string/") == 0);
157         CHECK(strcmp(nvlist_get_string(nvl, name), "") == 0);
158
159         name = nvlist_next(nvl, &type, &cookie);
160         CHECK(name != NULL);
161         CHECK(type == NV_TYPE_STRING);
162         CHECK(strcmp(name, "nvlist/string/x") == 0);
163         CHECK(strcmp(nvlist_get_string(nvl, name), "x") == 0);
164
165         name = nvlist_next(nvl, &type, &cookie);
166         CHECK(name != NULL);
167         CHECK(type == NV_TYPE_STRING);
168         CHECK(strcmp(name, "nvlist/string/abcdefghijklmnopqrstuvwxyz") == 0);
169         CHECK(strcmp(nvlist_get_string(nvl, name), "abcdefghijklmnopqrstuvwxyz") == 0);
170
171         name = nvlist_next(nvl, &type, &cookie);
172         CHECK(name != NULL);
173         CHECK(type == NV_TYPE_DESCRIPTOR);
174         CHECK(strcmp(name, "nvlist/descriptor/STDERR_FILENO") == 0);
175         CHECK(fd_is_valid(nvlist_get_descriptor(nvl, name)));
176
177         name = nvlist_next(nvl, &type, &cookie);
178         CHECK(name != NULL);
179         CHECK(type == NV_TYPE_BINARY);
180         CHECK(strcmp(name, "nvlist/binary/x") == 0);
181         CHECK(memcmp(nvlist_get_binary(nvl, name, NULL), "x", 1) == 0);
182         CHECK(memcmp(nvlist_get_binary(nvl, name, &size), "x", 1) == 0);
183         CHECK(size == 1);
184
185         name = nvlist_next(nvl, &type, &cookie);
186         CHECK(name != NULL);
187         CHECK(type == NV_TYPE_BINARY);
188         CHECK(strcmp(name, "nvlist/binary/abcdefghijklmnopqrstuvwxyz") == 0);
189         CHECK(memcmp(nvlist_get_binary(nvl, name, NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
190         CHECK(memcmp(nvlist_get_binary(nvl, name, &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
191         CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz"));
192
193         name = nvlist_next(nvl, &type, &cookie);
194         CHECK(name != NULL);
195         CHECK(type == NV_TYPE_NVLIST);
196         CHECK(strcmp(name, "nvlist/nvlist/empty") == 0);
197         cnvl = nvlist_get_nvlist(nvl, name);
198         CHECK(nvlist_empty(cnvl));
199
200         name = nvlist_next(nvl, &type, &cookie);
201         CHECK(name != NULL);
202         CHECK(type == NV_TYPE_NVLIST);
203         CHECK(strcmp(name, "nvlist/nvlist") == 0);
204         cnvl = nvlist_get_nvlist(nvl, name);
205
206         ccookie = NULL;
207
208         cname = nvlist_next(cnvl, &ctype, &ccookie);
209         CHECK(cname != NULL);
210         CHECK(ctype == NV_TYPE_BOOL);
211         CHECK(strcmp(cname, "nvlist/bool/true") == 0);
212         CHECK(nvlist_get_bool(cnvl, cname) == true);
213
214         cname = nvlist_next(cnvl, &ctype, &ccookie);
215         CHECK(cname != NULL);
216         CHECK(ctype == NV_TYPE_BOOL);
217         CHECK(strcmp(cname, "nvlist/bool/false") == 0);
218         CHECK(nvlist_get_bool(cnvl, cname) == false);
219
220         cname = nvlist_next(cnvl, &ctype, &ccookie);
221         CHECK(cname != NULL);
222         CHECK(ctype == NV_TYPE_NUMBER);
223         CHECK(strcmp(cname, "nvlist/number/0") == 0);
224         CHECK(nvlist_get_number(cnvl, cname) == 0);
225
226         cname = nvlist_next(cnvl, &ctype, &ccookie);
227         CHECK(cname != NULL);
228         CHECK(ctype == NV_TYPE_NUMBER);
229         CHECK(strcmp(cname, "nvlist/number/1") == 0);
230         CHECK(nvlist_get_number(cnvl, cname) == 1);
231
232         cname = nvlist_next(cnvl, &ctype, &ccookie);
233         CHECK(cname != NULL);
234         CHECK(ctype == NV_TYPE_NUMBER);
235         CHECK(strcmp(cname, "nvlist/number/-1") == 0);
236         CHECK((int)nvlist_get_number(cnvl, cname) == -1);
237
238         cname = nvlist_next(cnvl, &ctype, &ccookie);
239         CHECK(cname != NULL);
240         CHECK(ctype == NV_TYPE_NUMBER);
241         CHECK(strcmp(cname, "nvlist/number/UINT64_MAX") == 0);
242         CHECK(nvlist_get_number(cnvl, cname) == UINT64_MAX);
243
244         cname = nvlist_next(cnvl, &ctype, &ccookie);
245         CHECK(cname != NULL);
246         CHECK(ctype == NV_TYPE_NUMBER);
247         CHECK(strcmp(cname, "nvlist/number/INT64_MIN") == 0);
248         CHECK((int64_t)nvlist_get_number(cnvl, cname) == INT64_MIN);
249
250         cname = nvlist_next(cnvl, &ctype, &ccookie);
251         CHECK(cname != NULL);
252         CHECK(ctype == NV_TYPE_NUMBER);
253         CHECK(strcmp(cname, "nvlist/number/INT64_MAX") == 0);
254         CHECK((int64_t)nvlist_get_number(cnvl, cname) == INT64_MAX);
255
256         cname = nvlist_next(cnvl, &ctype, &ccookie);
257         CHECK(cname != NULL);
258         CHECK(ctype == NV_TYPE_STRING);
259         CHECK(strcmp(cname, "nvlist/string/") == 0);
260         CHECK(strcmp(nvlist_get_string(cnvl, cname), "") == 0);
261
262         cname = nvlist_next(cnvl, &ctype, &ccookie);
263         CHECK(cname != NULL);
264         CHECK(ctype == NV_TYPE_STRING);
265         CHECK(strcmp(cname, "nvlist/string/x") == 0);
266         CHECK(strcmp(nvlist_get_string(cnvl, cname), "x") == 0);
267
268         cname = nvlist_next(cnvl, &ctype, &ccookie);
269         CHECK(cname != NULL);
270         CHECK(ctype == NV_TYPE_STRING);
271         CHECK(strcmp(cname, "nvlist/string/abcdefghijklmnopqrstuvwxyz") == 0);
272         CHECK(strcmp(nvlist_get_string(cnvl, cname), "abcdefghijklmnopqrstuvwxyz") == 0);
273
274         cname = nvlist_next(cnvl, &ctype, &ccookie);
275         CHECK(cname != NULL);
276         CHECK(ctype == NV_TYPE_DESCRIPTOR);
277         CHECK(strcmp(cname, "nvlist/descriptor/STDERR_FILENO") == 0);
278         CHECK(fd_is_valid(nvlist_get_descriptor(cnvl, cname)));
279
280         cname = nvlist_next(cnvl, &ctype, &ccookie);
281         CHECK(cname != NULL);
282         CHECK(ctype == NV_TYPE_BINARY);
283         CHECK(strcmp(cname, "nvlist/binary/x") == 0);
284         CHECK(memcmp(nvlist_get_binary(cnvl, cname, NULL), "x", 1) == 0);
285         CHECK(memcmp(nvlist_get_binary(cnvl, cname, &size), "x", 1) == 0);
286         CHECK(size == 1);
287
288         cname = nvlist_next(cnvl, &ctype, &ccookie);
289         CHECK(cname != NULL);
290         CHECK(ctype == NV_TYPE_BINARY);
291         CHECK(strcmp(cname, "nvlist/binary/abcdefghijklmnopqrstuvwxyz") == 0);
292         CHECK(memcmp(nvlist_get_binary(cnvl, cname, NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
293         CHECK(memcmp(nvlist_get_binary(cnvl, cname, &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
294         CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz"));
295
296         cname = nvlist_next(cnvl, &ctype, &ccookie);
297         CHECK(cname != NULL);
298         CHECK(ctype == NV_TYPE_NVLIST);
299         CHECK(strcmp(cname, "nvlist/nvlist/empty") == 0);
300         empty = nvlist_get_nvlist(cnvl, cname);
301         CHECK(nvlist_empty(empty));
302
303         cname = nvlist_next(cnvl, &ctype, &ccookie);
304         CHECK(cname == NULL);
305
306         name = nvlist_next(nvl, &type, &cookie);
307         CHECK(name == NULL);
308 }
309
310 int
311 main(void)
312 {
313         int status, socks[2];
314         pid_t pid;
315
316         printf("1..134\n");
317         fflush(stdout);
318
319         if (socketpair(PF_UNIX, SOCK_STREAM, 0, socks) < 0)
320                 err(1, "socketpair() failed");
321         pid = fork();
322         switch (pid) {
323         case -1:
324                 /* Failure. */
325                 err(1, "unable to fork");
326         case 0:
327                 /* Child. */
328                 close(socks[0]);
329                 child(socks[1]);
330                 return (0);
331         default:
332                 /* Parent. */
333                 close(socks[1]);
334                 parent(socks[0]);
335                 break;
336         }
337
338         if (waitpid(pid, &status, 0) < 0)
339                 err(1, "waitpid() failed");
340
341         return (0);
342 }