iPXE
test.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 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  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Self-test infrastructure
29  *
30  */
31 
32 /* Forcibly enable assertions */
33 #undef NDEBUG
34 
35 #include <stddef.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <errno.h>
39 #include <assert.h>
40 #include <ipxe/test.h>
41 #include <ipxe/init.h>
42 #include <ipxe/image.h>
43 #include <usr/profstat.h>
44 
45 /** Current self-test set */
46 static struct self_test *current_tests;
47 
48 /**
49  * Report test result
50  *
51  * @v success Test succeeded
52  * @v file Test code file
53  * @v line Test code line
54  * @v test Test code
55  */
56 void test_ok ( int success, const char *file, unsigned int line,
57  const char *test ) {
58 
59  /* Sanity check */
60  assert ( current_tests != NULL );
61 
62  /* Increment test counter */
64 
65  /* Report failure if applicable */
66  if ( ! success ) {
68  printf ( "FAILURE: \"%s\" test failed at %s line %d: ( %s )\n",
69  current_tests->name, file, line, test );
70  }
71 }
72 
73 /**
74  * Run self-test set
75  *
76  */
77 static void run_tests ( struct self_test *tests ) {
78  unsigned int old_assertion_failures = assertion_failures;
79 
80  /* Sanity check */
81  assert ( current_tests == NULL );
82 
83  /* Record current test set */
84  current_tests = tests;
85 
86  /* Run tests */
87  tests->exec();
88 
89  /* Clear current test set */
91 
92  /* Record number of assertion failures */
93  tests->assertion_failures =
94  ( assertion_failures - old_assertion_failures );
95 
96  /* Print test set summary */
97  if ( tests->failures || tests->assertion_failures ) {
98  printf ( "FAILURE: \"%s\" %d of %d tests failed",
99  tests->name, tests->failures, tests->total );
100  if ( tests->assertion_failures ) {
101  printf ( " with %d assertion failures",
102  tests->assertion_failures );
103  }
104  printf ( "\n" );
105  } else {
106  printf ( "OK: \"%s\" %d tests passed\n",
107  tests->name, tests->total );
108  }
109 }
110 
111 /**
112  * Run all self-tests
113  *
114  * @ret rc Return status code
115  */
116 static int run_all_tests ( void ) {
117  struct self_test *tests;
118  unsigned int failures = 0;
119  unsigned int assertions = 0;
120  unsigned int total = 0;
121 
122  /* Run all compiled-in self-tests */
123  printf ( "Starting %s self-tests\n", _S2 ( ARCH ) );
125  run_tests ( tests );
126 
127  /* Print overall summary */
128  for_each_table_entry ( tests, SELF_TESTS ) {
129  total += tests->total;
130  failures += tests->failures;
131  assertions += tests->assertion_failures;
132  }
133  if ( failures || assertions ) {
134  printf ( "FAILURE: %d of %d tests failed",
135  failures, total );
136  if ( assertions ) {
137  printf ( " with %d assertion failures", assertions );
138  }
139  printf ( "\n" );
140  return -EINPROGRESS;
141  } else {
142  printf ( "OK: all %d tests passed\n", total );
143  profstat();
144  return 0;
145  }
146 }
147 
148 static int test_image_probe ( struct image *image __unused ) {
149  return -ENOTTY;
150 }
151 
152 static int test_image_exec ( struct image *image __unused ) {
153  return run_all_tests();
154 }
155 
156 static struct image_type test_image_type = {
157  .name = "self-tests",
158  .probe = test_image_probe,
159  .exec = test_image_exec,
160 };
161 
162 static struct image test_image = {
163  .refcnt = REF_INIT ( ref_no_free ),
164  .name = "<TESTS>",
165  .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ),
166  .type = &test_image_type,
167 };
168 
169 static void test_init ( void ) {
170  int rc;
171 
172  /* Register self-tests image */
173  if ( ( rc = register_image ( &test_image ) ) != 0 ) {
174  DBG ( "Could not register self-test image: %s\n",
175  strerror ( rc ) );
176  /* No way to report failure */
177  return;
178  }
179 }
180 
181 /** Self-test initialisation function */
182 struct init_fn test_init_fn __init_fn ( INIT_EARLY ) = {
183  .name = "test",
184  .initialise = test_init,
185 };
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
unsigned int failures
Number of test failures.
Definition: test.h:23
unsigned int total
Number of tests run.
Definition: test.h:21
#define _S2(x)
Stringify expanded argument.
Definition: compiler.h:53
Error codes.
static int run_all_tests(void)
Run all self-tests.
Definition: test.c:116
#define INIT_EARLY
Early initialisation.
Definition: init.h:29
uint32_t type
Operating system type.
Definition: ena.h:12
An executable image type.
Definition: image.h:94
void(* exec)(void)
Run self-tests.
Definition: test.h:19
Self-test infrastructure.
const char * name
Test set name.
Definition: test.h:17
An executable image.
Definition: image.h:23
A self-test set.
Definition: test.h:15
unsigned int assertion_failures
Number of assertion failures triggered.
Definition: assert.c:35
char * name
Name of this image type.
Definition: image.h:96
struct init_fn test_init_fn __init_fn(INIT_EARLY)
Self-test initialisation function.
void profstat(void)
Print profiling statistics.
Definition: profstat.c:40
An initialisation function.
Definition: init.h:14
#define IMAGE_STATIC
Image is statically allocated.
Definition: image.h:88
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
Executable images.
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
const char * name
Definition: init.h:15
static void test_init(void)
Definition: test.c:169
static struct image_type test_image_type
Definition: test.c:156
#define EINPROGRESS
Operation in progress.
Definition: errno.h:418
int register_image(struct image *image)
Register executable image.
Definition: image.c:314
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define SELF_TESTS
Self-test table.
Definition: test.h:29
static int test_image_exec(struct image *image __unused)
Definition: test.c:152
unsigned int assertion_failures
Number of assertion failures.
Definition: test.h:25
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
void test_ok(int success, const char *file, unsigned int line, const char *test)
Report test result.
Definition: test.c:56
Profiling.
static void run_tests(struct self_test *tests)
Run self-test set.
Definition: test.c:77
static int test_image_probe(struct image *image __unused)
Definition: test.c:148
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
#define IMAGE_STATIC_NAME
Image name is statically allocated.
Definition: image.h:91
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition: refcnt.h:77
static struct self_test * current_tests
Current self-test set.
Definition: test.c:46
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static struct image test_image
Definition: test.c:162
void ref_no_free(struct refcnt *refcnt __unused)
Do not free reference-counted object.
Definition: refcnt.c:101
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
static int test
Definition: epic100.c:73
struct refcnt refcnt
Reference count.
Definition: image.h:25