]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/netbsd-tests/lib/librefuse/t_refuse_opt.c
MFC r314450,r313439:
[FreeBSD/stable/10.git] / contrib / netbsd-tests / lib / librefuse / t_refuse_opt.c
1 /*      $NetBSD: t_refuse_opt.c,v 1.8 2017/01/13 21:30:41 christos Exp $ */
2
3 /*-
4  * Copyright (c) 2016 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.      IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 #include <sys/cdefs.h>
29 __RCSID("$NetBSD: t_refuse_opt.c,v 1.8 2017/01/13 21:30:41 christos Exp $");
30
31 #define _KERNTYPES
32 #include <sys/types.h>
33
34 #include <atf-c.h>
35
36 #include <fuse.h>
37
38 #include "h_macros.h"
39
40 ATF_TC(t_fuse_opt_add_arg);
41 ATF_TC_HEAD(t_fuse_opt_add_arg, tc)
42 {
43         atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_add_arg(3) works");
44 }
45
46 ATF_TC_BODY(t_fuse_opt_add_arg, tc)
47 {
48         struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
49
50         RZ(fuse_opt_add_arg(&args, "foo"));
51         RZ(fuse_opt_add_arg(&args, "bar"));
52
53         ATF_REQUIRE_EQ(args.argc, 2);
54         ATF_CHECK_STREQ(args.argv[0], "foo");
55         ATF_CHECK_STREQ(args.argv[1], "bar");
56         ATF_CHECK(args.allocated != 0);
57 }
58
59 ATF_TC(t_fuse_opt_insert_arg);
60 ATF_TC_HEAD(t_fuse_opt_insert_arg, tc)
61 {
62         atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_insert_arg(3) works");
63 }
64
65 ATF_TC_BODY(t_fuse_opt_insert_arg, tc)
66 {
67         struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
68
69         RZ(fuse_opt_insert_arg(&args, 0, "foo"));
70         RZ(fuse_opt_insert_arg(&args, 0, "bar"));
71
72         ATF_REQUIRE_EQ(args.argc, 2);
73         ATF_CHECK_STREQ(args.argv[0], "bar");
74         ATF_CHECK_STREQ(args.argv[1], "foo");
75         ATF_CHECK(args.allocated != 0);
76 }
77
78 ATF_TC(t_fuse_opt_add_opt);
79 ATF_TC_HEAD(t_fuse_opt_add_opt, tc)
80 {
81         atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_add_opt(3) works");
82 }
83
84 ATF_TC_BODY(t_fuse_opt_add_opt, tc)
85 {
86         char* opt = NULL;
87
88         RZ(fuse_opt_add_opt(&opt, "fo\\o"));
89         ATF_CHECK_STREQ(opt, "fo\\o");
90
91         RZ(fuse_opt_add_opt(&opt, "ba,r"));
92         ATF_CHECK_STREQ(opt, "fo\\o,ba,r");
93 }
94
95 ATF_TC(t_fuse_opt_add_opt_escaped);
96 ATF_TC_HEAD(t_fuse_opt_add_opt_escaped, tc)
97 {
98         atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_add_opt_escaped(3) works");
99 }
100
101 ATF_TC_BODY(t_fuse_opt_add_opt_escaped, tc)
102 {
103         char* opt = NULL;
104
105         RZ(fuse_opt_add_opt_escaped(&opt, "fo\\o"));
106         ATF_CHECK_STREQ(opt, "fo\\\\o");
107
108         RZ(fuse_opt_add_opt_escaped(&opt, "ba,r"));
109         ATF_CHECK_STREQ(opt, "fo\\\\o,ba\\,r");
110 }
111
112 ATF_TC(t_fuse_opt_match);
113 ATF_TC_HEAD(t_fuse_opt_match, tc)
114 {
115         atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_match(3) works"
116                                           " for every form of templates");
117 }
118
119 ATF_TC_BODY(t_fuse_opt_match, tc)
120 {
121         struct fuse_opt o1[] = { FUSE_OPT_KEY("-x"    , 0), FUSE_OPT_END };
122         struct fuse_opt o2[] = { FUSE_OPT_KEY("foo"   , 0), FUSE_OPT_END };
123         struct fuse_opt o3[] = { FUSE_OPT_KEY("foo="  , 0), FUSE_OPT_END };
124         struct fuse_opt o4[] = { FUSE_OPT_KEY("foo=%s", 0), FUSE_OPT_END };
125         struct fuse_opt o5[] = { FUSE_OPT_KEY("-x "   , 0), FUSE_OPT_END };
126         struct fuse_opt o6[] = { FUSE_OPT_KEY("-x %s" , 0), FUSE_OPT_END };
127
128         ATF_CHECK(fuse_opt_match(o1, "-x") == 1);
129         ATF_CHECK(fuse_opt_match(o1,  "x") == 0);
130
131         ATF_CHECK(fuse_opt_match(o2,  "foo") == 1);
132         ATF_CHECK(fuse_opt_match(o2, "-foo") == 0);
133
134         ATF_CHECK(fuse_opt_match(o3, "foo=bar") == 1);
135         ATF_CHECK(fuse_opt_match(o3, "foo"    ) == 0);
136
137         ATF_CHECK(fuse_opt_match(o4, "foo=bar") == 1);
138         ATF_CHECK(fuse_opt_match(o4, "foo"    ) == 0);
139
140         ATF_CHECK(fuse_opt_match(o5, "-xbar" ) == 1);
141         ATF_CHECK(fuse_opt_match(o5, "-x"    ) == 1);
142         ATF_CHECK(fuse_opt_match(o5, "-x=bar") == 1);
143         ATF_CHECK(fuse_opt_match(o5, "bar"   ) == 0);
144
145         ATF_CHECK(fuse_opt_match(o6, "-xbar" ) == 1);
146         ATF_CHECK(fuse_opt_match(o6, "-x"    ) == 1);
147         ATF_CHECK(fuse_opt_match(o6, "-x=bar") == 1);
148         ATF_CHECK(fuse_opt_match(o6, "bar"   ) == 0);
149 }
150
151 struct foofs_config {
152         int number;
153         char *string;
154         char* nonopt;
155 };
156
157 #define FOOFS_OPT(t, p, v) { t, offsetof(struct foofs_config, p), v }
158
159 static struct fuse_opt foofs_opts[] = {
160         FOOFS_OPT("number=%i"     , number, 0),
161         FOOFS_OPT("-n %i"         , number, 0),
162         FOOFS_OPT("string=%s"     , string, 0),
163         FOOFS_OPT("number1"       , number, 1),
164         FOOFS_OPT("number2"       , number, 2),
165         FOOFS_OPT("--number=three", number, 3),
166         FOOFS_OPT("--number=four" , number, 4),
167         FUSE_OPT_END
168 };
169
170 static int foo_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) {
171         struct foofs_config *config = data;
172
173         if (key == FUSE_OPT_KEY_NONOPT && config->nonopt == NULL) {
174                 config->nonopt = strdup(arg);
175                 return 0;
176         }
177         else {
178                 return 1;
179         }
180 }
181
182 ATF_TC(t_fuse_opt_parse_null_args);
183 ATF_TC_HEAD(t_fuse_opt_parse_null_args, tc)
184 {
185         atf_tc_set_md_var(tc, "descr", "NULL args means an empty arguments vector");
186 }
187
188 ATF_TC_BODY(t_fuse_opt_parse_null_args, tc)
189 {
190         struct foofs_config config;
191
192         memset(&config, 0, sizeof(config));
193         ATF_CHECK(fuse_opt_parse(NULL, &config, NULL, NULL) == 0);
194         ATF_CHECK_EQ(config.number, 0);
195         ATF_CHECK_EQ(config.string, NULL);
196         ATF_CHECK_EQ(config.nonopt, NULL);
197 }
198
199 ATF_TC(t_fuse_opt_parse_null_opts);
200 ATF_TC_HEAD(t_fuse_opt_parse_null_opts, tc)
201 {
202         atf_tc_set_md_var(tc, "descr", "NULL opts means an opts array which only has FUSE_OPT_END");
203 }
204
205 ATF_TC_BODY(t_fuse_opt_parse_null_opts, tc)
206 {
207         struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
208         struct foofs_config config;
209
210         RZ(fuse_opt_add_arg(&args, "foofs"));
211         RZ(fuse_opt_add_arg(&args, "-o"));
212         RZ(fuse_opt_add_arg(&args, "number=1,string=foo"));
213         RZ(fuse_opt_add_arg(&args, "bar"));
214
215         memset(&config, 0, sizeof(config));
216         ATF_CHECK(fuse_opt_parse(&args, &config, NULL, NULL) == 0);
217         ATF_CHECK_EQ(config.number, 0);
218         ATF_CHECK_EQ(config.string, NULL);
219         ATF_CHECK_EQ(config.nonopt, NULL);
220         ATF_CHECK_EQ(args.argc, 4);
221         ATF_CHECK_STREQ(args.argv[0], "foofs");
222         ATF_CHECK_STREQ(args.argv[1], "-o");
223         ATF_CHECK_STREQ(args.argv[2], "number=1,string=foo");
224         ATF_CHECK_STREQ(args.argv[3], "bar");
225 }
226
227 ATF_TC(t_fuse_opt_parse_null_proc);
228 ATF_TC_HEAD(t_fuse_opt_parse_null_proc, tc)
229 {
230         atf_tc_set_md_var(tc, "descr", "NULL proc means a processor function always returning 1,"
231                                           " i.e. keep the argument");
232 }
233
234 ATF_TC_BODY(t_fuse_opt_parse_null_proc, tc)
235 {
236         struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
237         struct foofs_config config;
238
239         RZ(fuse_opt_add_arg(&args, "foofs"));
240         RZ(fuse_opt_add_arg(&args, "-o"));
241         RZ(fuse_opt_add_arg(&args, "number=1,string=foo"));
242         RZ(fuse_opt_add_arg(&args, "bar"));
243
244         memset(&config, 0, sizeof(config));
245         ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, NULL) == 0);
246         ATF_CHECK_EQ(config.number, 1);
247         ATF_CHECK_STREQ(config.string, "foo");
248         ATF_CHECK_EQ(config.nonopt, NULL);
249         ATF_CHECK_EQ(args.argc, 2);
250         ATF_CHECK_STREQ(args.argv[0], "foofs");
251         ATF_CHECK_STREQ(args.argv[1], "bar");
252 }
253
254 ATF_TC(t_fuse_opt_parse);
255 ATF_TC_HEAD(t_fuse_opt_parse, tc)
256 {
257         atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_parse(3) fully works");
258 }
259
260 ATF_TC_BODY(t_fuse_opt_parse, tc)
261 {
262         struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
263         struct foofs_config config;
264
265     /* Standard form */
266         fuse_opt_free_args(&args);
267         RZ(fuse_opt_add_arg(&args, "foofs"));
268         RZ(fuse_opt_add_arg(&args, "-o"));
269         RZ(fuse_opt_add_arg(&args, "number=1,string=foo"));
270         RZ(fuse_opt_add_arg(&args, "bar"));
271
272         memset(&config, 0, sizeof(config));
273         ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
274         ATF_CHECK_EQ(config.number, 1);
275         ATF_CHECK_STREQ(config.string, "foo");
276         ATF_CHECK_STREQ(config.nonopt, "bar");
277         ATF_CHECK_EQ(args.argc, 1);
278         ATF_CHECK_STREQ(args.argv[0], "foofs");
279
280     /* Concatenated -o */
281         fuse_opt_free_args(&args);
282         RZ(fuse_opt_add_arg(&args, "foofs"));
283         RZ(fuse_opt_add_arg(&args, "-onumber=1,unknown,string=foo"));
284         RZ(fuse_opt_add_arg(&args, "bar"));
285
286         memset(&config, 0, sizeof(config));
287         ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
288         ATF_CHECK_EQ(config.number, 1);
289         ATF_CHECK_STREQ(config.string, "foo");
290         ATF_CHECK_STREQ(config.nonopt, "bar");
291         ATF_CHECK_EQ(args.argc, 3);
292         ATF_CHECK_STREQ(args.argv[0], "foofs");
293         ATF_CHECK_STREQ(args.argv[1], "-o");
294         ATF_CHECK_STREQ(args.argv[2], "unknown");
295
296         /* Sparse -o */
297         fuse_opt_free_args(&args);
298         RZ(fuse_opt_add_arg(&args, "foofs"));
299         RZ(fuse_opt_add_arg(&args, "bar"));
300         RZ(fuse_opt_add_arg(&args, "baz"));
301         RZ(fuse_opt_add_arg(&args, "-o"));
302         RZ(fuse_opt_add_arg(&args, "number=1"));
303         RZ(fuse_opt_add_arg(&args, "-o"));
304         RZ(fuse_opt_add_arg(&args, "unknown"));
305         RZ(fuse_opt_add_arg(&args, "-o"));
306         RZ(fuse_opt_add_arg(&args, "string=foo"));
307
308         memset(&config, 0, sizeof(config));
309         ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
310         ATF_CHECK_EQ(config.number, 1);
311         ATF_CHECK_STREQ(config.string, "foo");
312         ATF_CHECK_STREQ(config.nonopt, "bar");
313         ATF_CHECK_EQ(args.argc, 4);
314         ATF_CHECK_STREQ(args.argv[0], "foofs");
315         ATF_CHECK_STREQ(args.argv[1], "-o");
316         ATF_CHECK_STREQ(args.argv[2], "unknown");
317         ATF_CHECK_STREQ(args.argv[3], "baz");
318
319         /* Separate -n %i */
320         fuse_opt_free_args(&args);
321         RZ(fuse_opt_add_arg(&args, "foofs"));
322         RZ(fuse_opt_add_arg(&args, "-n"));
323         RZ(fuse_opt_add_arg(&args, "3"));
324
325         memset(&config, 0, sizeof(config));
326         ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
327         ATF_CHECK_EQ(config.number, 3);
328         ATF_CHECK_EQ(config.string, NULL);
329         ATF_CHECK_EQ(config.nonopt, NULL);
330         ATF_CHECK_EQ(args.argc, 1);
331         ATF_CHECK_STREQ(args.argv[0], "foofs");
332
333         /* Concatenated -n %i */
334         fuse_opt_free_args(&args);
335         RZ(fuse_opt_add_arg(&args, "foofs"));
336         RZ(fuse_opt_add_arg(&args, "-n3"));
337
338         memset(&config, 0, sizeof(config));
339         ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
340         ATF_CHECK_EQ(config.number, 3);
341         ATF_CHECK_EQ(config.string, NULL);
342         ATF_CHECK_EQ(config.nonopt, NULL);
343         ATF_CHECK_EQ(args.argc, 1);
344         ATF_CHECK_STREQ(args.argv[0], "foofs");
345
346         /* -o constant */
347         fuse_opt_free_args(&args);
348         RZ(fuse_opt_add_arg(&args, "foofs"));
349         RZ(fuse_opt_add_arg(&args, "-o"));
350         RZ(fuse_opt_add_arg(&args, "number2"));
351
352         memset(&config, 0, sizeof(config));
353         ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
354         ATF_CHECK_EQ(config.number, 2);
355         ATF_CHECK_EQ(config.string, NULL);
356         ATF_CHECK_EQ(config.nonopt, NULL);
357         ATF_CHECK_EQ(args.argc, 1);
358         ATF_CHECK_STREQ(args.argv[0], "foofs");
359
360         /* -x constant */
361         fuse_opt_free_args(&args);
362         RZ(fuse_opt_add_arg(&args, "foofs"));
363         RZ(fuse_opt_add_arg(&args, "--number=four"));
364
365         memset(&config, 0, sizeof(config));
366         ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
367         ATF_CHECK_EQ(config.number, 4);
368         ATF_CHECK_EQ(config.string, NULL);
369         ATF_CHECK_EQ(config.nonopt, NULL);
370         ATF_CHECK_EQ(args.argc, 1);
371         ATF_CHECK_STREQ(args.argv[0], "foofs");
372
373         /* end-of-options "--" marker */
374         fuse_opt_free_args(&args);
375         RZ(fuse_opt_add_arg(&args, "foofs"));
376     RZ(fuse_opt_add_arg(&args, "--"));
377         RZ(fuse_opt_add_arg(&args, "-onumber=1"));
378         RZ(fuse_opt_add_arg(&args, "-ostring=foo"));
379
380         memset(&config, 0, sizeof(config));
381         ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
382         ATF_CHECK_EQ(config.number, 0);
383         ATF_CHECK_EQ(config.string, NULL);
384         ATF_CHECK_STREQ(config.nonopt, "-onumber=1");
385         ATF_CHECK_EQ(args.argc, 3);
386         ATF_CHECK_STREQ(args.argv[0], "foofs");
387         ATF_CHECK_STREQ(args.argv[1], "--");
388         ATF_CHECK_STREQ(args.argv[2], "-ostring=foo");
389
390         /* The "--" marker at the last of outargs should be removed */
391         fuse_opt_free_args(&args);
392         RZ(fuse_opt_add_arg(&args, "foofs"));
393     RZ(fuse_opt_add_arg(&args, "--"));
394         RZ(fuse_opt_add_arg(&args, "-onumber=1"));
395
396         memset(&config, 0, sizeof(config));
397         ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
398         ATF_CHECK_EQ(config.number, 0);
399         ATF_CHECK_EQ(config.string, NULL);
400         ATF_CHECK_STREQ(config.nonopt, "-onumber=1");
401         ATF_CHECK_EQ(args.argc, 1);
402         ATF_CHECK_STREQ(args.argv[0], "foofs");
403 }
404
405 ATF_TP_ADD_TCS(tp)
406 {
407         ATF_TP_ADD_TC(tp, t_fuse_opt_add_arg);
408         ATF_TP_ADD_TC(tp, t_fuse_opt_insert_arg);
409         ATF_TP_ADD_TC(tp, t_fuse_opt_add_opt);
410         ATF_TP_ADD_TC(tp, t_fuse_opt_add_opt_escaped);
411         ATF_TP_ADD_TC(tp, t_fuse_opt_match);
412         ATF_TP_ADD_TC(tp, t_fuse_opt_parse_null_args);
413         ATF_TP_ADD_TC(tp, t_fuse_opt_parse_null_opts);
414         ATF_TP_ADD_TC(tp, t_fuse_opt_parse_null_proc);
415         ATF_TP_ADD_TC(tp, t_fuse_opt_parse);
416
417         return atf_no_error();
418 }