4 * This file and its contents are supplied under the terms of the
5 * Common Development and Distribution License ("CDDL"), version 1.0.
6 * You may only use this file in accordance with the terms of version
9 * A full copy of the text of the CDDL should have accompanied this
10 * source. A copy of the CDDL is also available via the Internet at
11 * http://www.illumos.org/license/CDDL.
17 * Copyright (c) 2016 by Delphix. All rights reserved.
23 #include <libzfs_core.h>
24 #include <sys/nvpair.h>
27 static const char *pool
;
28 static boolean_t unexpected_failures
;
31 nvlist_equal(nvlist_t
*nvla
, nvlist_t
*nvlb
)
33 if (fnvlist_num_pairs(nvla
) != fnvlist_num_pairs(nvlb
))
36 * The nvlists have the same number of pairs and keys are unique, so
37 * if every key in A is also in B and assigned to the same value, the
38 * lists are identical.
40 for (nvpair_t
*pair
= nvlist_next_nvpair(nvla
, NULL
);
41 pair
!= NULL
; pair
= nvlist_next_nvpair(nvla
, pair
)) {
42 const char *key
= nvpair_name(pair
);
44 if (!nvlist_exists(nvlb
, key
))
47 if (nvpair_type(pair
) !=
48 nvpair_type(fnvlist_lookup_nvpair(nvlb
, key
)))
51 switch (nvpair_type(pair
)) {
52 case DATA_TYPE_BOOLEAN_VALUE
:
53 if (fnvpair_value_boolean_value(pair
) !=
54 fnvlist_lookup_boolean_value(nvlb
, key
)) {
58 case DATA_TYPE_STRING
:
59 if (strcmp(fnvpair_value_string(pair
),
60 fnvlist_lookup_string(nvlb
, key
))) {
65 if (fnvpair_value_int64(pair
) !=
66 fnvlist_lookup_int64(nvlb
, key
)) {
70 case DATA_TYPE_NVLIST
:
71 if (!nvlist_equal(fnvpair_value_nvlist(pair
),
72 fnvlist_lookup_nvlist(nvlb
, key
))) {
77 (void) printf("Unexpected type for nvlist_equal\n");
85 test(const char *testname
, boolean_t expect_success
, boolean_t expect_match
)
87 const char *progstr
= "input = ...; return {output=input}";
91 (void) printf("\nrunning test '%s'; input:\n", testname
);
94 int err
= lzc_channel_program(pool
, progstr
,
95 10 * 1000 * 1000, 10 * 1024 * 1024, nvl
, &outnvl
);
97 (void) printf("lzc_channel_program returned %u\n", err
);
98 dump_nvlist(outnvl
, 5);
100 if (err
== 0 && expect_match
) {
102 * Verify that outnvl is the same as input nvl, if we expect
103 * them to be. The input and output will never match if the
104 * input contains an array (since arrays are converted to lua
105 * tables), so this is only asserted for some test cases.
107 nvlist_t
*real_outnvl
= fnvlist_lookup_nvlist(outnvl
, "return");
108 real_outnvl
= fnvlist_lookup_nvlist(real_outnvl
, "output");
109 if (!nvlist_equal(nvl
, real_outnvl
)) {
110 unexpected_failures
= B_TRUE
;
111 (void) printf("unexpected input/output mismatch for "
112 "case: %s\n", testname
);
115 if (err
!= 0 && expect_success
) {
116 unexpected_failures
= B_TRUE
;
117 (void) printf("unexpected FAIL of case: %s\n", testname
);
121 nvl
= fnvlist_alloc();
127 const char *key
= "key";
129 /* Note: maximum nvlist key length is 32KB */
131 char *bigstring
= malloc(len
);
132 if (bigstring
== NULL
) {
137 for (int i
= 0; i
< len
; i
++)
138 bigstring
[i
] = 'a' + i
% 26;
139 bigstring
[len
- 1] = '\0';
141 nvl
= fnvlist_alloc();
143 fnvlist_add_boolean(nvl
, key
);
144 test("boolean", B_TRUE
, B_FALSE
);
146 fnvlist_add_boolean_value(nvl
, key
, B_TRUE
);
147 test("boolean_value", B_FALSE
, B_FALSE
);
149 fnvlist_add_byte(nvl
, key
, 1);
150 test("byte", B_FALSE
, B_FALSE
);
152 fnvlist_add_int8(nvl
, key
, 1);
153 test("int8", B_FALSE
, B_FALSE
);
155 fnvlist_add_uint8(nvl
, key
, 1);
156 test("uint8", B_FALSE
, B_FALSE
);
158 fnvlist_add_int16(nvl
, key
, 1);
159 test("int16", B_FALSE
, B_FALSE
);
161 fnvlist_add_uint16(nvl
, key
, 1);
162 test("uint16", B_FALSE
, B_FALSE
);
164 fnvlist_add_int32(nvl
, key
, 1);
165 test("int32", B_FALSE
, B_FALSE
);
167 fnvlist_add_uint32(nvl
, key
, 1);
168 test("uint32", B_FALSE
, B_FALSE
);
170 fnvlist_add_int64(nvl
, key
, 1);
171 test("int64", B_TRUE
, B_TRUE
);
173 fnvlist_add_uint64(nvl
, key
, 1);
174 test("uint64", B_FALSE
, B_FALSE
);
176 fnvlist_add_string(nvl
, key
, "1");
177 test("string", B_TRUE
, B_TRUE
);
181 nvlist_t
*val
= fnvlist_alloc();
182 fnvlist_add_string(val
, "subkey", "subvalue");
183 fnvlist_add_nvlist(nvl
, key
, val
);
185 test("nvlist", B_TRUE
, B_TRUE
);
188 boolean_t val
[2] = { B_FALSE
, B_TRUE
};
189 fnvlist_add_boolean_array(nvl
, key
, val
, 2);
190 test("boolean_array", B_FALSE
, B_FALSE
);
193 uchar_t val
[2] = { 0, 1 };
194 fnvlist_add_byte_array(nvl
, key
, val
, 2);
195 test("byte_array", B_FALSE
, B_FALSE
);
198 int8_t val
[2] = { 0, 1 };
199 fnvlist_add_int8_array(nvl
, key
, val
, 2);
200 test("int8_array", B_FALSE
, B_FALSE
);
203 uint8_t val
[2] = { 0, 1 };
204 fnvlist_add_uint8_array(nvl
, key
, val
, 2);
205 test("uint8_array", B_FALSE
, B_FALSE
);
208 int16_t val
[2] = { 0, 1 };
209 fnvlist_add_int16_array(nvl
, key
, val
, 2);
210 test("int16_array", B_FALSE
, B_FALSE
);
213 uint16_t val
[2] = { 0, 1 };
214 fnvlist_add_uint16_array(nvl
, key
, val
, 2);
215 test("uint16_array", B_FALSE
, B_FALSE
);
218 int32_t val
[2] = { 0, 1 };
219 fnvlist_add_int32_array(nvl
, key
, val
, 2);
220 test("int32_array", B_FALSE
, B_FALSE
);
223 uint32_t val
[2] = { 0, 1 };
224 fnvlist_add_uint32_array(nvl
, key
, val
, 2);
225 test("uint32_array", B_FALSE
, B_FALSE
);
228 int64_t val
[2] = { 0, 1 };
229 fnvlist_add_int64_array(nvl
, key
, val
, 2);
230 test("int64_array", B_TRUE
, B_FALSE
);
233 uint64_t val
[2] = { 0, 1 };
234 fnvlist_add_uint64_array(nvl
, key
, val
, 2);
235 test("uint64_array", B_FALSE
, B_FALSE
);
238 const char *val
[2] = { "0", "1" };
239 fnvlist_add_string_array(nvl
, key
, val
, 2);
240 test("string_array", B_TRUE
, B_FALSE
);
244 val
[0] = fnvlist_alloc();
245 fnvlist_add_string(val
[0], "subkey", "subvalue");
246 val
[1] = fnvlist_alloc();
247 fnvlist_add_string(val
[1], "subkey2", "subvalue2");
248 fnvlist_add_nvlist_array(nvl
, key
, (const nvlist_t
**)val
, 2);
249 fnvlist_free(val
[0]);
250 fnvlist_free(val
[1]);
251 test("nvlist_array", B_FALSE
, B_FALSE
);
254 fnvlist_add_string(nvl
, bigstring
, "1");
255 test("large_key", B_TRUE
, B_TRUE
);
258 fnvlist_add_string(nvl
, key
, bigstring
);
259 test("large_value", B_TRUE
, B_TRUE
);
262 for (int i
= 0; i
< 1024; i
++) {
264 (void) snprintf(buf
, sizeof (buf
), "key-%u", i
);
265 fnvlist_add_int64(nvl
, buf
, i
);
267 test("many_keys", B_TRUE
, B_TRUE
);
271 for (int i
= 0; i
< 10; i
++) {
272 nvlist_t
*newval
= fnvlist_alloc();
273 fnvlist_add_nvlist(newval
, "key", nvl
);
277 test("deeply_nested_pos", B_TRUE
, B_TRUE
);
280 for (int i
= 0; i
< 90; i
++) {
281 nvlist_t
*newval
= fnvlist_alloc();
282 fnvlist_add_nvlist(newval
, "key", nvl
);
286 test("deeply_nested_neg", B_FALSE
, B_FALSE
);
294 main(int argc
, const char *argv
[])
296 (void) libzfs_core_init();
299 (void) printf("usage: %s <pool>\n",
308 return (unexpected_failures
);