Ver código fonte

[test] Add a basic infrastructure for running self-tests

This self-test mechanism is inspired by Perl's Test::Simple and
similar modules.  The aim is to encourage the use of self-tests by
making it as easy as possible to create self-test code

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 anos atrás
pai
commit
eac134f8dc
2 arquivos alterados com 184 adições e 0 exclusões
  1. 45
    0
      src/include/ipxe/test.h
  2. 139
    0
      src/tests/test.c

+ 45
- 0
src/include/ipxe/test.h Ver arquivo

@@ -0,0 +1,45 @@
1
+#ifndef _IPXE_TEST_H
2
+#define _IPXE_TEST_H
3
+
4
+FILE_LICENCE ( GPL2_OR_LATER );
5
+
6
+/** @file
7
+ *
8
+ * Self-test infrastructure
9
+ *
10
+ */
11
+
12
+#include <ipxe/tables.h>
13
+
14
+/** A self-test set */
15
+struct self_test {
16
+	/** Test set name */
17
+	const char *name;
18
+	/** Run self-tests */
19
+	void ( * exec ) ( void );
20
+	/** Number of tests run */
21
+	unsigned int total;
22
+	/** Number of test failures */
23
+	unsigned int failures;
24
+	/** Number of assertion failures */
25
+	unsigned int assertion_failures;
26
+};
27
+
28
+/** Self-test table */
29
+#define SELF_TESTS __table ( struct self_test, "self_tests" )
30
+
31
+/** Declare a self-test */
32
+#define __self_test __table_entry ( SELF_TESTS, 01 )
33
+
34
+extern void test_ok ( int success, const char *file, unsigned int line );
35
+
36
+/**
37
+ * Report test result
38
+ *
39
+ * @v success		Test succeeded
40
+ */
41
+#define ok( success ) do {				\
42
+	test_ok ( (success), __FILE__, __LINE__ );	\
43
+	} while ( 0 )
44
+
45
+#endif /* _IPXE_TEST_H */

+ 139
- 0
src/tests/test.c Ver arquivo

@@ -0,0 +1,139 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+/** @file
22
+ *
23
+ * Self-test infrastructure
24
+ *
25
+ */
26
+
27
+/* Forcibly enable assertions */
28
+#undef NDEBUG
29
+
30
+#include <stddef.h>
31
+#include <stdio.h>
32
+#include <assert.h>
33
+#include <ipxe/test.h>
34
+#include <ipxe/init.h>
35
+
36
+/** Current self-test set */
37
+static struct self_test *current_tests;
38
+
39
+/**
40
+ * Report test result
41
+ *
42
+ * @v success		Test succeeded
43
+ * @v file		Test code file
44
+ * @v line		Test code line
45
+ */
46
+void test_ok ( int success, const char *file, unsigned int line ) {
47
+
48
+	/* Sanity check */
49
+	assert ( current_tests != NULL );
50
+
51
+	/* Increment test counter */
52
+	current_tests->total++;
53
+
54
+	/* Report failure if applicable */
55
+	if ( ! success ) {
56
+		current_tests->failures++;
57
+		printf ( "FAILURE: \"%s\" test failed at %s line %d\n",
58
+			 current_tests->name, file, line );
59
+	}
60
+}
61
+
62
+/**
63
+ * Run self-test set
64
+ *
65
+ */
66
+static void run_tests ( struct self_test *tests ) {
67
+	unsigned int old_assertion_failures = assertion_failures;
68
+
69
+	/* Sanity check */
70
+	assert ( current_tests == NULL );
71
+
72
+	/* Record current test set */
73
+	current_tests = tests;
74
+
75
+	/* Run tests */
76
+	tests->exec();
77
+
78
+	/* Clear current test set */
79
+	current_tests = NULL;
80
+
81
+	/* Record number of assertion failures */
82
+	tests->assertion_failures =
83
+		( assertion_failures - old_assertion_failures );
84
+
85
+	/* Print test set summary */
86
+	if ( tests->failures || tests->assertion_failures ) {
87
+		printf ( "FAILURE: \"%s\" %d of %d tests failed",
88
+			 tests->name, tests->failures, tests->total );
89
+		if ( tests->assertion_failures ) {
90
+			printf ( " with %d assertion failures",
91
+				 tests->assertion_failures );
92
+		}
93
+		printf ( "\n" );
94
+	} else {
95
+		printf ( "OK: \"%s\" %d tests passed\n",
96
+			 tests->name, tests->total );
97
+	}
98
+}
99
+
100
+/**
101
+ * Run all self-tests
102
+ *
103
+ */
104
+static void test_init ( void ) {
105
+	struct self_test *tests;
106
+	unsigned int failures = 0;
107
+	unsigned int assertions = 0;
108
+	unsigned int total = 0;
109
+
110
+	/* Run all compiled-in self-tests */
111
+	printf ( "Starting self-tests\n" );
112
+	for_each_table_entry ( tests, SELF_TESTS )
113
+		run_tests ( tests );
114
+
115
+	/* Print overall summary */
116
+	for_each_table_entry ( tests, SELF_TESTS ) {
117
+		total += tests->total;
118
+		failures += tests->failures;
119
+		assertions += tests->assertion_failures;
120
+	}
121
+	if ( failures || assertions ) {
122
+		printf ( "FAILURE: %d of %d tests failed",
123
+			 failures, total );
124
+		if ( assertions ) {
125
+			printf ( " with %d assertion failures", assertions );
126
+		}
127
+		printf ( "\n" );
128
+	} else {
129
+		printf ( "OK: all %d tests passed\n", total );
130
+	}
131
+
132
+	/* Lock system */
133
+	while ( 1 ) {}
134
+}
135
+
136
+/** Self-test initialisation function */
137
+struct init_fn test_init_fn __init_fn ( INIT_NORMAL ) = {
138
+	.initialise = test_init,
139
+};

Carregando…
Cancelar
Salvar