iPXE
list_test.c File Reference

List function tests. More...

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <ipxe/list.h>
#include <ipxe/test.h>

Go to the source code of this file.

Data Structures

struct  list_test
 A list test structure. More...

Macros

#define list_contents_ok(list, expected)
 Report list test result.
#define list_iterate_ok(macro, expected, pos, ...)
 Report list iteration test result.
#define list_iterate_entry_ok(macro, expected, pos, ...)
 Report list entry iteration test result.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static LIST_HEAD (test_list)
 Test list.
static int list_check_contents (struct list_head *list, const char *expected)
 Check list contents are as expected.
static void list_test_exec (void)
 Perform list self-test.

Variables

static struct list_test list_tests []
 List test elements.
struct self_test list_test __self_test
 List self-test.

Detailed Description

List function tests.

Definition in file list_test.c.

Macro Definition Documentation

◆ list_contents_ok

#define list_contents_ok ( list,
expected )
Value:
do { \
ok ( list_check_contents ( (list), (expected) ) ); \
} while ( 0 )
static int list_check_contents(struct list_head *list, const char *expected)
Check list contents are as expected.
Definition list_test.c:73

Report list test result.

Parameters
listTest list
expectedExpected contents

Definition at line 122 of file list_test.c.

122#define list_contents_ok( list, expected ) do { \
123 ok ( list_check_contents ( (list), (expected) ) ); \
124 } while ( 0 )

Referenced by list_test_exec().

◆ list_iterate_ok

#define list_iterate_ok ( macro,
expected,
pos,
... )
Value:
do { \
const char *check = expected; \
macro ( pos, __VA_ARGS__ ) { \
struct list_test *entry = \
list_entry ( pos, struct list_test, \
list ); \
ok ( entry->label == *(check++) ); \
} \
ok ( *check == '\0' ); \
} while ( 0 )
A list test structure.
Definition list_test.c:42
char label
Label.
Definition list_test.c:46

Report list iteration test result.

Parameters
macroIterator macro
expectedExpected contents
posIterator
...Arguments to iterator macro

Definition at line 134 of file list_test.c.

134#define list_iterate_ok( macro, expected, pos, ... ) do { \
135 const char *check = expected; \
136 macro ( pos, __VA_ARGS__ ) { \
137 struct list_test *entry = \
138 list_entry ( pos, struct list_test, \
139 list ); \
140 ok ( entry->label == *(check++) ); \
141 } \
142 ok ( *check == '\0' ); \
143 } while ( 0 )

Referenced by list_test_exec().

◆ list_iterate_entry_ok

#define list_iterate_entry_ok ( macro,
expected,
pos,
... )
Value:
do { \
const char *check = expected; \
macro ( pos, __VA_ARGS__ ) { \
ok ( (pos)->label == *(check++) ); \
} \
ok ( *check == '\0' ); \
} while ( 0 )
A text label widget.
Definition label.h:16

Report list entry iteration test result.

Parameters
macroIterator macro
expectedExpected contents
posIterator
...Arguments to iterator macro

Definition at line 153 of file list_test.c.

153#define list_iterate_entry_ok( macro, expected, pos, ... ) do { \
154 const char *check = expected; \
155 macro ( pos, __VA_ARGS__ ) { \
156 ok ( (pos)->label == *(check++) ); \
157 } \
158 ok ( *check == '\0' ); \
159 } while ( 0 )

Referenced by list_test_exec().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ LIST_HEAD()

LIST_HEAD ( test_list )
static

Test list.

◆ list_check_contents()

int list_check_contents ( struct list_head * list,
const char * expected )
static

Check list contents are as expected.

Parameters
listTest list
expectedExpected contents
okList contents are as expected

Definition at line 73 of file list_test.c.

74 {
75 struct list_test *entry;
76 size_t num_entries = 0;
77
78 /* Determine size of list */
79 list_for_each_entry ( entry, list, list )
81
82 {
83 char found[ num_entries + 1 ];
84 char found_rev[ num_entries + 1 ];
85 char *tmp;
86
87 /* Build up list content string */
88 tmp = found;
89 list_for_each_entry ( entry, list, list )
90 *(tmp++) = entry->label;
91 *tmp = '\0';
92
93 /* Sanity check reversed list */
94 tmp = &found_rev[ sizeof ( found_rev ) - 1 ];
95 *tmp = '\0';
97 *(--tmp) = entry->label;
98 if ( strcmp ( found, found_rev ) != 0 ) {
99 printf ( "FAILURE: list reversal mismatch (forward "
100 "\"%s\", reverse \"%s\")\n",
101 found, found_rev );
102 return 0;
103 }
104
105 /* Compare against expected content */
106 if ( strcmp ( found, expected ) == 0 ) {
107 return 1;
108 } else {
109 printf ( "FAILURE: expected \"%s\", got \"%s\"\n",
110 expected, found );
111 return 0;
112 }
113 }
114}
__be32 num_entries
Definition CIB_PRM.h:3
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_for_each_entry_reverse(pos, head, member)
Iterate over entries in a list in reverse order.
Definition list.h:445
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
struct list_head list
List element.
Definition list_test.c:44
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition vsprintf.c:465

References list_test::label, list_test::list, list_for_each_entry, list_for_each_entry_reverse, num_entries, printf(), strcmp(), and tmp.

◆ list_test_exec()

void list_test_exec ( void )
static

Perform list self-test.

Definition at line 165 of file list_test.c.

165 {
166 struct list_head *list = &test_list;
167 struct list_head target_list;
168 struct list_head *target = &target_list;
169 struct list_head *raw_pos;
170 struct list_test *pos;
171 struct list_test *tmp;
172
173 /* Test initialiser and list_empty() */
174 ok ( list_empty ( list ) );
175 list_contents_ok ( list, "" );
176
177 /* Test list_add(), list_add_tail() and list_del() */
179 list_contents_ok ( list, "" );
180 list_add ( &list_tests[4].list, list ); /* prepend */
181 list_contents_ok ( list, "4" );
182 list_add ( &list_tests[2].list, list ); /* prepend */
183 list_contents_ok ( list, "24" );
184 list_add_tail ( &list_tests[7].list, list ); /* append */
185 list_contents_ok ( list, "247" );
186 list_add ( &list_tests[1].list, &list_tests[4].list ); /* after */
187 list_contents_ok ( list, "2417" );
188 list_add_tail ( &list_tests[8].list, &list_tests[7].list ); /* before */
189 list_contents_ok ( list, "24187" );
190 list_del ( &list_tests[4].list ); /* delete middle */
191 list_contents_ok ( list, "2187" );
192 list_del ( &list_tests[2].list ); /* delete first */
193 list_contents_ok ( list, "187" );
194 list_del ( &list_tests[7].list ); /* delete last */
195 list_contents_ok ( list, "18" );
196 list_del ( &list_tests[1].list ); /* delete all */
197 list_del ( &list_tests[8].list ); /* delete all */
198 list_contents_ok ( list, "" );
199 ok ( list_empty ( list ) );
200
201 /* Test list_is_singular() */
203 ok ( ! list_is_singular ( list ) );
204 list_add ( &list_tests[1].list, list );
205 ok ( list_is_singular ( list ) );
206 list_add ( &list_tests[3].list, list );
207 ok ( ! list_is_singular ( list ) );
208 list_del ( &list_tests[1].list );
209 ok ( list_is_singular ( list ) );
210
211 /* Test list_is_last() */
214 ok ( list_is_last ( &list_tests[6].list, list ) );
216 ok ( list_is_last ( &list_tests[4].list, list ) );
217 ok ( ! list_is_last ( &list_tests[6].list, list ) );
218
219 /* Test list_cut_position() - empty list */
221 INIT_LIST_HEAD ( target );
222 list_cut_position ( target, list, list );
223 list_contents_ok ( list, "" );
224 list_contents_ok ( target, "" );
225
226 /* Test list_cut_position() - singular list, move nothing */
228 INIT_LIST_HEAD ( target );
230 list_cut_position ( target, list, list );
231 list_contents_ok ( list, "4" );
232 list_contents_ok ( target, "" );
233
234 /* Test list_cut_position() - singular list, move singular entry */
236 INIT_LIST_HEAD ( target );
238 list_cut_position ( target, list, &list_tests[9].list );
239 list_contents_ok ( list, "" );
240 list_contents_ok ( target, "9" );
241
242 /* Test list_cut_position() - multi-entry list, move nothing */
247 INIT_LIST_HEAD ( target );
248 list_cut_position ( target, list, list );
249 list_contents_ok ( list, "327" );
250 list_contents_ok ( target, "" );
251
252 /* Test list_cut_position() - multi-entry list, move some */
254 INIT_LIST_HEAD ( target );
260 list_cut_position ( target, list, &list_tests[0].list );
261 list_contents_ok ( list, "932" );
262 list_contents_ok ( target, "80" );
263
264 /* Test list_cut_position() - multi-entry list, move everything */
266 INIT_LIST_HEAD ( target );
272 list_cut_position ( target, list, &list_tests[1].list );
273 list_contents_ok ( list, "" );
274 list_contents_ok ( target, "35471" );
275
276 /* Test list_splice() - empty list */
278 INIT_LIST_HEAD ( target );
279 list_splice ( list, target );
280 list_contents_ok ( list, "" );
281 list_contents_ok ( target, "" );
282
283 /* Test list_splice() - both lists empty */
285 INIT_LIST_HEAD ( target );
286 list_splice ( list, target );
287 list_contents_ok ( target, "" );
288
289 /* Test list_splice() - source list empty */
291 INIT_LIST_HEAD ( target );
292 list_add_tail ( &list_tests[1].list, target );
293 list_add_tail ( &list_tests[3].list, target );
295 list_contents_ok ( target, "13" );
296
297 /* Test list_splice() - destination list empty */
299 INIT_LIST_HEAD ( target );
303 list_splice ( list, target );
304 list_contents_ok ( target, "652" );
305
306 /* Test list_splice() - both lists non-empty */
308 INIT_LIST_HEAD ( target );
312 list_add_tail ( &list_tests[1].list, target );
313 list_add_tail ( &list_tests[9].list, target );
315 list_contents_ok ( target, "18459" );
316
317 /* Test list_splice_tail() - both lists empty */
319 INIT_LIST_HEAD ( target );
320 list_splice_tail ( list, target );
321 list_contents_ok ( target, "" );
322
323 /* Test list_splice_tail() - source list empty */
325 INIT_LIST_HEAD ( target );
326 list_add_tail ( &list_tests[5].list, target );
328 list_contents_ok ( target, "5" );
329
330 /* Test list_splice_tail() - destination list empty */
332 INIT_LIST_HEAD ( target );
336 list_splice_tail ( list, target );
337 list_contents_ok ( target, "210" );
338
339 /* Test list_splice_tail() - both lists non-empty */
341 INIT_LIST_HEAD ( target );
345 list_add_tail ( &list_tests[2].list, target );
346 list_add_tail ( &list_tests[4].list, target );
348 list_contents_ok ( target, "95724" );
349
350 /* Test list_splice_init() */
352 INIT_LIST_HEAD ( target );
354 list_add_tail ( &list_tests[1].list, target );
355 list_splice_init ( list, target );
356 ok ( list_empty ( list ) );
357 list_contents_ok ( list, "" );
358 list_contents_ok ( target, "41" );
359
360 /* Test list_splice_tail_init() */
362 INIT_LIST_HEAD ( target );
365 list_add_tail ( &list_tests[5].list, target );
367 ok ( list_empty ( list ) );
368 list_contents_ok ( list, "" );
369 list_contents_ok ( target, "325" );
370
371 /* Test list_entry() */
372 INIT_LIST_HEAD ( &list_tests[3].list ); // for list_check()
373 ok ( list_entry ( &list_tests[3].list, struct list_test, list )
374 == &list_tests[3] );
375
376 /* Test list_first_entry() and list_last_entry() */
381 ok ( list_first_entry ( list, struct list_test, list )
382 == &list_tests[9] );
383 ok ( list_last_entry ( list, struct list_test, list )
384 == &list_tests[6] );
385 list_del ( &list_tests[9].list );
386 ok ( list_first_entry ( list, struct list_test, list )
387 == &list_tests[5] );
388 ok ( list_last_entry ( list, struct list_test, list )
389 == &list_tests[6] );
390 list_del ( &list_tests[6].list );
391 ok ( list_first_entry ( list, struct list_test, list )
392 == &list_tests[5] );
393 ok ( list_last_entry ( list, struct list_test, list )
394 == &list_tests[5] );
395 list_del ( &list_tests[5].list );
396 ok ( list_first_entry ( list, struct list_test, list ) == NULL );
397 ok ( list_last_entry ( list, struct list_test, list ) == NULL );
398
399 /* Test list_next_entry() and list_prev_entry() */
405 ok ( list_prev_entry ( &list_tests[5], list, list ) == NULL );
406 ok ( list_next_entry ( &list_tests[5], list, list ) == &list_tests[3] );
407 ok ( list_prev_entry ( &list_tests[3], list, list ) == &list_tests[5] );
408 ok ( list_next_entry ( &list_tests[3], list, list ) == &list_tests[1] );
409 ok ( list_prev_entry ( &list_tests[1], list, list ) == &list_tests[3] );
410 ok ( list_next_entry ( &list_tests[1], list, list ) == &list_tests[7] );
411 ok ( list_prev_entry ( &list_tests[7], list, list ) == &list_tests[1] );
412 ok ( list_next_entry ( &list_tests[7], list, list ) == NULL );
413 list_del ( &list_tests[7].list );
414 ok ( list_prev_entry ( &list_tests[1], list, list ) == &list_tests[3] );
415 ok ( list_next_entry ( &list_tests[1], list, list ) == NULL );
416 list_del ( &list_tests[3].list );
417 ok ( list_prev_entry ( &list_tests[5], list, list ) == NULL );
418 ok ( list_next_entry ( &list_tests[5], list, list ) == &list_tests[1] );
419 ok ( list_prev_entry ( &list_tests[1], list, list ) == &list_tests[5] );
420 ok ( list_next_entry ( &list_tests[1], list, list ) == NULL );
421
422 /* Test list_is_first_entry() and list_is_last_entry() */
429 ok ( ! list_is_first_entry ( &list_tests[8], list, list ) );
430 ok ( ! list_is_first_entry ( &list_tests[3], list, list ) );
431 ok ( ! list_is_first_entry ( &list_tests[6], list, list ) );
432 ok ( ! list_is_last_entry ( &list_tests[4], list, list ) );
433 ok ( ! list_is_last_entry ( &list_tests[8], list, list ) );
434 ok ( ! list_is_last_entry ( &list_tests[3], list, list ) );
436 list_del ( &list_tests[4].list );
438 list_del ( &list_tests[8].list );
439 list_del ( &list_tests[6].list );
442
443 /* Test list_is_head_entry() */
448 ok ( list_is_head_entry ( list_entry ( list, typeof ( *pos ), list ),
449 list, list ) );
450 ok ( ! list_is_head_entry ( &list_tests[1], list, list ) );
451 ok ( ! list_is_head_entry ( &list_tests[6], list, list ) );
452 ok ( ! list_is_head_entry ( &list_tests[8], list, list ) );
453 list_for_each_entry ( pos, list, list ) {
454 ok ( list_contains_entry ( pos, list, list ) );
455 ok ( ! list_is_head_entry ( pos, list, list ) );
456 }
457 ok ( list_is_head_entry ( pos, list, list ) );
458
459 /* Test list_for_each() */
464 list_iterate_ok ( list_for_each, "673", raw_pos, list );
465
466 /* Test list_for_each_entry() and list_for_each_entry_reverse() */
473 pos, list, list );
475 pos, list, list );
476
477 /* Test list_for_each_entry_safe() */
482 {
483 char *expected = "241";
485 list_contents_ok ( list, expected );
486 list_del ( &pos->list );
487 expected++;
488 list_contents_ok ( list, expected );
489 }
490 }
491 ok ( list_empty ( list ) );
492
493 /* Test list_for_each_entry_continue() and
494 * list_for_each_entry_continue_reverse()
495 */
502 pos = &list_tests[7];
504 pos, list, list );
505 ok ( pos == list_entry ( list, struct list_test, list ) );
507 pos, list, list );
508 pos = &list_tests[3];
510 pos, list, list );
511 pos = &list_tests[2];
513 pos, list, list );
514 ok ( pos == list_entry ( list, struct list_test, list ) );
516 pos, list, list );
517 pos = &list_tests[4];
519 pos, list, list );
520
521 /* Test list_for_each_entry_safe_continue() */
528 {
529 char *expecteds[] = { "94257", "9457", "947", "94" };
530 char **expected = expecteds;
531 pos = &list_tests[4];
533 list_contents_ok ( list, *expected );
534 list_del ( &pos->list );
535 expected++;
536 list_contents_ok ( list, *expected );
537 }
538 }
539 list_contents_ok ( list, "94" );
540 {
541 char *expecteds[] = { "94", "4", "" };
542 char **expected = expecteds;
543 ok ( pos == list_entry ( list, struct list_test, list ) );
545 list_contents_ok ( list, *expected );
546 list_del ( &pos->list );
547 expected++;
548 list_contents_ok ( list, *expected );
549 }
550 }
551 ok ( list_empty ( list ) );
552
553 /* Test list_contains() and list_contains_entry() */
556 list_add ( &list_tests[8].list, list );
557 list_add ( &list_tests[5].list, list );
558 ok ( list_contains ( &list_tests[8].list, list ) );
560 ok ( list_contains ( &list_tests[5].list, list ) );
562 ok ( ! list_contains ( &list_tests[3].list, list ) );
563 ok ( ! list_contains_entry ( &list_tests[3], list, list ) );
564
565 /* Test list_check_contains_entry() */
567 list_add ( &list_tests[4].list, list );
568 list_add ( &list_tests[0].list, list );
569 list_add ( &list_tests[3].list, list );
573}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
#define list_is_last_entry(entry, head, member)
Test if entry is last in a list.
Definition list.h:399
#define list_cut_position(new, list, entry)
Cut a list into two.
Definition list.h:186
#define list_contains_entry(entry, head, member)
Test if list contains a specified entry.
Definition list.h:540
#define list_for_each_entry_continue_reverse(pos, head, member)
Iterate over entries in a list in reverse, starting after current position.
Definition list.h:487
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334
#define list_for_each_entry_safe_continue(pos, tmp, head, member)
Iterate over subsequent entries in a list, safe against deletion.
Definition list.h:501
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition list.h:347
#define list_contains(entry, head)
Test if list contains a specified entry.
Definition list.h:516
#define list_entry(list, type, member)
Get the container of a list entry.
Definition list.h:322
#define list_splice(list, entry)
Move all entries from one list into another list.
Definition list.h:221
#define list_splice_tail(list, entry)
Move all entries from one list into another list.
Definition list.h:251
#define list_is_head_entry(entry, head, member)
Test if entry is the list head.
Definition list.h:410
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_prev_entry(pos, head, member)
Get the container of the previous entry in a list.
Definition list.h:374
#define list_next_entry(pos, head, member)
Get the container of the next entry in a list.
Definition list.h:360
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_for_each_entry_continue(pos, head, member)
Iterate over entries in a list, starting after current position.
Definition list.h:474
#define list_splice_init(list, entry)
Move all entries from one list into another list and reinitialise empty list.
Definition list.h:279
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_for_each(pos, head)
Iterate over a list.
Definition list.h:419
#define list_is_first_entry(entry, head, member)
Test if entry is first in a list.
Definition list.h:388
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
#define list_is_singular(list)
Test whether a list has just one entry.
Definition list.h:150
#define list_check_contains_entry(entry, head, member)
Check list contains a specified entry.
Definition list.h:550
#define list_is_last(list, head)
Test whether an entry is the last entry in list.
Definition list.h:164
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
#define list_splice_tail_init(list, entry)
Move all entries from one list into another list and reinitialise empty list.
Definition list.h:300
static struct list_test list_tests[]
List test elements.
Definition list_test.c:50
#define list_contents_ok(list, expected)
Report list test result.
Definition list_test.c:122
#define list_iterate_ok(macro, expected, pos,...)
Report list iteration test result.
Definition list_test.c:134
#define list_iterate_entry_ok(macro, expected, pos,...)
Report list entry iteration test result.
Definition list_test.c:153
A doubly-linked list entry (or list head)
Definition list.h:19
#define ok(success)
Definition test.h:46

References INIT_LIST_HEAD, list_test::list, list_add, list_add_tail, list_check_contains_entry, list_contains, list_contains_entry, list_contents_ok, list_cut_position, list_del, list_empty, list_entry, list_first_entry, list_for_each, list_for_each_entry, list_for_each_entry_continue, list_for_each_entry_continue_reverse, list_for_each_entry_reverse, list_for_each_entry_safe, list_for_each_entry_safe_continue, list_is_first_entry, list_is_head_entry, list_is_last, list_is_last_entry, list_is_singular, list_iterate_entry_ok, list_iterate_ok, list_last_entry, list_next_entry, list_prev_entry, list_splice, list_splice_init, list_splice_tail, list_splice_tail_init, list_tests, NULL, ok, tmp, and typeof().

Variable Documentation

◆ list_tests

struct list_test list_tests[]
static
Initial value:
= {
{ .label = '0' },
{ .label = '1' },
{ .label = '2' },
{ .label = '3' },
{ .label = '4' },
{ .label = '5' },
{ .label = '6' },
{ .label = '7' },
{ .label = '8' },
{ .label = '9' },
}

List test elements.

Definition at line 50 of file list_test.c.

50 {
51 { .label = '0' },
52 { .label = '1' },
53 { .label = '2' },
54 { .label = '3' },
55 { .label = '4' },
56 { .label = '5' },
57 { .label = '6' },
58 { .label = '7' },
59 { .label = '8' },
60 { .label = '9' },
61};

Referenced by list_test_exec().

◆ __self_test

struct self_test list_test __self_test
Initial value:
= {
.name = "list",
.exec = list_test_exec,
}
static void list_test_exec(void)
Perform list self-test.
Definition list_test.c:165

List self-test.

Definition at line 576 of file list_test.c.

576 {
577 .name = "list",
578 .exec = list_test_exec,
579};