plugins: Wire up rust plugin support for NBD_INFO_INIT_STATE
[nbdkit/ericb.git] / server / test-public.c
blob4a7eb1732243401f148d2b97ae5ad569e5ec5114
1 /* nbdkit
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
6 * met:
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
30 * SUCH DAMAGE.
33 #include <config.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdbool.h>
38 #include <stdint.h>
39 #include <inttypes.h>
40 #include <limits.h>
41 #include <string.h>
42 #include <unistd.h>
44 #include "internal.h"
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. */
50 void
51 nbdkit_error (const char *fs, ...)
53 error_flagged = true;
56 volatile int quit;
57 int quit_fd = -1;
59 struct connection *
60 threadlocal_get_conn (void)
62 abort ();
65 int connection_get_status (struct connection *conn)
67 abort ();
70 static bool
71 test_nbdkit_parse_size (void)
73 bool pass = true;
74 struct pair {
75 const char *str;
76 int64_t res;
77 } pairs[] = {
78 /* Bogus strings */
79 { "", -1 },
80 { "0x0", -1 },
81 { "garbage", -1 },
82 { "0garbage", -1 },
83 { "8E", -1 },
84 { "8192P", -1 },
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 */
94 { "-1", -1 },
95 { "-2", -1 },
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 */
104 { "M", -1 },
105 { "1MB", -1 },
106 { "1MiB", -1 },
107 { "1.5M", -1 },
109 /* Valid strings */
110 { "-0", 0 },
111 { "0", 0 },
112 { "+0", 0 },
113 { " 08", 8 },
114 { "1", 1 },
115 { "+1", 1 },
116 { "1234567890", 1234567890 },
117 { "+1234567890", 1234567890 },
118 { "9223372036854775807", INT64_MAX },
119 { "1s", 512 },
120 { "2S", 1024 },
121 { "1b", 1 },
122 { "1B", 1 },
123 { "1k", 1024 },
124 { "1K", 1024 },
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++) {
140 int64_t r;
142 error_flagged = false;
143 r = nbdkit_parse_size (pairs[i].str);
144 if (r != pairs[i].res) {
145 fprintf (stderr,
146 "Wrong parse for %s, got %" PRId64 ", expected %" PRId64 "\n",
147 pairs[i].str, r, pairs[i].res);
148 pass = false;
150 if ((r == -1) != error_flagged) {
151 fprintf (stderr, "Wrong error message handling for %s\n", pairs[i].str);
152 pass = false;
156 return pass;
159 static bool
160 test_nbdkit_parse_ints (void)
162 bool pass = true;
164 #define PARSE(...) PARSE_(__VA_ARGS__)
165 #define PARSE_(TYPE, FORMAT, TEST, RET, EXPECTED) \
166 do { \
167 error_flagged = false; \
168 TYPE i = 123; \
169 int r = nbdkit_parse_##TYPE ("test", TEST, &i); \
170 if (r != RET || i != (r ? 123 : EXPECTED)) { \
171 fprintf (stderr, \
172 "%s: %d: wrong parse for %s: r=%d i=" FORMAT "\n", \
173 __FILE__, __LINE__, TEST, r, i); \
174 pass = false; \
176 if ((r == -1) != error_flagged) { \
177 fprintf (stderr, \
178 "%s: %d: wrong error message handling for %s\n", \
179 __FILE__, __LINE__, TEST); \
180 pass = false; \
182 } while (0)
183 #define OK 0
184 #define BAD -1, 0
186 /* Test the basic parsing of decimals, hexadecimal, octal and
187 * negative numbers.
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);
326 #undef PARSE
327 #undef PARSE_
328 #undef OK
329 #undef BAD
330 return pass;
333 static bool
334 test_nbdkit_read_password (void)
336 bool pass = true;
337 char template[] = "+/tmp/nbdkit_testpw_XXXXXX";
338 char template2[] = "/tmp/nbdkit_testpw2_XXXXXX";
339 char fdbuf[16];
340 char *pw = template;
341 int fd;
343 /* Test expected failure - no such file */
344 error_flagged = false;
345 if (nbdkit_read_password ("+/nosuch", &pw) != -1) {
346 fprintf (stderr, "Failed to diagnose failed password file\n");
347 pass = false;
349 else if (pw != NULL) {
350 fprintf (stderr, "Failed to set password to NULL on failure\n");
351 pass = false;
353 else if (!error_flagged) {
354 fprintf (stderr, "Wrong error message handling\n");
355 pass = false;
357 error_flagged = false;
359 /* Test direct password */
360 if (nbdkit_read_password ("abc", &pw) != 0) {
361 fprintf (stderr, "Failed to reuse direct password\n");
362 pass = false;
364 else if (strcmp (pw, "abc") != 0) {
365 fprintf (stderr, "Wrong direct password, expected 'abc' got '%s'\n", pw);
366 pass = false;
368 free (pw);
369 pw = NULL;
371 /* Test reading password from file */
372 fd = mkstemp (&template[1]);
373 if (fd < 0) {
374 perror ("mkstemp");
375 pass = false;
377 else if (write (fd, "abc\n", 4) != 4) {
378 fprintf (stderr, "Failed to write to file %s\n", &template[1]);
379 pass = false;
381 else if (nbdkit_read_password (template, &pw) != 0) {
382 fprintf (stderr, "Failed to read password from file %s\n", &template[1]);
383 pass = false;
385 else if (strcmp (pw, "abc") != 0) {
386 fprintf (stderr, "Wrong file password, expected 'abc' got '%s'\n", pw);
387 pass = false;
389 free (pw);
391 if (fd >= 0) {
392 close (fd);
393 unlink (&template[1]);
396 /* Test reading password from file descriptor. */
397 fd = mkstemp (template2);
398 if (fd < 0) {
399 perror ("mkstemp");
400 pass = false;
402 else if (write (fd, "abc\n", 4) != 4) {
403 fprintf (stderr, "Failed to write to file %s\n", template2);
404 pass = false;
406 else {
407 snprintf (fdbuf, sizeof fdbuf, "-%d", fd);
408 lseek (fd, 0, 0);
409 if (nbdkit_read_password (fdbuf, &pw) == -1) {
410 fprintf (stderr, "Failed to read password from fd %s\n", fdbuf);
411 pass = false;
413 else if (strcmp (pw, "abc") != 0) {
414 fprintf (stderr, "Wrong file password, expected 'abc' got '%s'\n", pw);
415 pass = false;
417 free (pw);
420 if (fd >= 0) {
421 /* Don't close fd, it is closed by nbdkit_read_password. */
422 unlink (template2);
425 if (error_flagged) {
426 fprintf (stderr, "Wrong error message handling\n");
427 pass = false;
430 /* XXX Testing reading from stdin would require setting up a pty */
431 return pass;
435 main (int argc, char *argv[])
437 bool pass = true;
438 pass &= test_nbdkit_parse_size ();
439 pass &= test_nbdkit_parse_ints ();
440 pass &= test_nbdkit_read_password ();
441 /* nbdkit_absolute_path and nbdkit_nanosleep not unit-tested here, but
442 * get plenty of coverage in the main testsuite.
444 return pass ? EXIT_SUCCESS : EXIT_FAILURE;