resetting manifest requested domain to floor
[platform/upstream/ccache.git] / test / framework.c
1 /*
2  * Copyright (C) 2010 Joel Rosdahl
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the Free
6  * Software Foundation; either version 3 of the License, or (at your option)
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 51
16  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #include "ccache.h"
20 #include "test/framework.h"
21
22 #if defined(HAVE_TERMIOS_H)
23 #define USE_COLOR
24 #include <termios.h>
25 #endif
26
27 static unsigned total_asserts;
28 static unsigned total_tests;
29 static unsigned total_suites;
30 static unsigned failed_tests;
31 static const char *current_suite;
32 static const char *current_test;
33 static char *dir_before_suite;
34 static char *dir_before_test;
35 static int verbose;
36
37 static const char COLOR_END[] = "\x1b[m";
38 static const char COLOR_GREEN[] = "\x1b[32m";
39 static const char COLOR_RED[] = "\x1b[31m";
40
41 #define COLOR(tty, color) ((tty) ? COLOR_##color : "")
42
43 static int
44 is_tty(int fd)
45 {
46 #ifdef USE_COLOR
47         struct termios t;
48         return tcgetattr(fd, &t) == 0;
49 #else
50         (void)fd;
51         return 0;
52 #endif
53 }
54
55 static const char *
56 plural_s(unsigned n)
57 {
58         return n == 1 ? "" : "s";
59 }
60
61 int
62 cct_run(suite_fn *suites, int verbose_output)
63 {
64         suite_fn *suite;
65         int tty = is_tty(1);
66
67         verbose = verbose_output;
68
69         for (suite = suites; *suite; suite++) {
70                 unsigned test_index = 0;
71                 while (1) {
72                         test_index = (*suite)(test_index + 1);
73                         if (test_index == 0) {
74                                 /* We have reached the end of the suite. */
75                                 break;
76                         }
77                 }
78         }
79
80         if (failed_tests == 0) {
81                 printf("%sPASSED%s: %u assertion%s, %u test%s, %u suite%s\n",
82                        COLOR(tty, GREEN), COLOR(tty, END),
83                        total_asserts, plural_s(total_asserts),
84                        total_tests, plural_s(total_tests),
85                        total_suites, plural_s(total_suites));
86         } else {
87                 printf("%sFAILED%s: %u test%s\n",
88                        COLOR(tty, RED), COLOR(tty, END),
89                        failed_tests, plural_s(failed_tests));
90         }
91         return failed_tests > 0 ? 1 : 0;
92 }
93
94 void
95 cct_suite_begin(const char *name)
96 {
97         ++total_suites;
98         if (verbose) {
99                 printf("=== SUITE: %s ===\n", name);
100         }
101         dir_before_suite = gnu_getcwd();
102         create_dir(name);
103         cct_chdir(name);
104         current_suite = name;
105 }
106
107 void
108 cct_suite_end()
109 {
110         cct_chdir(dir_before_suite);
111         free(dir_before_suite);
112         dir_before_suite = NULL;
113 }
114
115 void
116 cct_test_begin(const char *name)
117 {
118         extern char *cache_logfile;
119
120         ++total_tests;
121         if (verbose) {
122                 printf("--- TEST: %s ---\n", name);
123         }
124         dir_before_test = gnu_getcwd();
125         create_dir(name);
126         cct_chdir(name);
127         current_test = name;
128
129         cc_reset();
130         cache_logfile = getenv("CCACHE_LOGFILE");
131 }
132
133 void
134 cct_test_end()
135 {
136         if (dir_before_test) {
137                 cct_chdir(dir_before_test);
138                 free(dir_before_test);
139                 dir_before_test = NULL;
140         }
141 }
142
143 void
144 cct_check_passed(const char *file, int line, const char *what)
145 {
146         ++total_asserts;
147         if (verbose) {
148                 printf("%s:%d: Passed assertion: %s\n", file, line, what);
149         }
150 }
151
152 void
153 cct_check_failed(const char *file, int line, const char *what,
154                  const char *expected, const char *actual)
155 {
156         ++total_asserts;
157         ++failed_tests;
158         fprintf(stderr, "%s:%d: Failed assertion:\n", file, line);
159         fprintf(stderr, "  Suite:      %s\n", current_suite);
160         fprintf(stderr, "  Test:       %s\n", current_test);
161         if (expected && actual) {
162                 fprintf(stderr, "  Expression: %s\n", what);
163                 fprintf(stderr, "  Expected:   %s\n", expected);
164                 fprintf(stderr, "  Actual:     %s\n", actual);
165         } else {
166                 fprintf(stderr, "  Assertion:  %s\n", what);
167         }
168         fprintf(stderr, "\n");
169 }
170
171 int
172 cct_check_int_eq(const char *file, int line, const char *expression,
173                  int expected, int actual)
174 {
175         if (expected == actual) {
176                 cct_check_passed(file, line, expression);
177                 return 1;
178         } else {
179                 char *exp_str = format("%i", expected);
180                 char *act_str = format("%i", actual);
181                 cct_check_failed(file, line, expression, exp_str, act_str);
182                 free(exp_str);
183                 free(act_str);
184                 return 0;
185         }
186 }
187
188 int
189 cct_check_uns_eq(const char *file, int line, const char *expression,
190                  unsigned expected, unsigned actual)
191 {
192         if (expected == actual) {
193                 cct_check_passed(file, line, expression);
194                 return 1;
195         } else {
196                 char *exp_str = format("%i", expected);
197                 char *act_str = format("%i", actual);
198                 cct_check_failed(file, line, expression, exp_str, act_str);
199                 free(exp_str);
200                 free(act_str);
201                 return 0;
202         }
203 }
204
205 int
206 cct_check_str_eq(const char *file, int line, const char *expression,
207                  const char *expected, const char *actual, int free1,
208                  int free2)
209 {
210         int result;
211
212         if (expected && actual && str_eq(actual, expected)) {
213                 cct_check_passed(file, line, expression);
214                 result = 1;
215         } else {
216                 char *exp_str = expected ? format("\"%s\"", expected) : x_strdup("(null)");
217                 char *act_str = actual ? format("\"%s\"", actual) : x_strdup("(null)");
218                 cct_check_failed(file, line, expression, exp_str, act_str);
219                 free(exp_str);
220                 free(act_str);
221                 result = 0;
222         }
223
224         if (free1) {
225                 free((char *)expected);
226         }
227         if (free2) {
228                 free((char *)actual);
229         }
230         return result;
231 }
232
233 int
234 cct_check_args_eq(const char *file, int line, const char *expression,
235                   struct args *expected, struct args *actual,
236                   int free1, int free2)
237 {
238         int result;
239
240         if (expected && actual && args_equal(actual, expected)) {
241                 cct_check_passed(file, line, expression);
242                 result = 1;
243         } else {
244                 char *exp_str = expected ? args_to_string(expected) : x_strdup("(null)");
245                 char *act_str = actual ? args_to_string(actual) : x_strdup("(null)");
246                 cct_check_failed(file, line, expression, exp_str, act_str);
247                 free(exp_str);
248                 free(act_str);
249                 result = 0;
250         }
251
252         if (free1) {
253                 args_free(expected);
254         }
255         if (free2) {
256                 args_free(actual);
257         }
258         return result;
259 }
260
261 void
262 cct_chdir(const char *path)
263 {
264         if (chdir(path) != 0) {
265                 fprintf(stderr, "chdir: %s: %s", path, strerror(errno));
266                 abort();
267         }
268 }
269
270 void
271 cct_wipe(const char *path)
272 {
273         /* TODO: rewrite using traverse(). */
274         char *command = format("rm -rf %s", path);
275         if (system(command) != 0) {
276                 perror(command);
277         }
278         free(command);
279 }
280
281 void
282 cct_create_fresh_dir(const char *path)
283 {
284         cct_wipe(path);
285         if (mkdir(path, 0777) != 0) {
286                 fprintf(stderr, "mkdir: %s: %s", path, strerror(errno));;
287                 abort();
288         }
289 }