Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / tests / uri_test.c
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 /** @file
23  *
24  * URI self-tests
25  *
26  */
27
28 /* Forcibly enable assertions */
29 #undef NDEBUG
30
31 #include <string.h>
32 #include <byteswap.h>
33 #include <ipxe/uri.h>
34 #include <ipxe/params.h>
35 #include <ipxe/test.h>
36
37 /** A URI parsing/formatting test */
38 struct uri_test {
39         /** URI string */
40         const char *string;
41         /** URI */
42         struct uri uri;
43 };
44
45 /** A URI port number test */
46 struct uri_port_test {
47         /** URI string */
48         const char *string;
49         /** Default port number */
50         unsigned int default_port;
51         /** Expected port number */
52         unsigned int port;
53 };
54
55 /** A URI or path resolution test */
56 struct uri_resolve_test {
57         /** Base path or URI */
58         const char *base;
59         /** Relative path or URI */
60         const char *relative;
61         /** Expected resolved path or URI */
62         const char *resolved;
63 };
64
65 /** A TFTP URI test */
66 struct uri_tftp_test {
67         /** Next-server address */
68         struct in_addr next_server;
69         /** Filename */
70         const char *filename;
71         /** URI */
72         struct uri uri;
73         /** URI string (for display only; cannot be reparsed) */
74         const char *string;
75 };
76
77 /** A current working URI test */
78 struct uri_churi_test {
79         /** Relative URI */
80         const char *relative;
81         /** Expected new working URI */
82         const char *expected;
83 };
84
85 /** A form parameter URI test list */
86 struct uri_params_test_list {
87         /** Key */
88         const char *key;
89         /** Value */
90         const char *value;
91 };
92
93 /** A form parameter URI test */
94 struct uri_params_test {
95         /** URI string */
96         const char *string;
97         /** URI */
98         struct uri uri;
99         /** Parameter list name */
100         const char *name;
101         /** Parameter list */
102         struct uri_params_test_list *list;
103 };
104
105 /**
106  * Compare two URI component strings
107  *
108  * @v first             First string, or NULL
109  * @v second            Second string, or NULL
110  * @v difference        Difference
111  */
112 static int uristrcmp ( const char *first, const char *second ) {
113
114         /* Compare strings, allowing for either to be NULL */
115         if ( first == second ) {
116                 return 0;
117         } else if ( ( first == NULL ) || ( second == NULL ) ) {
118                 return -1;
119         } else {
120                 return strcmp ( first, second );
121         }
122 }
123
124 /**
125  * Report URI equality test result
126  *
127  * @v uri               URI
128  * @v expected          Expected URI
129  * @v file              Test code file
130  * @v line              Test code line
131  */
132 static void uri_okx ( struct uri *uri, struct uri *expected, const char *file,
133                       unsigned int line ) {
134
135         okx ( uristrcmp ( uri->scheme, expected->scheme ) == 0, file, line );
136         okx ( uristrcmp ( uri->opaque, expected->opaque ) == 0, file, line );
137         okx ( uristrcmp ( uri->user, expected->user ) == 0, file, line );
138         okx ( uristrcmp ( uri->password, expected->password ) == 0, file, line);
139         okx ( uristrcmp ( uri->host, expected->host ) == 0, file, line );
140         okx ( uristrcmp ( uri->port, expected->port ) == 0, file, line );
141         okx ( uristrcmp ( uri->path, expected->path ) == 0, file, line );
142         okx ( uristrcmp ( uri->query, expected->query ) == 0, file, line );
143         okx ( uristrcmp ( uri->fragment, expected->fragment ) == 0, file, line);
144         okx ( uri->params == expected->params, file, line );
145 }
146 #define uri_ok( uri, expected ) uri_okx ( uri, expected, __FILE__, __LINE__ )
147
148 /**
149  * Report URI parsing test result
150  *
151  * @v test              URI test
152  * @v file              Test code file
153  * @v line              Test code line
154  */
155 static void uri_parse_okx ( struct uri_test *test, const char *file,
156                             unsigned int line ) {
157         struct uri *uri;
158
159         /* Parse URI */
160         uri = parse_uri ( test->string );
161         okx ( uri != NULL, file, line );
162         if ( uri )
163                 uri_okx ( uri, &test->uri, file, line );
164         uri_put ( uri );
165 }
166 #define uri_parse_ok( test ) uri_parse_okx ( test, __FILE__, __LINE__ )
167
168 /**
169  * Report URI formatting test result
170  *
171  * @v test              URI test
172  * @v file              Test code file
173  * @v line              Test code line
174  */
175 static void uri_format_okx ( struct uri_test *test, const char *file,
176                              unsigned int line ) {
177         char buf[ strlen ( test->string ) + 1 /* NUL */ ];
178         char *tmp;
179         size_t len;
180
181         /* Format into fixed-size buffer */
182         len = format_uri ( &test->uri, buf, sizeof ( buf ) );
183         okx ( len == ( sizeof ( buf ) - 1 /* NUL */ ), file, line );
184         okx ( strcmp ( buf, test->string ) == 0, file, line );
185
186         /* Format into temporarily allocated buffer */
187         tmp = format_uri_alloc ( &test->uri );
188         okx ( tmp != NULL, file, line );
189         if ( tmp )
190                 okx ( strcmp ( tmp, test->string ) == 0, file, line );
191         free ( tmp );
192 }
193 #define uri_format_ok( test ) uri_format_okx ( test, __FILE__, __LINE__ )
194
195 /**
196  * Report URI duplication test result
197  *
198  * @v test              URI
199  * @v file              Test code file
200  * @v line              Test code line
201  */
202 static void uri_dup_okx ( struct uri *uri, const char *file,
203                           unsigned int line ) {
204         struct uri *dup;
205
206         dup = uri_dup ( uri );
207         okx ( dup != NULL, file, line );
208         if ( dup )
209                 uri_okx ( dup, uri, file, line );
210         uri_put ( dup );
211 }
212 #define uri_dup_ok( test ) uri_dup_okx ( test, __FILE__, __LINE__ )
213
214 /**
215  * Report URI combined parsing and formatting test result
216  *
217  * @v test              URI test
218  * @v file              Test code file
219  * @v line              Test code line
220  */
221 static void uri_parse_format_dup_okx ( struct uri_test *test, const char *file,
222                                        unsigned int line ) {
223
224         uri_parse_okx ( test, file, line );
225         uri_format_okx ( test, file, line );
226         uri_dup_okx ( &test->uri, file, line );
227 }
228 #define uri_parse_format_dup_ok( test ) \
229         uri_parse_format_dup_okx ( test, __FILE__, __LINE__ )
230
231 /**
232  * Report URI port number test result
233  *
234  * @v test              URI port number test
235  * @v file              Test code file
236  * @v line              Test code line
237  */
238 static void uri_port_okx ( struct uri_port_test *test, const char *file,
239                            unsigned int line ) {
240         struct uri *uri;
241         unsigned int port;
242
243         /* Parse URI */
244         uri = parse_uri ( test->string );
245         okx ( uri != NULL, file, line );
246         if ( uri ) {
247                 port = uri_port ( uri, test->default_port );
248                 okx ( port == test->port, file, line );
249         }
250         uri_put ( uri );
251 }
252 #define uri_port_ok( test ) uri_port_okx ( test, __FILE__, __LINE__ )
253
254 /**
255  * Report URI resolution test result
256  *
257  * @v test              Path resolution test
258  * @v file              Test code file
259  * @v line              Test code line
260  */
261 static void uri_resolve_okx ( struct uri_resolve_test *test,
262                               const char *file, unsigned int line ) {
263         struct uri *base;
264         struct uri *relative;
265         struct uri *resolved = NULL;
266         char *formatted;
267
268         /* Parse URIs */
269         base = parse_uri ( test->base );
270         okx ( base != NULL, file, line );
271         relative = parse_uri ( test->relative );
272         okx ( relative != NULL, file, line );
273
274         /* Resolve URI  */
275         if ( base && relative ) {
276                 resolved = resolve_uri ( base, relative );
277                 okx ( resolved != NULL, file, line );
278         }
279
280         /* Format resolved URI */
281         formatted = format_uri_alloc ( resolved );
282         okx ( formatted != NULL, file, line );
283
284         /* Check resolved URI */
285         if ( formatted )
286                 okx ( strcmp ( formatted, test->resolved ) == 0, file, line );
287
288         free ( formatted );
289         uri_put ( resolved );
290         uri_put ( relative );
291         uri_put ( base );
292 }
293 #define uri_resolve_ok( test ) uri_resolve_okx ( test, __FILE__, __LINE__ )
294
295 /**
296  * Report path resolution test result
297  *
298  * @v test              Path resolution test
299  * @v file              Test code file
300  * @v line              Test code line
301  */
302 static void uri_resolve_path_okx ( struct uri_resolve_test *test,
303                                    const char *file, unsigned int line ) {
304         char *resolved;
305
306         /* Resolve paths using resolve_path() directly */
307         resolved = resolve_path ( test->base, test->relative );
308         okx ( resolved != NULL, file, line );
309         if ( resolved )
310                 okx ( strcmp ( resolved, test->resolved ) == 0, file, line );
311         free ( resolved );
312
313         /* Resolve paths as URIs (since all paths are valid URIs) */
314         uri_resolve_okx ( test, file, line );
315 }
316 #define uri_resolve_path_ok( test ) \
317         uri_resolve_path_okx ( test, __FILE__, __LINE__ )
318
319 /**
320  * Report URI TFTP test result
321  *
322  * @v test              URI TFTP test
323  * @v file              Test code file
324  * @v line              Test code line
325  */
326 static void uri_tftp_okx ( struct uri_tftp_test *test, const char *file,
327                            unsigned int line ) {
328         char buf[ strlen ( test->string ) + 1 /* NUL */ ];
329         struct uri *uri;
330         size_t len;
331
332         /* Construct URI */
333         uri = tftp_uri ( test->next_server, test->filename );
334         okx ( uri != NULL, file, line );
335         if ( uri ) {
336                 uri_okx ( uri, &test->uri, file, line );
337                 len = format_uri ( uri, buf, sizeof ( buf ) );
338                 okx ( len == ( sizeof ( buf ) - 1 /* NUL */ ), file, line );
339                 okx ( strcmp ( buf, test->string ) == 0, file, line );
340         }
341         uri_put ( uri );
342 }
343 #define uri_tftp_ok( test ) uri_tftp_okx ( test, __FILE__, __LINE__ )
344
345 /**
346  * Report current working URI test result
347  *
348  * @v tests             List of current working URI tests
349  * @v file              Test code file
350  * @v line              Test code line
351  */
352 static void uri_churi_okx ( struct uri_churi_test *test, const char *file,
353                             unsigned int line ) {
354         struct uri *old_cwuri;
355         struct uri *uri;
356         char *formatted;
357
358         /* Preserve original current working URI */
359         old_cwuri = uri_get ( cwuri );
360
361         /* Perform sequence of current working URI changes */
362         do {
363                 /* Parse relative URI */
364                 uri = parse_uri ( test->relative );
365                 okx ( uri != NULL, file, line );
366
367                 /* Move to this URI */
368                 churi ( uri );
369
370                 /* Format new current working URI */
371                 formatted = format_uri_alloc ( cwuri );
372                 okx ( formatted != NULL, file, line );
373                 if ( formatted ) {
374                         okx ( strcmp ( formatted, test->expected ) == 0,
375                               file, line );
376                 }
377
378                 /* Free temporary storage */
379                 free ( formatted );
380                 uri_put ( uri );
381
382                 /* Move to next current working URI test */
383                 test++;
384
385         } while ( test->relative != NULL );
386
387         /* Restore original current working URI */
388         churi ( old_cwuri );
389         uri_put ( old_cwuri );
390 }
391 #define uri_churi_ok( test ) uri_churi_okx ( test, __FILE__, __LINE__ )
392
393 /**
394  * Report form parameter URI test list result
395  *
396  * @v test              Form parameter URI test
397  * @v uri               URI
398  * @v file              Test code file
399  * @v line              Test code line
400  */
401 static void uri_params_list_okx ( struct uri_params_test *test,
402                                   struct uri *uri, const char *file,
403                                   unsigned int line ) {
404         struct uri_params_test_list *list;
405         struct parameter *param;
406
407         /* Check URI */
408         uri_okx ( uri, &test->uri, file, line );
409
410         /* Check URI parameters */
411         okx ( uri->params != NULL, file, line );
412         if ( uri->params ) {
413                 list = test->list;
414                 for_each_param ( param, uri->params ) {
415                         okx ( strcmp ( param->key, list->key ) == 0,
416                               file, line );
417                         okx ( strcmp ( param->value, list->value ) == 0,
418                               file, line );
419                         list++;
420                 }
421                 okx ( list->key == NULL, file, line );
422         }
423 }
424 #define uri_params_list_ok( test ) \
425         uri_params_list_okx ( test, __FILE__, __LINE__ )
426
427 /**
428  * Report form parameter URI test result
429  *
430  * @v test              Form parameter URI test
431  * @v file              Test code file
432  * @v line              Test code line
433  */
434 static void uri_params_okx ( struct uri_params_test *test, const char *file,
435                              unsigned int line ) {
436         struct uri_params_test_list *list;
437         struct parameters *params;
438         struct parameter *param;
439         struct uri *uri;
440         struct uri *dup;
441
442         /* Create parameter list */
443         params = create_parameters ( test->name );
444         okx ( params != NULL, file, line );
445         if ( params ) {
446                 for ( list = test->list ; list->key ; list++ ) {
447                         param = add_parameter ( params, list->key, list->value);
448                         okx ( param != NULL, file, line );
449                 }
450         }
451
452         /* Record parameter list as part of expected URI */
453         test->uri.params = params;
454
455         /* Parse URI */
456         uri = parse_uri ( test->string );
457         okx ( uri != NULL, file, line );
458         if ( uri )
459                 uri_params_list_okx ( test, uri, file, line );
460
461         /* Duplicate URI */
462         dup = uri_dup ( uri );
463         okx ( dup != NULL, file, line );
464         if ( dup )
465                 uri_params_list_okx ( test, dup, file, line );
466
467         /* Clear parameter list in expected URI */
468         test->uri.params = NULL;
469
470         uri_put ( uri );
471         uri_put ( dup );
472 }
473 #define uri_params_ok( test ) uri_params_okx ( test, __FILE__, __LINE__ )
474
475 /** Empty URI */
476 static struct uri_test uri_empty = {
477         .string = "",
478 };
479
480 /** Basic HTTP URI */
481 static struct uri_test uri_boot_ipxe_org = {
482         "http://boot.ipxe.org/demo/boot.php",
483         { .scheme = "http", .host = "boot.ipxe.org", .path = "/demo/boot.php" }
484 };
485
486 /** Basic opaque URI */
487 static struct uri_test uri_mailto = {
488         "mailto:ipxe-devel@lists.ipxe.org",
489         { .scheme = "mailto", .opaque = "ipxe-devel@lists.ipxe.org" }
490 };
491
492 /** HTTP URI with all the trimmings */
493 static struct uri_test uri_http_all = {
494         "http://anon:password@example.com:3001/~foo/cgi-bin/foo.pl?a=b&c=d#bit",
495         {
496                 .scheme = "http",
497                 .user = "anon",
498                 .password = "password",
499                 .host = "example.com",
500                 .port = "3001",
501                 .path = "/~foo/cgi-bin/foo.pl",
502                 .query = "a=b&c=d",
503                 .fragment = "bit",
504         },
505 };
506
507 /** HTTP URI with escaped characters */
508 static struct uri_test uri_http_escaped = {
509         "https://test.ipxe.org/wtf%3F%0A?kind%23of/uri%20is#this%3F",
510         {
511                 .scheme = "https",
512                 .host = "test.ipxe.org",
513                 .path = "/wtf?\n",
514                 .query = "kind#of/uri is",
515                 .fragment = "this?",
516         },
517 };
518
519 /** HTTP URI with improperly escaped characters */
520 static struct uri_test uri_http_escaped_improper = {
521         /* We accept for parsing improperly escaped characters.
522          * (Formatting the parsed URI would produce the properly
523          * encoded form, and so would not exactly match the original
524          * URI string.)
525          */
526         "https://test%2eipxe.org/wt%66%3f\n?kind%23of/uri is#this?",
527         {
528                 .scheme = "https",
529                 .host = "test.ipxe.org",
530                 .path = "/wtf?\n",
531                 .query = "kind#of/uri is",
532                 .fragment = "this?",
533         },
534 };
535
536 /** IPv6 URI */
537 static struct uri_test uri_ipv6 = {
538         "http://[2001:ba8:0:1d4::6950:5845]/",
539         {
540                 .scheme = "http",
541                 .host = "[2001:ba8:0:1d4::6950:5845]",
542                 .path = "/",
543         },
544 };
545
546 /** IPv6 URI with port */
547 static struct uri_test uri_ipv6_port = {
548         "http://[2001:ba8:0:1d4::6950:5845]:8001/boot",
549         {
550                 .scheme = "http",
551                 .host = "[2001:ba8:0:1d4::6950:5845]",
552                 .port = "8001",
553                 .path = "/boot",
554         },
555 };
556
557 /** IPv6 URI with link-local address */
558 static struct uri_test uri_ipv6_local = {
559         "http://[fe80::69ff:fe50:5845%25net0]/ipxe",
560         {
561                 .scheme = "http",
562                 .host = "[fe80::69ff:fe50:5845%net0]",
563                 .path = "/ipxe",
564         },
565 };
566
567 /** IPv6 URI with link-local address not conforming to RFC 6874 */
568 static struct uri_test uri_ipv6_local_non_conforming = {
569         /* We accept for parsing a single "%" in "%net0" (rather than
570          * the properly encoded form "%25net0").  (Formatting the
571          * parsed URI would produce the properly encoded form, and so
572          * would not exactly match the original URI string.)
573          */
574         "http://[fe80::69ff:fe50:5845%net0]/ipxe",
575         {
576                 .scheme = "http",
577                 .host = "[fe80::69ff:fe50:5845%net0]",
578                 .path = "/ipxe",
579         },
580 };
581
582 /** iSCSI URI */
583 static struct uri_test uri_iscsi = {
584         "iscsi:10.253.253.1::::iqn.2010-04.org.ipxe:rabbit",
585         {
586                 .scheme = "iscsi",
587                 .opaque = "10.253.253.1::::iqn.2010-04.org.ipxe:rabbit",
588         },
589 };
590
591 /** URI with port number */
592 static struct uri_port_test uri_explicit_port = {
593         "http://192.168.0.1:8080/boot.php",
594         80,
595         8080,
596 };
597
598 /** URI without port number */
599 static struct uri_port_test uri_default_port = {
600         "http://192.168.0.1/boot.php",
601         80,
602         80,
603 };
604
605 /** Simple path resolution test */
606 static struct uri_resolve_test uri_simple_path = {
607         "/etc/passwd",
608         "group",
609         "/etc/group",
610 };
611
612 /** Path resolution test with "." and ".." elements */
613 static struct uri_resolve_test uri_relative_path = {
614         "/var/lib/tftpboot/pxe/pxelinux.0",
615         "./../ipxe/undionly.kpxe",
616         "/var/lib/tftpboot/ipxe/undionly.kpxe",
617 };
618
619 /** Path resolution test terminating with directory */
620 static struct uri_resolve_test uri_directory_path = {
621         "/test/cgi-bin.pl/boot.ipxe",
622         "..",
623         "/test/",
624 };
625
626 /** Path resolution test with excessive ".." elements */
627 static struct uri_resolve_test uri_excessive_path = {
628         "/var/lib/tftpboot/ipxe.pxe",
629         "../../../../../../../foo",
630         "/foo",
631 };
632
633 /** Path resolution test with absolute path */
634 static struct uri_resolve_test uri_absolute_path = {
635         "/var/lib/tftpboot",
636         "/etc/hostname",
637         "/etc/hostname",
638 };
639
640 /** Relative URI resolution test */
641 static struct uri_resolve_test uri_relative = {
642         "http://boot.ipxe.org/demo/boot.php?vendor=10ec&device=8139",
643         "initrd.img",
644         "http://boot.ipxe.org/demo/initrd.img",
645 };
646
647 /** Absolute URI resolution test */
648 static struct uri_resolve_test uri_absolute = {
649         "http://boot.ipxe.org/demo/boot.php",
650         "ftp://192.168.0.1/boot.ipxe",
651         "ftp://192.168.0.1/boot.ipxe",
652 };
653
654 /** Absolute path URI resolution test */
655 static struct uri_resolve_test uri_absolute_uri_path = {
656         "http://boot.ipxe.org/demo/boot.php#test",
657         "/demo/vmlinuz",
658         "http://boot.ipxe.org/demo/vmlinuz",
659 };
660
661 /** Query URI resolution test */
662 static struct uri_resolve_test uri_query = {
663         "http://10.253.253.1/test.pl?mac=02-00-69-50-58-45",
664         "?mac=00-1f-16-bc-fe-2f",
665         "http://10.253.253.1/test.pl?mac=00-1f-16-bc-fe-2f",
666 };
667
668 /** Fragment URI resolution test */
669 static struct uri_resolve_test uri_fragment = {
670         "http://192.168.0.254/test#foo",
671         "#bar",
672         "http://192.168.0.254/test#bar",
673 };
674
675 /** TFTP URI with absolute path */
676 static struct uri_tftp_test uri_tftp_absolute = {
677         { .s_addr = htonl ( 0xc0a80002 ) /* 192.168.0.2 */ },
678         "/absolute/path",
679         {
680                 .scheme = "tftp",
681                 .host = "192.168.0.2",
682                 .path = "/absolute/path",
683         },
684         "tftp://192.168.0.2/absolute/path",
685 };
686
687 /** TFTP URI with relative path */
688 static struct uri_tftp_test uri_tftp_relative = {
689         { .s_addr = htonl ( 0xc0a80003 ) /* 192.168.0.3 */ },
690         "relative/path",
691         {
692                 .scheme = "tftp",
693                 .host = "192.168.0.3",
694                 .path = "relative/path",
695         },
696         "tftp://192.168.0.3/relative/path",
697 };
698
699 /** TFTP URI with path containing special characters */
700 static struct uri_tftp_test uri_tftp_icky = {
701         { .s_addr = htonl ( 0x0a000006 ) /* 10.0.0.6 */ },
702         "C:\\tftpboot\\icky#path",
703         {
704                 .scheme = "tftp",
705                 .host = "10.0.0.6",
706                 .path = "C:\\tftpboot\\icky#path",
707         },
708         "tftp://10.0.0.6/C%3A\\tftpboot\\icky%23path",
709 };
710
711 /** Current working URI test */
712 static struct uri_churi_test uri_churi[] = {
713         {
714                 "http://boot.ipxe.org/demo/boot.php",
715                 "http://boot.ipxe.org/demo/boot.php",
716         },
717         {
718                 "?vendor=10ec&device=8139",
719                 "http://boot.ipxe.org/demo/boot.php?vendor=10ec&device=8139",
720         },
721         {
722                 "fedora/fedora.ipxe",
723                 "http://boot.ipxe.org/demo/fedora/fedora.ipxe",
724         },
725         {
726                 "vmlinuz",
727                 "http://boot.ipxe.org/demo/fedora/vmlinuz",
728         },
729         {
730                 "http://local/boot/initrd.img",
731                 "http://local/boot/initrd.img",
732         },
733         {
734                 "modules/8139too.ko",
735                 "http://local/boot/modules/8139too.ko",
736         },
737         {
738                 NULL,
739                 NULL,
740         }
741 };
742
743 /** Form parameter URI test list */
744 static struct uri_params_test_list uri_params_list[] = {
745         {
746                 "vendor",
747                 "10ec",
748         },
749         {
750                 "device",
751                 "8139",
752         },
753         {
754                 "uuid",
755                 "f59fac00-758f-498f-9fe5-87d790045d94",
756         },
757         {
758                 NULL,
759                 NULL,
760         }
761 };
762
763 /** Form parameter URI test */
764 static struct uri_params_test uri_params = {
765         "http://boot.ipxe.org/demo/boot.php##params",
766         {
767                 .scheme = "http",
768                 .host = "boot.ipxe.org",
769                 .path = "/demo/boot.php",
770         },
771         NULL,
772         uri_params_list,
773 };
774
775 /** Named form parameter URI test list */
776 static struct uri_params_test_list uri_named_params_list[] = {
777         {
778                 "mac",
779                 "00:1e:65:80:d3:b6",
780         },
781         {
782                 "serial",
783                 "LXTQ20Z1139322762F2000",
784         },
785         {
786                 NULL,
787                 NULL,
788         }
789 };
790
791 /** Named form parameter URI test */
792 static struct uri_params_test uri_named_params = {
793         "http://192.168.100.4:3001/register##params=foo",
794         {
795                 .scheme = "http",
796                 .host = "192.168.100.4",
797                 .port = "3001",
798                 .path = "/register",
799         },
800         "foo",
801         uri_named_params_list,
802 };
803
804 /**
805  * Perform URI self-test
806  *
807  */
808 static void uri_test_exec ( void ) {
809
810         /* URI parsing, formatting, and duplication tests */
811         uri_parse_format_dup_ok ( &uri_empty );
812         uri_parse_format_dup_ok ( &uri_boot_ipxe_org );
813         uri_parse_format_dup_ok ( &uri_mailto );
814         uri_parse_format_dup_ok ( &uri_http_all );
815         uri_parse_format_dup_ok ( &uri_http_escaped );
816         uri_parse_ok ( &uri_http_escaped_improper ); /* Parse only */
817         uri_parse_format_dup_ok ( &uri_ipv6 );
818         uri_parse_format_dup_ok ( &uri_ipv6_port );
819         uri_parse_format_dup_ok ( &uri_ipv6_local );
820         uri_parse_ok ( &uri_ipv6_local_non_conforming ); /* Parse only */
821         uri_parse_format_dup_ok ( &uri_iscsi );
822
823         /** URI port number tests */
824         uri_port_ok ( &uri_explicit_port );
825         uri_port_ok ( &uri_default_port );
826
827         /** Path resolution tests */
828         uri_resolve_path_ok ( &uri_simple_path );
829         uri_resolve_path_ok ( &uri_relative_path );
830         uri_resolve_path_ok ( &uri_directory_path );
831         uri_resolve_path_ok ( &uri_excessive_path );
832         uri_resolve_path_ok ( &uri_absolute_path );
833
834         /** URI resolution tests */
835         uri_resolve_ok ( &uri_relative );
836         uri_resolve_ok ( &uri_absolute );
837         uri_resolve_ok ( &uri_absolute_uri_path );
838         uri_resolve_ok ( &uri_query );
839         uri_resolve_ok ( &uri_fragment );
840
841         /* TFTP URI construction tests */
842         uri_tftp_ok ( &uri_tftp_absolute );
843         uri_tftp_ok ( &uri_tftp_relative );
844         uri_tftp_ok ( &uri_tftp_icky );
845
846         /* Current working URI tests */
847         uri_churi_ok ( uri_churi );
848
849         /* Form parameter URI tests */
850         uri_params_ok ( &uri_params );
851         uri_params_ok ( &uri_named_params );
852 }
853
854 /** URI self-test */
855 struct self_test uri_test __self_test = {
856         .name = "uri",
857         .exec = uri_test_exec,
858 };