g10: Add test for keydb as well as new testing infrastructure.
[gnupg.git] / g10 / test.c
1 /* test.c - Infrastructure for unit tests.
2  * Copyright (C) 2015 g10 Code GmbH
3  *
4  * This file is part of GnuPG.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include <config.h>
21 #include "gpg.h"
22
23 /* A unit test consists of one or more tests.  Tests can be broken
24    into groups and each group can consist of one or more tests.  */
25
26 /* The number of test groups.  */
27 static int test_groups;
28 /* The current test group.  */
29 static char *test_group;
30
31 /* Whether there was already a failure in the current test group.  */
32 static int current_test_group_failed;
33 /* The number of test groups with a failure.  */
34 static int test_groups_failed;
35
36 /* The total number of tests.  */
37 static int tests;
38 /* The total number of tests that failed.  */
39 static int tests_failed;
40
41 #define TEST_GROUP(description)      \
42   do {                               \
43     test_group = (description);      \
44     test_groups ++;                  \
45     current_test_group_failed = 0;   \
46   } while (0)
47
48 #define STRINGIFY2(x) #x
49 #define STRINGIFY(x) STRINGIFY2(x)
50
51 /* Execute a test.  */
52 #define TEST(description, test, expected)       \
53   do {                                          \
54     int test_result;                            \
55     int expected_result;                        \
56                                                 \
57     tests ++;                                   \
58                                                 \
59     printf ("%d. Checking %s...",               \
60             tests, (description) ?: "");        \
61     fflush (stdout);                            \
62                                                 \
63     test_result = (test);                       \
64     expected_result = (expected);               \
65                                                 \
66     if (test_result == expected_result)         \
67       {                                         \
68         printf (" ok.\n");                      \
69       }                                         \
70     else                                        \
71       {                                         \
72         printf (" failed.\n");                  \
73         printf ("  %s == %s failed.\n",         \
74                 STRINGIFY(test),                \
75                 STRINGIFY(expected));           \
76         tests_failed ++;                        \
77         if (! current_test_group_failed)        \
78           {                                     \
79             current_test_group_failed = 1;      \
80             test_groups_failed ++;              \
81           }                                     \
82       }                                         \
83   } while (0)
84
85 /* Test that a condition evaluates to true.  */
86 #define TEST_P(description, test)               \
87   TEST(description, !!(test), 1)
88
89 /* Like CHECK, but if the test fails, abort the program.  */
90 #define ASSERT(description, test, expected)             \
91   do {                                                  \
92     int tests_failed_pre = tests_failed;                \
93     CHECK(description, test, expected);                 \
94     if (tests_failed_pre != tests_failed)               \
95       exit (1);                                         \
96   } while (0)
97
98 /* Call this if something went wrong.  */
99 #define ABORT(message)                          \
100   do {                                          \
101     printf ("aborting...");                     \
102     if (message)                                \
103       printf (" %s\n", (message));              \
104                                                 \
105     exit(1);                                    \
106   } while (0)
107
108 /* You need to fill this function in.  */
109 static void do_test (int argc, char *argv[]);
110
111 static void
112 print_results (void)
113 {
114   if (tests_failed == 0)
115     {
116       printf ("All %d tests passed.\n", tests);
117       exit (0);
118     }
119   else
120     {
121       printf ("%d of %d tests failed",
122               tests_failed, tests);
123       if (test_groups > 1)
124         printf (" (%d of %d groups)",
125                 test_groups_failed, test_groups);
126       printf ("\n");
127
128       exit (1);
129     }
130 }
131
132 int
133 main (int argc, char *argv[])
134 {
135   (void) test_group;
136
137   do_test (argc, argv);
138   atexit (print_results);
139
140   return tests_failed == 0;
141 }