xref: /freebsd/sys/contrib/openzfs/tests/unit/test_namecheck.c (revision d0b3ecdc274930e190ea233b6b69ff03782eaf8d)
1*d0b3ecdcSMartin Matuska // SPDX-License-Identifier: CDDL-1.0
2*d0b3ecdcSMartin Matuska /*
3*d0b3ecdcSMartin Matuska  * This file and its contents are supplied under the terms of the
4*d0b3ecdcSMartin Matuska  * Common Development and Distribution License ("CDDL"), version 1.0.
5*d0b3ecdcSMartin Matuska  * You may only use this file in accordance with the terms of version
6*d0b3ecdcSMartin Matuska  * 1.0 of the CDDL.
7*d0b3ecdcSMartin Matuska  *
8*d0b3ecdcSMartin Matuska  * A full copy of the text of the CDDL should have accompanied this
9*d0b3ecdcSMartin Matuska  * source.  A copy of the CDDL is also available via the Internet at
10*d0b3ecdcSMartin Matuska  * http://www.illumos.org/license/CDDL.
11*d0b3ecdcSMartin Matuska  */
12*d0b3ecdcSMartin Matuska 
13*d0b3ecdcSMartin Matuska /*
14*d0b3ecdcSMartin Matuska  * Copyright (c) 2026, Christos Longros.
15*d0b3ecdcSMartin Matuska  */
16*d0b3ecdcSMartin Matuska 
17*d0b3ecdcSMartin Matuska #include <string.h>
18*d0b3ecdcSMartin Matuska 
19*d0b3ecdcSMartin Matuska #include <sys/fs/zfs.h>
20*d0b3ecdcSMartin Matuska #include "zfs_namecheck.h"
21*d0b3ecdcSMartin Matuska 
22*d0b3ecdcSMartin Matuska #include "unit.h"
23*d0b3ecdcSMartin Matuska 
24*d0b3ecdcSMartin Matuska /* ========== */
25*d0b3ecdcSMartin Matuska 
26*d0b3ecdcSMartin Matuska /*
27*d0b3ecdcSMartin Matuska  * The namecheck routines validate a name and report, via namecheck_err_t,
28*d0b3ecdcSMartin Matuska  * exactly why it failed.  We test them in two directions:
29*d0b3ecdcSMartin Matuska  *
30*d0b3ecdcSMartin Matuska  *   - Validity path: randomly generated names from unit_rand_str(), which
31*d0b3ecdcSMartin Matuska  *     give only 'a'-'z' characters.
32*d0b3ecdcSMartin Matuska  *
33*d0b3ecdcSMartin Matuska  *   - Invalidity path: explicit names, each tested against their specific
34*d0b3ecdcSMartin Matuska  *     error code since the rejection reason depends on the exact characters
35*d0b3ecdcSMartin Matuska  *     used.
36*d0b3ecdcSMartin Matuska  */
37*d0b3ecdcSMartin Matuska typedef int (*namecheck_f)(const char *, namecheck_err_t *, char *);
38*d0b3ecdcSMartin Matuska 
39*d0b3ecdcSMartin Matuska /* Confirm 'name' is accepted by 'fn'. */
40*d0b3ecdcSMartin Matuska static void
check_valid(namecheck_f fn,const char * name)41*d0b3ecdcSMartin Matuska check_valid(namecheck_f fn, const char *name)
42*d0b3ecdcSMartin Matuska {
43*d0b3ecdcSMartin Matuska 	namecheck_err_t why = (namecheck_err_t)-1;
44*d0b3ecdcSMartin Matuska 	char what = '\0';
45*d0b3ecdcSMartin Matuska 	unit_ok(fn(name, &why, &what));
46*d0b3ecdcSMartin Matuska }
47*d0b3ecdcSMartin Matuska 
48*d0b3ecdcSMartin Matuska /* Confirm 'name' is rejected by 'fn' with the 'why' we expected. */
49*d0b3ecdcSMartin Matuska static void
check_invalid(namecheck_f fn,const char * name,namecheck_err_t expected)50*d0b3ecdcSMartin Matuska check_invalid(namecheck_f fn, const char *name, namecheck_err_t expected)
51*d0b3ecdcSMartin Matuska {
52*d0b3ecdcSMartin Matuska 	namecheck_err_t why = (namecheck_err_t)-1;
53*d0b3ecdcSMartin Matuska 	char what = '\0';
54*d0b3ecdcSMartin Matuska 	unit_err(fn(name, &why, &what), -1);
55*d0b3ecdcSMartin Matuska 	unit_eq(why, expected);
56*d0b3ecdcSMartin Matuska }
57*d0b3ecdcSMartin Matuska 
58*d0b3ecdcSMartin Matuska /* Confirm 'fn' rejects a lengthy name and returns NAME_ERR_TOOLONG. */
59*d0b3ecdcSMartin Matuska static void
check_longname_invalid(namecheck_f fn)60*d0b3ecdcSMartin Matuska check_longname_invalid(namecheck_f fn)
61*d0b3ecdcSMartin Matuska {
62*d0b3ecdcSMartin Matuska 	char buf[ZFS_MAX_DATASET_NAME_LEN + 16];
63*d0b3ecdcSMartin Matuska 	check_invalid(fn, unit_rand_str(buf, sizeof (buf)), NAME_ERR_TOOLONG);
64*d0b3ecdcSMartin Matuska }
65*d0b3ecdcSMartin Matuska 
66*d0b3ecdcSMartin Matuska /* ========== */
67*d0b3ecdcSMartin Matuska 
68*d0b3ecdcSMartin Matuska /* pool_namecheck: dataset character set that must begin with a letter. */
69*d0b3ecdcSMartin Matuska static MunitResult
test_pool_namecheck(const MunitParameter params[],void * data)70*d0b3ecdcSMartin Matuska test_pool_namecheck(const MunitParameter params[], void *data)
71*d0b3ecdcSMartin Matuska {
72*d0b3ecdcSMartin Matuska 	(void) params, (void) data;
73*d0b3ecdcSMartin Matuska 
74*d0b3ecdcSMartin Matuska 	/* A random array of letters is always a valid pool name. */
75*d0b3ecdcSMartin Matuska 	char pool[16];
76*d0b3ecdcSMartin Matuska 	check_valid(pool_namecheck, unit_rand_str(pool, sizeof (pool)));
77*d0b3ecdcSMartin Matuska 
78*d0b3ecdcSMartin Matuska 	/* Fixed names cover the rest of the allowed character set. */
79*d0b3ecdcSMartin Matuska 	check_valid(pool_namecheck, "tank_01");
80*d0b3ecdcSMartin Matuska 	check_valid(pool_namecheck, "Pool-2.0:label");
81*d0b3ecdcSMartin Matuska 
82*d0b3ecdcSMartin Matuska 	/* A pool name has to start with a letter. */
83*d0b3ecdcSMartin Matuska 	check_invalid(pool_namecheck, "0tank", NAME_ERR_NOLETTER);
84*d0b3ecdcSMartin Matuska 	check_invalid(pool_namecheck, "_tank", NAME_ERR_NOLETTER);
85*d0b3ecdcSMartin Matuska 
86*d0b3ecdcSMartin Matuska 	/* These pool names are reserved. */
87*d0b3ecdcSMartin Matuska 	check_invalid(pool_namecheck, "mirror", NAME_ERR_RESERVED);
88*d0b3ecdcSMartin Matuska 	check_invalid(pool_namecheck, "raidz", NAME_ERR_RESERVED);
89*d0b3ecdcSMartin Matuska 	check_invalid(pool_namecheck, "draid", NAME_ERR_RESERVED);
90*d0b3ecdcSMartin Matuska 
91*d0b3ecdcSMartin Matuska 	/* A pool name carries no hierarchy or snapshot delimiter. */
92*d0b3ecdcSMartin Matuska 	check_invalid(pool_namecheck, "tank/fs", NAME_ERR_INVALCHAR);
93*d0b3ecdcSMartin Matuska 	check_invalid(pool_namecheck, "tank@snap", NAME_ERR_INVALCHAR);
94*d0b3ecdcSMartin Matuska 
95*d0b3ecdcSMartin Matuska 	check_longname_invalid(pool_namecheck);
96*d0b3ecdcSMartin Matuska 
97*d0b3ecdcSMartin Matuska 	return (MUNIT_OK);
98*d0b3ecdcSMartin Matuska }
99*d0b3ecdcSMartin Matuska 
100*d0b3ecdcSMartin Matuska /* dataset_namecheck: any entity except a bookmark. */
101*d0b3ecdcSMartin Matuska static MunitResult
test_dataset_namecheck(const MunitParameter params[],void * data)102*d0b3ecdcSMartin Matuska test_dataset_namecheck(const MunitParameter params[], void *data)
103*d0b3ecdcSMartin Matuska {
104*d0b3ecdcSMartin Matuska 	(void) params, (void) data;
105*d0b3ecdcSMartin Matuska 
106*d0b3ecdcSMartin Matuska 	/* A path of random, independently-valid components is accepted. */
107*d0b3ecdcSMartin Matuska 	char path[64];
108*d0b3ecdcSMartin Matuska 	unit_rand_str(path, sizeof (path));
109*d0b3ecdcSMartin Matuska 	path[20] = path[40] = '/';
110*d0b3ecdcSMartin Matuska 	check_valid(dataset_namecheck, path);
111*d0b3ecdcSMartin Matuska 
112*d0b3ecdcSMartin Matuska 	/* A trailing snapshot is still a valid dataset name. */
113*d0b3ecdcSMartin Matuska 	check_valid(dataset_namecheck, "tank/home@snap");
114*d0b3ecdcSMartin Matuska 
115*d0b3ecdcSMartin Matuska 	/* '%' is allowed, for temporary clone names (online recv). */
116*d0b3ecdcSMartin Matuska 	check_valid(dataset_namecheck, "tank/%recv");
117*d0b3ecdcSMartin Matuska 
118*d0b3ecdcSMartin Matuska 	check_invalid(dataset_namecheck, "/tank", NAME_ERR_LEADING_SLASH);
119*d0b3ecdcSMartin Matuska 	check_invalid(dataset_namecheck, "tank/", NAME_ERR_TRAILING_SLASH);
120*d0b3ecdcSMartin Matuska 	check_invalid(dataset_namecheck, "tank//home",
121*d0b3ecdcSMartin Matuska 	    NAME_ERR_EMPTY_COMPONENT);
122*d0b3ecdcSMartin Matuska 	check_invalid(dataset_namecheck, "", NAME_ERR_EMPTY_COMPONENT);
123*d0b3ecdcSMartin Matuska 	check_invalid(dataset_namecheck, "tank/./home", NAME_ERR_SELF_REF);
124*d0b3ecdcSMartin Matuska 	check_invalid(dataset_namecheck, "tank/../home", NAME_ERR_PARENT_REF);
125*d0b3ecdcSMartin Matuska 	check_invalid(dataset_namecheck, "tank/fs!", NAME_ERR_INVALCHAR);
126*d0b3ecdcSMartin Matuska 
127*d0b3ecdcSMartin Matuska 	/* A bookmark delimiter does not belong in a dataset name. */
128*d0b3ecdcSMartin Matuska 	check_invalid(dataset_namecheck, "tank/fs#bm", NAME_ERR_INVALCHAR);
129*d0b3ecdcSMartin Matuska 
130*d0b3ecdcSMartin Matuska 	check_longname_invalid(dataset_namecheck);
131*d0b3ecdcSMartin Matuska 
132*d0b3ecdcSMartin Matuska 	return (MUNIT_OK);
133*d0b3ecdcSMartin Matuska }
134*d0b3ecdcSMartin Matuska 
135*d0b3ecdcSMartin Matuska /* snapshot_namecheck: a valid snapshot name (an entity with '@'). */
136*d0b3ecdcSMartin Matuska static MunitResult
test_snapshot_namecheck(const MunitParameter params[],void * data)137*d0b3ecdcSMartin Matuska test_snapshot_namecheck(const MunitParameter params[], void *data)
138*d0b3ecdcSMartin Matuska {
139*d0b3ecdcSMartin Matuska 	(void) params, (void) data;
140*d0b3ecdcSMartin Matuska 
141*d0b3ecdcSMartin Matuska 	/* A random "filesystem@snapshot" pair is valid. */
142*d0b3ecdcSMartin Matuska 	char path[64];
143*d0b3ecdcSMartin Matuska 	unit_rand_str(path, sizeof (path));
144*d0b3ecdcSMartin Matuska 	path[40] = '@';
145*d0b3ecdcSMartin Matuska 	check_valid(snapshot_namecheck, path);
146*d0b3ecdcSMartin Matuska 
147*d0b3ecdcSMartin Matuska 	/* Without an '@' it is not a snapshot. */
148*d0b3ecdcSMartin Matuska 	check_invalid(snapshot_namecheck, "tank/home", NAME_ERR_NO_AT);
149*d0b3ecdcSMartin Matuska 
150*d0b3ecdcSMartin Matuska 	/* Only one delimiter is allowed. */
151*d0b3ecdcSMartin Matuska 	check_invalid(snapshot_namecheck, "tank@a@b",
152*d0b3ecdcSMartin Matuska 	    NAME_ERR_MULTIPLE_DELIMITERS);
153*d0b3ecdcSMartin Matuska 
154*d0b3ecdcSMartin Matuska 	/* Nothing may follow the snapshot name with a '/'. */
155*d0b3ecdcSMartin Matuska 	check_invalid(snapshot_namecheck, "tank@snap/x",
156*d0b3ecdcSMartin Matuska 	    NAME_ERR_TRAILING_SLASH);
157*d0b3ecdcSMartin Matuska 
158*d0b3ecdcSMartin Matuska 	return (MUNIT_OK);
159*d0b3ecdcSMartin Matuska }
160*d0b3ecdcSMartin Matuska 
161*d0b3ecdcSMartin Matuska /* bookmark_namecheck: a valid bookmark name (an entity with '#'). */
162*d0b3ecdcSMartin Matuska static MunitResult
test_bookmark_namecheck(const MunitParameter params[],void * data)163*d0b3ecdcSMartin Matuska test_bookmark_namecheck(const MunitParameter params[], void *data)
164*d0b3ecdcSMartin Matuska {
165*d0b3ecdcSMartin Matuska 	(void) params, (void) data;
166*d0b3ecdcSMartin Matuska 
167*d0b3ecdcSMartin Matuska 	/* A random "filesystem#bookmark" pair is valid. */
168*d0b3ecdcSMartin Matuska 	char path[64];
169*d0b3ecdcSMartin Matuska 	unit_rand_str(path, sizeof (path));
170*d0b3ecdcSMartin Matuska 	path[40] = '#';
171*d0b3ecdcSMartin Matuska 	check_valid(bookmark_namecheck, path);
172*d0b3ecdcSMartin Matuska 
173*d0b3ecdcSMartin Matuska 	/* Without a '#' it is not a bookmark. */
174*d0b3ecdcSMartin Matuska 	check_invalid(bookmark_namecheck, "tank/home", NAME_ERR_NO_POUND);
175*d0b3ecdcSMartin Matuska 
176*d0b3ecdcSMartin Matuska 	return (MUNIT_OK);
177*d0b3ecdcSMartin Matuska }
178*d0b3ecdcSMartin Matuska 
179*d0b3ecdcSMartin Matuska /* zfs_component_namecheck: one component; alphanumeric plus [-_.: ]. */
180*d0b3ecdcSMartin Matuska static MunitResult
test_component_namecheck(const MunitParameter params[],void * data)181*d0b3ecdcSMartin Matuska test_component_namecheck(const MunitParameter params[], void *data)
182*d0b3ecdcSMartin Matuska {
183*d0b3ecdcSMartin Matuska 	(void) params, (void) data;
184*d0b3ecdcSMartin Matuska 
185*d0b3ecdcSMartin Matuska 	/* A bare random component is valid. */
186*d0b3ecdcSMartin Matuska 	char comp[16];
187*d0b3ecdcSMartin Matuska 	unit_rand_str(comp, sizeof (comp));
188*d0b3ecdcSMartin Matuska 	check_valid(zfs_component_namecheck, comp);
189*d0b3ecdcSMartin Matuska 
190*d0b3ecdcSMartin Matuska 	/* An empty component is not valid. */
191*d0b3ecdcSMartin Matuska 	check_invalid(zfs_component_namecheck, "", NAME_ERR_EMPTY_COMPONENT);
192*d0b3ecdcSMartin Matuska 
193*d0b3ecdcSMartin Matuska 	/* A single component cannot contain a path separator. */
194*d0b3ecdcSMartin Matuska 	check_invalid(zfs_component_namecheck, "a/b", NAME_ERR_INVALCHAR);
195*d0b3ecdcSMartin Matuska 
196*d0b3ecdcSMartin Matuska 	check_longname_invalid(zfs_component_namecheck);
197*d0b3ecdcSMartin Matuska 
198*d0b3ecdcSMartin Matuska 	return (MUNIT_OK);
199*d0b3ecdcSMartin Matuska }
200*d0b3ecdcSMartin Matuska 
201*d0b3ecdcSMartin Matuska /* permset_namecheck: a permission set name, starting with '@'. */
202*d0b3ecdcSMartin Matuska static MunitResult
test_permset_namecheck(const MunitParameter params[],void * data)203*d0b3ecdcSMartin Matuska test_permset_namecheck(const MunitParameter params[], void *data)
204*d0b3ecdcSMartin Matuska {
205*d0b3ecdcSMartin Matuska 	(void) params, (void) data;
206*d0b3ecdcSMartin Matuska 
207*d0b3ecdcSMartin Matuska 	/* A random name behind a leading '@' is a valid permission set. */
208*d0b3ecdcSMartin Matuska 	char set[16];
209*d0b3ecdcSMartin Matuska 	set[0] = '@';
210*d0b3ecdcSMartin Matuska 	unit_rand_str(set + 1, sizeof (set) - 1);
211*d0b3ecdcSMartin Matuska 	check_valid(permset_namecheck, set);
212*d0b3ecdcSMartin Matuska 
213*d0b3ecdcSMartin Matuska 	/* It has to start with '@'. */
214*d0b3ecdcSMartin Matuska 	check_invalid(permset_namecheck, "backup", NAME_ERR_NO_AT);
215*d0b3ecdcSMartin Matuska 
216*d0b3ecdcSMartin Matuska 	/* The text after '@' follows the component rules. */
217*d0b3ecdcSMartin Matuska 	check_invalid(permset_namecheck, "@bad/name", NAME_ERR_INVALCHAR);
218*d0b3ecdcSMartin Matuska 
219*d0b3ecdcSMartin Matuska 	/* The length upper limit is checked ahead of everything else. */
220*d0b3ecdcSMartin Matuska 	check_longname_invalid(permset_namecheck);
221*d0b3ecdcSMartin Matuska 
222*d0b3ecdcSMartin Matuska 	return (MUNIT_OK);
223*d0b3ecdcSMartin Matuska }
224*d0b3ecdcSMartin Matuska 
225*d0b3ecdcSMartin Matuska /* mountpoint_namecheck: a mountpoint path, /[component][/]*. */
226*d0b3ecdcSMartin Matuska static MunitResult
test_mountpoint_namecheck(const MunitParameter params[],void * data)227*d0b3ecdcSMartin Matuska test_mountpoint_namecheck(const MunitParameter params[], void *data)
228*d0b3ecdcSMartin Matuska {
229*d0b3ecdcSMartin Matuska 	(void) params, (void) data;
230*d0b3ecdcSMartin Matuska 
231*d0b3ecdcSMartin Matuska 	namecheck_err_t why = (namecheck_err_t)-1;
232*d0b3ecdcSMartin Matuska 
233*d0b3ecdcSMartin Matuska 	/* An absolute path with a random component is accepted. */
234*d0b3ecdcSMartin Matuska 	char path[64];
235*d0b3ecdcSMartin Matuska 	unit_rand_str(path, sizeof (path));
236*d0b3ecdcSMartin Matuska 	path[0] = '/';
237*d0b3ecdcSMartin Matuska 	unit_ok(mountpoint_namecheck(path, &why));
238*d0b3ecdcSMartin Matuska 
239*d0b3ecdcSMartin Matuska 	/* The root mountpoint is valid. */
240*d0b3ecdcSMartin Matuska 	unit_ok(mountpoint_namecheck("/", &why));
241*d0b3ecdcSMartin Matuska 
242*d0b3ecdcSMartin Matuska 	/* A mountpoint must be absolute. */
243*d0b3ecdcSMartin Matuska 	unit_err(mountpoint_namecheck("relative/path", &why), -1);
244*d0b3ecdcSMartin Matuska 	unit_eq(why, NAME_ERR_LEADING_SLASH);
245*d0b3ecdcSMartin Matuska 
246*d0b3ecdcSMartin Matuska 	/* A NULL path counts as missing the leading slash. */
247*d0b3ecdcSMartin Matuska 	unit_err(mountpoint_namecheck(NULL, &why), -1);
248*d0b3ecdcSMartin Matuska 	unit_eq(why, NAME_ERR_LEADING_SLASH);
249*d0b3ecdcSMartin Matuska 
250*d0b3ecdcSMartin Matuska 	/* A long path component is rejected. */
251*d0b3ecdcSMartin Matuska 	char buf[ZFS_MAX_DATASET_NAME_LEN + 4];
252*d0b3ecdcSMartin Matuska 	buf[0] = '/';
253*d0b3ecdcSMartin Matuska 	(void) memset(buf + 1, 'a', sizeof (buf) - 2);
254*d0b3ecdcSMartin Matuska 	buf[sizeof (buf) - 1] = '\0';
255*d0b3ecdcSMartin Matuska 	unit_err(mountpoint_namecheck(buf, &why), -1);
256*d0b3ecdcSMartin Matuska 	unit_eq(why, NAME_ERR_TOOLONG);
257*d0b3ecdcSMartin Matuska 
258*d0b3ecdcSMartin Matuska 	return (MUNIT_OK);
259*d0b3ecdcSMartin Matuska }
260*d0b3ecdcSMartin Matuska 
261*d0b3ecdcSMartin Matuska /* get_dataset_depth: a path's level of nesting (depth). */
262*d0b3ecdcSMartin Matuska static MunitResult
test_dataset_depth(const MunitParameter params[],void * data)263*d0b3ecdcSMartin Matuska test_dataset_depth(const MunitParameter params[], void *data)
264*d0b3ecdcSMartin Matuska {
265*d0b3ecdcSMartin Matuska 	(void) params, (void) data;
266*d0b3ecdcSMartin Matuska 
267*d0b3ecdcSMartin Matuska 	/* Depth is the number of '/' separators in the path. */
268*d0b3ecdcSMartin Matuska 	unit_eq(get_dataset_depth("tank"), 0);
269*d0b3ecdcSMartin Matuska 	unit_eq(get_dataset_depth("tank/home"), 1);
270*d0b3ecdcSMartin Matuska 	unit_eq(get_dataset_depth("tank/home/user"), 2);
271*d0b3ecdcSMartin Matuska 
272*d0b3ecdcSMartin Matuska 	/* Counting stops at the snapshot or bookmark delimiter. */
273*d0b3ecdcSMartin Matuska 	unit_eq(get_dataset_depth("tank/home@snap"), 1);
274*d0b3ecdcSMartin Matuska 	unit_eq(get_dataset_depth("tank/home#bm"), 1);
275*d0b3ecdcSMartin Matuska 
276*d0b3ecdcSMartin Matuska 	/*
277*d0b3ecdcSMartin Matuska 	 * dataset_nestcheck() passes while the depth is under the limit and
278*d0b3ecdcSMartin Matuska 	 * fails once it reaches it.  zfs_max_dataset_nesting is a tunable that
279*d0b3ecdcSMartin Matuska 	 * can be adjusted to the desired nesting.
280*d0b3ecdcSMartin Matuska 	 */
281*d0b3ecdcSMartin Matuska 	zfs_max_dataset_nesting = 2;
282*d0b3ecdcSMartin Matuska 	unit_ok(dataset_nestcheck("a/b"));		/* depth 1, under 2 */
283*d0b3ecdcSMartin Matuska 	unit_err(dataset_nestcheck("a/b/c"), -1);	/* depth 2, at 2   */
284*d0b3ecdcSMartin Matuska 
285*d0b3ecdcSMartin Matuska 	return (MUNIT_OK);
286*d0b3ecdcSMartin Matuska }
287*d0b3ecdcSMartin Matuska 
288*d0b3ecdcSMartin Matuska /* ========== */
289*d0b3ecdcSMartin Matuska 
290*d0b3ecdcSMartin Matuska static const MunitTest namecheck_tests[] = {
291*d0b3ecdcSMartin Matuska 	UNIT_TEST("pool",	test_pool_namecheck),
292*d0b3ecdcSMartin Matuska 	UNIT_TEST("dataset",	test_dataset_namecheck),
293*d0b3ecdcSMartin Matuska 	UNIT_TEST("snapshot",	test_snapshot_namecheck),
294*d0b3ecdcSMartin Matuska 	UNIT_TEST("bookmark",	test_bookmark_namecheck),
295*d0b3ecdcSMartin Matuska 	UNIT_TEST("component",	test_component_namecheck),
296*d0b3ecdcSMartin Matuska 	UNIT_TEST("permset",	test_permset_namecheck),
297*d0b3ecdcSMartin Matuska 	UNIT_TEST("mountpoint",	test_mountpoint_namecheck),
298*d0b3ecdcSMartin Matuska 	UNIT_TEST("depth",	test_dataset_depth),
299*d0b3ecdcSMartin Matuska 	{ 0 },
300*d0b3ecdcSMartin Matuska };
301*d0b3ecdcSMartin Matuska 
302*d0b3ecdcSMartin Matuska static const MunitSuite namecheck_test_suite = {
303*d0b3ecdcSMartin Matuska 	"namecheck.",
304*d0b3ecdcSMartin Matuska 	namecheck_tests,
305*d0b3ecdcSMartin Matuska 	NULL,
306*d0b3ecdcSMartin Matuska 	1,
307*d0b3ecdcSMartin Matuska 	MUNIT_SUITE_OPTION_NONE,
308*d0b3ecdcSMartin Matuska };
309*d0b3ecdcSMartin Matuska 
310*d0b3ecdcSMartin Matuska int
main(int argc,char ** argv)311*d0b3ecdcSMartin Matuska main(int argc, char **argv)
312*d0b3ecdcSMartin Matuska {
313*d0b3ecdcSMartin Matuska 	return (munit_suite_main(&namecheck_test_suite, NULL, argc, argv));
314*d0b3ecdcSMartin Matuska }
315