2 * Copyright (C) 2018-2019 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 static bool error_flagged
;
48 /* Stubs for linking against minimal source files, and for proving that
49 * an error message is issued when expected. */
51 nbdkit_error (const char *fs
, ...)
60 threadlocal_get_conn (void)
65 int connection_get_status (struct connection
*conn
)
71 test_nbdkit_parse_size (void)
86 /* Strings leading to overflow */
87 { "9223372036854775808", -1 }, /* INT_MAX + 1 */
88 { "18446744073709551614", -1 }, /* UINT64_MAX - 1 */
89 { "18446744073709551615", -1 }, /* UINT64_MAX */
90 { "18446744073709551616", -1 }, /* UINT64_MAX + 1 */
91 { "999999999999999999999999", -1 },
93 /* Strings representing negative values */
96 { "-9223372036854775809", -1 }, /* INT64_MIN - 1 */
97 { "-9223372036854775808", -1 }, /* INT64_MIN */
98 { "-9223372036854775807", -1 }, /* INT64_MIN + 1 */
99 { "-18446744073709551616", -1 }, /* -UINT64_MAX - 1 */
100 { "-18446744073709551615", -1 }, /* -UINT64_MAX */
101 { "-18446744073709551614", -1 }, /* -UINT64_MAX + 1 */
103 /* Strings we may want to support in the future */
116 { "1234567890", 1234567890 },
117 { "+1234567890", 1234567890 },
118 { "9223372036854775807", INT64_MAX
},
125 { "1m", 1024 * 1024 },
126 { "1M", 1024 * 1024 },
127 { "+1M", 1024 * 1024 },
128 { "1g", 1024 * 1024 * 1024 },
129 { "1G", 1024 * 1024 * 1024 },
130 { "1t", 1024LL * 1024 * 1024 * 1024 },
131 { "1T", 1024LL * 1024 * 1024 * 1024 },
132 { "1p", 1024LL * 1024 * 1024 * 1024 * 1024 },
133 { "1P", 1024LL * 1024 * 1024 * 1024 * 1024 },
134 { "8191p", 1024LL * 1024 * 1024 * 1024 * 1024 * 8191 },
135 { "1e", 1024LL * 1024 * 1024 * 1024 * 1024 * 1024 },
136 { "1E", 1024LL * 1024 * 1024 * 1024 * 1024 * 1024 },
139 for (size_t i
= 0; i
< sizeof pairs
/ sizeof pairs
[0]; i
++) {
142 error_flagged
= false;
143 r
= nbdkit_parse_size (pairs
[i
].str
);
144 if (r
!= pairs
[i
].res
) {
146 "Wrong parse for %s, got %" PRId64
", expected %" PRId64
"\n",
147 pairs
[i
].str
, r
, pairs
[i
].res
);
150 if ((r
== -1) != error_flagged
) {
151 fprintf (stderr
, "Wrong error message handling for %s\n", pairs
[i
].str
);
160 test_nbdkit_parse_ints (void)
164 #define PARSE(...) PARSE_(__VA_ARGS__)
165 #define PARSE_(TYPE, FORMAT, TEST, RET, EXPECTED) \
167 error_flagged = false; \
169 int r = nbdkit_parse_##TYPE ("test", TEST, &i); \
170 if (r != RET || i != (r ? 123 : EXPECTED)) { \
172 "%s: %d: wrong parse for %s: r=%d i=" FORMAT "\n", \
173 __FILE__, __LINE__, TEST, r, i); \
176 if ((r == -1) != error_flagged) { \
178 "%s: %d: wrong error message handling for %s\n", \
179 __FILE__, __LINE__, TEST); \
186 /* Test the basic parsing of decimals, hexadecimal, octal and
189 PARSE (int, "%d", "0", OK
, 0);
190 PARSE (int, "%d", " 0", OK
, 0);
191 PARSE (int, "%d", " 0", OK
, 0);
192 PARSE (int, "%d", " 0", OK
, 0);
193 PARSE (int, "%d", "1", OK
, 1);
194 PARSE (int, "%d", " 1", OK
, 1);
195 PARSE (int, "%d", " 1", OK
, 1);
196 PARSE (int, "%d", " 1", OK
, 1);
197 PARSE (int, "%d", "99", OK
, 99);
198 PARSE (int, "%d", "0x1", OK
, 1);
199 PARSE (int, "%d", "0xf", OK
, 15);
200 PARSE (int, "%d", "0x10", OK
, 16);
201 PARSE (int, "%d", "0xff", OK
, 255);
202 PARSE (int, "%d", "0Xff", OK
, 255);
203 PARSE (int, "%d", "01", OK
, 1);
204 PARSE (int, "%d", "07", OK
, 7);
205 PARSE (int, "%d", "010", OK
, 8);
206 PARSE (int, "%d", "+0", OK
, 0);
207 PARSE (int, "%d", " +0", OK
, 0);
208 PARSE (int, "%d", "+99", OK
, 99);
209 PARSE (int, "%d", "+0xf", OK
, 15);
210 PARSE (int, "%d", "+010", OK
, 8);
211 PARSE (int, "%d", "-0", OK
, 0);
212 PARSE (int, "%d", " -0", OK
, 0);
213 PARSE (int, "%d", " -0", OK
, 0);
214 PARSE (int, "%d", "-99", OK
, -99);
215 PARSE (int, "%d", "-0xf", OK
, -15);
216 PARSE (int, "%d", "-0XF", OK
, -15);
217 PARSE (int, "%d", "-010", OK
, -8);
218 PARSE (int, "%d", "2147483647", OK
, 2147483647); /* INT_MAX */
219 PARSE (int, "%d", "-2147483648", OK
, -2147483648); /* INT_MIN */
220 PARSE (int, "%d", "0x7fffffff", OK
, 0x7fffffff);
221 PARSE (int, "%d", "-0x80000000", OK
, -0x80000000);
223 /* Test basic error handling. */
224 PARSE (int, "%d", "", BAD
);
225 PARSE (int, "%d", "-", BAD
);
226 PARSE (int, "%d", "- 0", BAD
);
227 PARSE (int, "%d", "+", BAD
);
228 PARSE (int, "%d", "++", BAD
);
229 PARSE (int, "%d", "++0", BAD
);
230 PARSE (int, "%d", "--0", BAD
);
231 PARSE (int, "%d", "0x", BAD
);
232 PARSE (int, "%d", "0xg", BAD
);
233 PARSE (int, "%d", "08", BAD
);
234 PARSE (int, "%d", "0x1p1", BAD
);
235 PARSE (int, "%d", "42x", BAD
);
236 PARSE (int, "%d", "42e42", BAD
);
237 PARSE (int, "%d", "42-", BAD
);
238 PARSE (int, "%d", "garbage", BAD
);
239 PARSE (int, "%d", "inf", BAD
);
240 PARSE (int, "%d", "nan", BAD
);
241 PARSE (int, "%d", "0.0", BAD
);
242 PARSE (int, "%d", "1,000", BAD
);
243 PARSE (int, "%d", "2147483648", BAD
); /* INT_MAX + 1 */
244 PARSE (int, "%d", "-2147483649", BAD
); /* INT_MIN - 1 */
245 PARSE (int, "%d", "999999999999999999999999", BAD
);
246 PARSE (int, "%d", "-999999999999999999999999", BAD
);
248 /* Test nbdkit_parse_unsigned. */
249 PARSE (unsigned, "%u", "0", OK
, 0);
250 PARSE (unsigned, "%u", " 0", OK
, 0);
251 PARSE (unsigned, "%u", "1", OK
, 1);
252 PARSE (unsigned, "%u", "99", OK
, 99);
253 PARSE (unsigned, "%u", "0x1", OK
, 1);
254 PARSE (unsigned, "%u", "0xf", OK
, 15);
255 PARSE (unsigned, "%u", "0x10", OK
, 16);
256 PARSE (unsigned, "%u", "0xff", OK
, 255);
257 PARSE (unsigned, "%u", "01", OK
, 1);
258 PARSE (unsigned, "%u", "07", OK
, 7);
259 PARSE (unsigned, "%u", "010", OK
, 8);
260 PARSE (unsigned, "%u", "+0", OK
, 0);
261 PARSE (unsigned, "%u", "+99", OK
, 99);
262 PARSE (unsigned, "%u", "+0xf", OK
, 15);
263 PARSE (unsigned, "%u", "+010", OK
, 8);
264 PARSE (unsigned, "%u", "-0", BAD
); /* this is by choice */
265 PARSE (unsigned, "%u", " -0", BAD
);
266 PARSE (unsigned, "%u", "-99", BAD
);
267 PARSE (unsigned, "%u", "-0xf", BAD
);
268 PARSE (unsigned, "%u", "-010", BAD
);
269 PARSE (unsigned, "%u", "2147483647", OK
, 2147483647); /* INT_MAX */
270 PARSE (unsigned, "%u", "-2147483648", BAD
); /* INT_MIN */
271 PARSE (unsigned, "%u", "0x7fffffff", OK
, 0x7fffffff);
272 PARSE (unsigned, "%u", "-0x80000000", BAD
);
274 /* Test nbdkit_parse_int8_t. */
275 PARSE (int8_t, "%" PRIi8
, "0", OK
, 0);
276 PARSE (int8_t, "%" PRIi8
, "0x7f", OK
, 0x7f);
277 PARSE (int8_t, "%" PRIi8
, "-0x80", OK
, -0x80);
278 PARSE (int8_t, "%" PRIi8
, "0x80", BAD
);
279 PARSE (int8_t, "%" PRIi8
, "-0x81", BAD
);
281 /* Test nbdkit_parse_uint8_t. */
282 PARSE (uint8_t, "%" PRIu8
, "0", OK
, 0);
283 PARSE (uint8_t, "%" PRIu8
, "0xff", OK
, 0xff);
284 PARSE (uint8_t, "%" PRIu8
, "0x100", BAD
);
285 PARSE (uint8_t, "%" PRIu8
, "-1", BAD
);
287 /* Test nbdkit_parse_int16_t. */
288 PARSE (int16_t, "%" PRIi16
, "0", OK
, 0);
289 PARSE (int16_t, "%" PRIi16
, "0x7fff", OK
, 0x7fff);
290 PARSE (int16_t, "%" PRIi16
, "-0x8000", OK
, -0x8000);
291 PARSE (int16_t, "%" PRIi16
, "0x8000", BAD
);
292 PARSE (int16_t, "%" PRIi16
, "-0x8001", BAD
);
294 /* Test nbdkit_parse_uint16_t. */
295 PARSE (uint16_t, "%" PRIu16
, "0", OK
, 0);
296 PARSE (uint16_t, "%" PRIu16
, "0xffff", OK
, 0xffff);
297 PARSE (uint16_t, "%" PRIu16
, "0x10000", BAD
);
298 PARSE (uint16_t, "%" PRIu16
, "-1", BAD
);
300 /* Test nbdkit_parse_int32_t. */
301 PARSE (int32_t, "%" PRIi32
, "0", OK
, 0);
302 PARSE (int32_t, "%" PRIi32
, "0x7fffffff", OK
, 0x7fffffff);
303 PARSE (int32_t, "%" PRIi32
, "-0x80000000", OK
, -0x80000000);
304 PARSE (int32_t, "%" PRIi32
, "0x80000000", BAD
);
305 PARSE (int32_t, "%" PRIi32
, "-0x80000001", BAD
);
307 /* Test nbdkit_parse_uint32_t. */
308 PARSE (uint32_t, "%" PRIu32
, "0", OK
, 0);
309 PARSE (uint32_t, "%" PRIu32
, "0xffffffff", OK
, 0xffffffff);
310 PARSE (uint32_t, "%" PRIu32
, "0x100000000", BAD
);
311 PARSE (uint32_t, "%" PRIu32
, "-1", BAD
);
313 /* Test nbdkit_parse_int64_t. */
314 PARSE (int64_t, "%" PRIi64
, "0", OK
, 0);
315 PARSE (int64_t, "%" PRIi64
, "0x7fffffffffffffff", OK
, 0x7fffffffffffffff);
316 PARSE (int64_t, "%" PRIi64
, "-0x8000000000000000", OK
, -0x8000000000000000);
317 PARSE (int64_t, "%" PRIi64
, "0x8000000000000000", BAD
);
318 PARSE (int64_t, "%" PRIi64
, "-0x8000000000000001", BAD
);
320 /* Test nbdkit_parse_uint64_t. */
321 PARSE (uint64_t, "%" PRIu64
, "0", OK
, 0);
322 PARSE (uint64_t, "%" PRIu64
, "0xffffffffffffffff", OK
, 0xffffffffffffffff);
323 PARSE (uint64_t, "%" PRIu64
, "0x10000000000000000", BAD
);
324 PARSE (uint64_t, "%" PRIu64
, "-1", BAD
);
334 test_nbdkit_read_password (void)
337 char template[] = "+/tmp/nbdkit_testpw_XXXXXX";
341 /* Test expected failure - no such file */
342 error_flagged
= false;
343 if (nbdkit_read_password ("+/nosuch", &pw
) != -1) {
344 fprintf (stderr
, "Failed to diagnose failed password file\n");
347 else if (pw
!= NULL
) {
348 fprintf (stderr
, "Failed to set password to NULL on failure\n");
351 else if (!error_flagged
) {
352 fprintf (stderr
, "Wrong error message handling\n");
355 error_flagged
= false;
357 /* Test direct password */
358 if (nbdkit_read_password ("abc", &pw
) != 0) {
359 fprintf (stderr
, "Failed to reuse direct password\n");
362 else if (strcmp (pw
, "abc") != 0) {
363 fprintf (stderr
, "Wrong direct password, expected 'abc' got '%s'\n", pw
);
369 /* Test reading password from file */
370 fd
= mkstemp (&template[1]);
375 else if (write (fd
, "abc\n", 4) != 4) {
376 fprintf (stderr
, "Failed to write to file %s\n", &template[1]);
379 else if (nbdkit_read_password (template, &pw
) != 0) {
380 fprintf (stderr
, "Failed to read password from file %s\n", &template[1]);
383 else if (strcmp (pw
, "abc") != 0) {
384 fprintf (stderr
, "Wrong file password, expected 'abc' got '%s'\n", pw
);
391 unlink (&template[1]);
395 fprintf (stderr
, "Wrong error message handling\n");
399 /* XXX Testing reading from stdin would require setting up a pty */
404 main (int argc
, char *argv
[])
407 pass
&= test_nbdkit_parse_size ();
408 pass
&= test_nbdkit_parse_ints ();
409 pass
&= test_nbdkit_read_password ();
410 /* nbdkit_absolute_path and nbdkit_nanosleep not unit-tested here, but
411 * get plenty of coverage in the main testsuite.
413 return pass
? EXIT_SUCCESS
: EXIT_FAILURE
;