]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libnv/tests/nvlist_send_recv_test.c
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
[FreeBSD/FreeBSD.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 #include <sys/nv.h>
36
37 #include <err.h>
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <unistd.h>
43
44 static int ntest = 1;
45
46 #define CHECK(expr)     do {                                            \
47         if ((expr))                                                     \
48                 printf("ok # %d %s:%u\n", ntest, __FILE__, __LINE__);   \
49         else                                                            \
50                 printf("not ok # %d %s:%u\n", ntest, __FILE__, __LINE__);\
51         ntest++;                                                        \
52 } while (0)
53
54 #define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF)
55
56 static void
57 child(int sock)
58 {
59         nvlist_t *nvl;
60         nvlist_t *empty;
61
62         nvl = nvlist_create(0);
63         empty = nvlist_create(0);
64
65         nvlist_add_bool(nvl, "nvlist/bool/true", true);
66         nvlist_add_bool(nvl, "nvlist/bool/false", false);
67         nvlist_add_number(nvl, "nvlist/number/0", 0);
68         nvlist_add_number(nvl, "nvlist/number/1", 1);
69         nvlist_add_number(nvl, "nvlist/number/-1", -1);
70         nvlist_add_number(nvl, "nvlist/number/UINT64_MAX", UINT64_MAX);
71         nvlist_add_number(nvl, "nvlist/number/INT64_MIN", INT64_MIN);
72         nvlist_add_number(nvl, "nvlist/number/INT64_MAX", INT64_MAX);
73         nvlist_add_string(nvl, "nvlist/string/", "");
74         nvlist_add_string(nvl, "nvlist/string/x", "x");
75         nvlist_add_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz");
76         nvlist_add_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO", STDERR_FILENO);
77         nvlist_add_binary(nvl, "nvlist/binary/x", "x", 1);
78         nvlist_add_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz"));
79         nvlist_move_nvlist(nvl, "nvlist/nvlist/empty", empty);
80         nvlist_add_nvlist(nvl, "nvlist/nvlist", nvl);
81
82         nvlist_send(sock, nvl);
83
84         nvlist_destroy(nvl);
85 }
86
87 static void
88 parent(int sock)
89 {
90         nvlist_t *nvl;
91         const nvlist_t *cnvl, *empty;
92         const char *name, *cname;
93         void *cookie, *ccookie;
94         int type, ctype;
95         size_t size;
96
97         nvl = nvlist_recv(sock, 0);
98         CHECK(nvlist_error(nvl) == 0);
99         if (nvlist_error(nvl) != 0)
100                 err(1, "nvlist_recv() failed");
101
102         cookie = NULL;
103
104         name = nvlist_next(nvl, &type, &cookie);
105         CHECK(name != NULL);
106         CHECK(type == NV_TYPE_BOOL);
107         CHECK(strcmp(name, "nvlist/bool/true") == 0);
108         CHECK(nvlist_get_bool(nvl, name) == true);
109
110         name = nvlist_next(nvl, &type, &cookie);
111         CHECK(name != NULL);
112         CHECK(type == NV_TYPE_BOOL);
113         CHECK(strcmp(name, "nvlist/bool/false") == 0);
114         CHECK(nvlist_get_bool(nvl, name) == false);
115
116         name = nvlist_next(nvl, &type, &cookie);
117         CHECK(name != NULL);
118         CHECK(type == NV_TYPE_NUMBER);
119         CHECK(strcmp(name, "nvlist/number/0") == 0);
120         CHECK(nvlist_get_number(nvl, name) == 0);
121
122         name = nvlist_next(nvl, &type, &cookie);
123         CHECK(name != NULL);
124         CHECK(type == NV_TYPE_NUMBER);
125         CHECK(strcmp(name, "nvlist/number/1") == 0);
126         CHECK(nvlist_get_number(nvl, name) == 1);
127
128         name = nvlist_next(nvl, &type, &cookie);
129         CHECK(name != NULL);
130         CHECK(type == NV_TYPE_NUMBER);
131         CHECK(strcmp(name, "nvlist/number/-1") == 0);
132         CHECK((int)nvlist_get_number(nvl, name) == -1);
133
134         name = nvlist_next(nvl, &type, &cookie);
135         CHECK(name != NULL);
136         CHECK(type == NV_TYPE_NUMBER);
137         CHECK(strcmp(name, "nvlist/number/UINT64_MAX") == 0);
138         CHECK(nvlist_get_number(nvl, name) == UINT64_MAX);
139
140         name = nvlist_next(nvl, &type, &cookie);
141         CHECK(name != NULL);
142         CHECK(type == NV_TYPE_NUMBER);
143         CHECK(strcmp(name, "nvlist/number/INT64_MIN") == 0);
144         CHECK((int64_t)nvlist_get_number(nvl, name) == INT64_MIN);
145
146         name = nvlist_next(nvl, &type, &cookie);
147         CHECK(name != NULL);
148         CHECK(type == NV_TYPE_NUMBER);
149         CHECK(strcmp(name, "nvlist/number/INT64_MAX") == 0);
150         CHECK((int64_t)nvlist_get_number(nvl, name) == INT64_MAX);
151
152         name = nvlist_next(nvl, &type, &cookie);
153         CHECK(name != NULL);
154         CHECK(type == NV_TYPE_STRING);
155         CHECK(strcmp(name, "nvlist/string/") == 0);
156         CHECK(strcmp(nvlist_get_string(nvl, name), "") == 0);
157
158         name = nvlist_next(nvl, &type, &cookie);
159         CHECK(name != NULL);
160         CHECK(type == NV_TYPE_STRING);
161         CHECK(strcmp(name, "nvlist/string/x") == 0);
162         CHECK(strcmp(nvlist_get_string(nvl, name), "x") == 0);
163
164         name = nvlist_next(nvl, &type, &cookie);
165         CHECK(name != NULL);
166         CHECK(type == NV_TYPE_STRING);
167         CHECK(strcmp(name, "nvlist/string/abcdefghijklmnopqrstuvwxyz") == 0);
168         CHECK(strcmp(nvlist_get_string(nvl, name), "abcdefghijklmnopqrstuvwxyz") == 0);
169
170         name = nvlist_next(nvl, &type, &cookie);
171         CHECK(name != NULL);
172         CHECK(type == NV_TYPE_DESCRIPTOR);
173         CHECK(strcmp(name, "nvlist/descriptor/STDERR_FILENO") == 0);
174         CHECK(fd_is_valid(nvlist_get_descriptor(nvl, name)));
175
176         name = nvlist_next(nvl, &type, &cookie);
177         CHECK(name != NULL);
178         CHECK(type == NV_TYPE_BINARY);
179         CHECK(strcmp(name, "nvlist/binary/x") == 0);
180         CHECK(memcmp(nvlist_get_binary(nvl, name, NULL), "x", 1) == 0);
181         CHECK(memcmp(nvlist_get_binary(nvl, name, &size), "x", 1) == 0);
182         CHECK(size == 1);
183
184         name = nvlist_next(nvl, &type, &cookie);
185         CHECK(name != NULL);
186         CHECK(type == NV_TYPE_BINARY);
187         CHECK(strcmp(name, "nvlist/binary/abcdefghijklmnopqrstuvwxyz") == 0);
188         CHECK(memcmp(nvlist_get_binary(nvl, name, NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
189         CHECK(memcmp(nvlist_get_binary(nvl, name, &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
190         CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz"));
191
192         name = nvlist_next(nvl, &type, &cookie);
193         CHECK(name != NULL);
194         CHECK(type == NV_TYPE_NVLIST);
195         CHECK(strcmp(name, "nvlist/nvlist/empty") == 0);
196         cnvl = nvlist_get_nvlist(nvl, name);
197         CHECK(nvlist_empty(cnvl));
198
199         name = nvlist_next(nvl, &type, &cookie);
200         CHECK(name != NULL);
201         CHECK(type == NV_TYPE_NVLIST);
202         CHECK(strcmp(name, "nvlist/nvlist") == 0);
203         cnvl = nvlist_get_nvlist(nvl, name);
204
205         ccookie = NULL;
206
207         cname = nvlist_next(cnvl, &ctype, &ccookie);
208         CHECK(cname != NULL);
209         CHECK(ctype == NV_TYPE_BOOL);
210         CHECK(strcmp(cname, "nvlist/bool/true") == 0);
211         CHECK(nvlist_get_bool(cnvl, cname) == true);
212
213         cname = nvlist_next(cnvl, &ctype, &ccookie);
214         CHECK(cname != NULL);
215         CHECK(ctype == NV_TYPE_BOOL);
216         CHECK(strcmp(cname, "nvlist/bool/false") == 0);
217         CHECK(nvlist_get_bool(cnvl, cname) == false);
218
219         cname = nvlist_next(cnvl, &ctype, &ccookie);
220         CHECK(cname != NULL);
221         CHECK(ctype == NV_TYPE_NUMBER);
222         CHECK(strcmp(cname, "nvlist/number/0") == 0);
223         CHECK(nvlist_get_number(cnvl, cname) == 0);
224
225         cname = nvlist_next(cnvl, &ctype, &ccookie);
226         CHECK(cname != NULL);
227         CHECK(ctype == NV_TYPE_NUMBER);
228         CHECK(strcmp(cname, "nvlist/number/1") == 0);
229         CHECK(nvlist_get_number(cnvl, cname) == 1);
230
231         cname = nvlist_next(cnvl, &ctype, &ccookie);
232         CHECK(cname != NULL);
233         CHECK(ctype == NV_TYPE_NUMBER);
234         CHECK(strcmp(cname, "nvlist/number/-1") == 0);
235         CHECK((int)nvlist_get_number(cnvl, cname) == -1);
236
237         cname = nvlist_next(cnvl, &ctype, &ccookie);
238         CHECK(cname != NULL);
239         CHECK(ctype == NV_TYPE_NUMBER);
240         CHECK(strcmp(cname, "nvlist/number/UINT64_MAX") == 0);
241         CHECK(nvlist_get_number(cnvl, cname) == UINT64_MAX);
242
243         cname = nvlist_next(cnvl, &ctype, &ccookie);
244         CHECK(cname != NULL);
245         CHECK(ctype == NV_TYPE_NUMBER);
246         CHECK(strcmp(cname, "nvlist/number/INT64_MIN") == 0);
247         CHECK((int64_t)nvlist_get_number(cnvl, cname) == INT64_MIN);
248
249         cname = nvlist_next(cnvl, &ctype, &ccookie);
250         CHECK(cname != NULL);
251         CHECK(ctype == NV_TYPE_NUMBER);
252         CHECK(strcmp(cname, "nvlist/number/INT64_MAX") == 0);
253         CHECK((int64_t)nvlist_get_number(cnvl, cname) == INT64_MAX);
254
255         cname = nvlist_next(cnvl, &ctype, &ccookie);
256         CHECK(cname != NULL);
257         CHECK(ctype == NV_TYPE_STRING);
258         CHECK(strcmp(cname, "nvlist/string/") == 0);
259         CHECK(strcmp(nvlist_get_string(cnvl, cname), "") == 0);
260
261         cname = nvlist_next(cnvl, &ctype, &ccookie);
262         CHECK(cname != NULL);
263         CHECK(ctype == NV_TYPE_STRING);
264         CHECK(strcmp(cname, "nvlist/string/x") == 0);
265         CHECK(strcmp(nvlist_get_string(cnvl, cname), "x") == 0);
266
267         cname = nvlist_next(cnvl, &ctype, &ccookie);
268         CHECK(cname != NULL);
269         CHECK(ctype == NV_TYPE_STRING);
270         CHECK(strcmp(cname, "nvlist/string/abcdefghijklmnopqrstuvwxyz") == 0);
271         CHECK(strcmp(nvlist_get_string(cnvl, cname), "abcdefghijklmnopqrstuvwxyz") == 0);
272
273         cname = nvlist_next(cnvl, &ctype, &ccookie);
274         CHECK(cname != NULL);
275         CHECK(ctype == NV_TYPE_DESCRIPTOR);
276         CHECK(strcmp(cname, "nvlist/descriptor/STDERR_FILENO") == 0);
277         CHECK(fd_is_valid(nvlist_get_descriptor(cnvl, cname)));
278
279         cname = nvlist_next(cnvl, &ctype, &ccookie);
280         CHECK(cname != NULL);
281         CHECK(ctype == NV_TYPE_BINARY);
282         CHECK(strcmp(cname, "nvlist/binary/x") == 0);
283         CHECK(memcmp(nvlist_get_binary(cnvl, cname, NULL), "x", 1) == 0);
284         CHECK(memcmp(nvlist_get_binary(cnvl, cname, &size), "x", 1) == 0);
285         CHECK(size == 1);
286
287         cname = nvlist_next(cnvl, &ctype, &ccookie);
288         CHECK(cname != NULL);
289         CHECK(ctype == NV_TYPE_BINARY);
290         CHECK(strcmp(cname, "nvlist/binary/abcdefghijklmnopqrstuvwxyz") == 0);
291         CHECK(memcmp(nvlist_get_binary(cnvl, cname, NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
292         CHECK(memcmp(nvlist_get_binary(cnvl, cname, &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
293         CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz"));
294
295         cname = nvlist_next(cnvl, &ctype, &ccookie);
296         CHECK(cname != NULL);
297         CHECK(ctype == NV_TYPE_NVLIST);
298         CHECK(strcmp(cname, "nvlist/nvlist/empty") == 0);
299         empty = nvlist_get_nvlist(cnvl, cname);
300         CHECK(nvlist_empty(empty));
301
302         cname = nvlist_next(cnvl, &ctype, &ccookie);
303         CHECK(cname == NULL);
304
305         name = nvlist_next(nvl, &type, &cookie);
306         CHECK(name == NULL);
307 }
308
309 int
310 main(void)
311 {
312         int status, socks[2];
313         pid_t pid;
314
315         printf("1..134\n");
316         fflush(stdout);
317
318         if (socketpair(PF_UNIX, SOCK_STREAM, 0, socks) < 0)
319                 err(1, "socketpair() failed");
320         pid = fork();
321         switch (pid) {
322         case -1:
323                 /* Failure. */
324                 err(1, "unable to fork");
325         case 0:
326                 /* Child. */
327                 close(socks[0]);
328                 child(socks[1]);
329                 return (0);
330         default:
331                 /* Parent. */
332                 close(socks[1]);
333                 parent(socks[0]);
334                 break;
335         }
336
337         if (waitpid(pid, &status, 0) < 0)
338                 err(1, "waitpid() failed");
339
340         return (0);
341 }