1 /* test.c - Infrastructure for unit tests.
2 * Copyright (C) 2015 g10 Code GmbH
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 /* A unit test consists of one or more tests. Tests can be broken
28 into groups and each group can consist of one or more tests. */
30 /* The number of test groups. */
31 static int test_groups;
32 /* The current test group. */
33 static char *test_group;
35 /* Whether there was already a failure in the current test group. */
36 static int current_test_group_failed;
37 /* The number of test groups with a failure. */
38 static int test_groups_failed;
40 /* The total number of tests. */
42 /* The total number of tests that failed. */
43 static int tests_failed;
45 /* Flag to request verbose diagnostics. This is set if the envvar
46 "verbose" exists and is not the empty string. */
49 #define TEST_GROUP(description) \
51 test_group = (description); \
53 current_test_group_failed = 0; \
56 #define STRINGIFY2(x) #x
57 #define STRINGIFY(x) STRINGIFY2(x)
60 #define TEST(description, test, expected) \
63 int expected_result; \
68 printf ("%d. Checking %s...", \
69 tests, (description) ?: ""); \
72 test_result = (test); \
73 expected_result = (expected); \
75 if (test_result == expected_result) \
81 printf (" failed.\n"); \
82 printf (" %s == %s failed.\n", \
84 STRINGIFY(expected)); \
86 if (! current_test_group_failed) \
88 current_test_group_failed = 1; \
89 test_groups_failed ++; \
94 /* Test that a condition evaluates to true. */
95 #define TEST_P(description, test) \
96 TEST(description, !!(test), 1)
98 /* Like CHECK, but if the test fails, abort the program. */
99 #define ASSERT(description, test, expected) \
101 int tests_failed_pre = tests_failed; \
102 CHECK(description, test, expected); \
103 if (tests_failed_pre != tests_failed) \
107 /* Call this if something went wrong. */
108 #define ABORT(message) \
110 printf ("aborting..."); \
112 printf (" %s\n", (message)); \
117 /* You need to fill this function in. */
118 static void do_test (int argc, char *argv[]);
121 /* Print stats and call the real exit. If FORCE is set use
122 EXIT_FAILURE even if no test has failed. */
124 exit_tests (int force)
126 if (tests_failed == 0)
128 printf ("All %d tests passed.\n", tests);
133 printf ("%d of %d tests failed",
134 tests_failed, tests);
136 printf (" (%d of %d groups)",
137 test_groups_failed, test_groups);
144 /* Prepend FNAME with the srcdir environment variable's value and
145 return a malloced filename. Caller must release the returned
146 string using test_free. */
148 prepend_srcdir (const char *fname)
150 static const char *srcdir;
153 if (!srcdir && !(srcdir = getenv ("srcdir")))
156 result = malloc (strlen (srcdir) + 1 + strlen (fname) + 1);
157 strcpy (result, srcdir);
158 strcat (result, "/");
159 strcat (result, fname);
173 main (int argc, char *argv[])
179 s = getenv ("verbose");
183 do_test (argc, argv);
186 return !!tests_failed;