Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / tests / test.c
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
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 /** @file
23  *
24  * Self-test infrastructure
25  *
26  */
27
28 /* Forcibly enable assertions */
29 #undef NDEBUG
30
31 #include <stddef.h>
32 #include <stdio.h>
33 #include <errno.h>
34 #include <assert.h>
35 #include <ipxe/test.h>
36 #include <ipxe/init.h>
37 #include <ipxe/image.h>
38 #include <usr/profstat.h>
39
40 /** Current self-test set */
41 static struct self_test *current_tests;
42
43 /**
44  * Report test result
45  *
46  * @v success           Test succeeded
47  * @v file              Test code file
48  * @v line              Test code line
49  * @v test              Test code
50  */
51 void test_ok ( int success, const char *file, unsigned int line,
52                const char *test ) {
53
54         /* Sanity check */
55         assert ( current_tests != NULL );
56
57         /* Increment test counter */
58         current_tests->total++;
59
60         /* Report failure if applicable */
61         if ( ! success ) {
62                 current_tests->failures++;
63                 printf ( "FAILURE: \"%s\" test failed at %s line %d: ( %s )\n",
64                          current_tests->name, file, line, test );
65         }
66 }
67
68 /**
69  * Run self-test set
70  *
71  */
72 static void run_tests ( struct self_test *tests ) {
73         unsigned int old_assertion_failures = assertion_failures;
74
75         /* Sanity check */
76         assert ( current_tests == NULL );
77
78         /* Record current test set */
79         current_tests = tests;
80
81         /* Run tests */
82         tests->exec();
83
84         /* Clear current test set */
85         current_tests = NULL;
86
87         /* Record number of assertion failures */
88         tests->assertion_failures =
89                 ( assertion_failures - old_assertion_failures );
90
91         /* Print test set summary */
92         if ( tests->failures || tests->assertion_failures ) {
93                 printf ( "FAILURE: \"%s\" %d of %d tests failed",
94                          tests->name, tests->failures, tests->total );
95                 if ( tests->assertion_failures ) {
96                         printf ( " with %d assertion failures",
97                                  tests->assertion_failures );
98                 }
99                 printf ( "\n" );
100         } else {
101                 printf ( "OK: \"%s\" %d tests passed\n",
102                          tests->name, tests->total );
103         }
104 }
105
106 /**
107  * Run all self-tests
108  *
109  * @ret rc              Return status code
110  */
111 static int run_all_tests ( void ) {
112         struct self_test *tests;
113         unsigned int failures = 0;
114         unsigned int assertions = 0;
115         unsigned int total = 0;
116
117         /* Run all compiled-in self-tests */
118         printf ( "Starting self-tests\n" );
119         for_each_table_entry ( tests, SELF_TESTS )
120                 run_tests ( tests );
121
122         /* Print overall summary */
123         for_each_table_entry ( tests, SELF_TESTS ) {
124                 total += tests->total;
125                 failures += tests->failures;
126                 assertions += tests->assertion_failures;
127         }
128         if ( failures || assertions ) {
129                 printf ( "FAILURE: %d of %d tests failed",
130                          failures, total );
131                 if ( assertions ) {
132                         printf ( " with %d assertion failures", assertions );
133                 }
134                 printf ( "\n" );
135                 return -EINPROGRESS;
136         } else {
137                 printf ( "OK: all %d tests passed\n", total );
138                 profstat();
139                 return 0;
140         }
141 }
142
143 static int test_image_probe ( struct image *image __unused ) {
144         return -ENOTTY;
145 }
146
147 static int test_image_exec ( struct image *image __unused ) {
148         return run_all_tests();
149 }
150
151 static struct image_type test_image_type = {
152         .name = "self-tests",
153         .probe = test_image_probe,
154         .exec = test_image_exec,
155 };
156
157 static struct image test_image = {
158         .refcnt = REF_INIT ( ref_no_free ),
159         .name = "<TESTS>",
160         .type = &test_image_type,
161 };
162
163 static void test_init ( void ) {
164         int rc;
165
166         /* Register self-tests image */
167         if ( ( rc = register_image ( &test_image ) ) != 0 ) {
168                 DBG ( "Could not register self-test image: %s\n",
169                       strerror ( rc ) );
170                 /* No way to report failure */
171                 return;
172         }
173 }
174
175 /** Self-test initialisation function */
176 struct init_fn test_init_fn __init_fn ( INIT_EARLY ) = {
177         .initialise = test_init,
178 };