1 // Copyright (C) 2010-2018 Joel Rosdahl
3 // This program is free software; you can redistribute it and/or modify it
4 // under the terms of the GNU General Public License as published by the Free
5 // Software Foundation; either version 3 of the License, or (at your option)
8 // This program is distributed in the hope that it will be useful, but WITHOUT
9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 // You should have received a copy of the GNU General Public License along with
14 // this program; if not, write to the Free Software Foundation, Inc., 51
15 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 #include "framework.h"
22 #if defined(HAVE_TERMIOS_H)
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;
37 static const char COLOR_END[] = "\x1b[m";
38 static const char COLOR_GREEN[] = "\x1b[1;32m";
39 static const char COLOR_RED[] = "\x1b[1;31m";
41 #define COLOR(tty, color) ((tty) ? COLOR_ ## color : "")
48 return tcgetattr(fd, &t) == 0;
58 return n == 1 ? "" : "s";
62 cct_run(suite_fn *suites, int verbose_output)
67 x_unsetenv("GCC_COLORS"); // Avoid confusing argument processing tests.
68 verbose = verbose_output;
70 for (suite = suites; *suite; suite++) {
71 unsigned test_index = 0;
73 test_index = (*suite)(test_index + 1);
74 if (test_index == 0) {
75 // We have reached the end of the suite.
81 if (failed_tests == 0) {
82 printf("%sPASSED%s: %u assertion%s, %u test%s, %u suite%s\n",
83 COLOR(tty, GREEN), COLOR(tty, END),
84 total_asserts, plural_s(total_asserts),
85 total_tests, plural_s(total_tests),
86 total_suites, plural_s(total_suites));
88 printf("%sFAILED%s: %u test%s\n",
89 COLOR(tty, RED), COLOR(tty, END),
90 failed_tests, plural_s(failed_tests));
92 return failed_tests > 0 ? 1 : 0;
96 cct_suite_begin(const char *name)
100 printf("=== SUITE: %s ===\n", name);
102 dir_before_suite = gnu_getcwd();
105 current_suite = name;
111 cct_chdir(dir_before_suite);
112 free(dir_before_suite);
113 dir_before_suite = NULL;
117 cct_test_begin(const char *name)
121 printf("--- TEST: %s ---\n", name);
123 dir_before_test = gnu_getcwd();
128 putenv("CCACHE_CONFIG_PATH=/dev/null");
135 if (dir_before_test) {
136 cct_chdir(dir_before_test);
137 free(dir_before_test);
138 dir_before_test = NULL;
143 cct_check_passed(const char *file, int line, const char *what)
147 printf("%s:%d: Passed assertion: %s\n", file, line, what);
152 cct_check_failed(const char *file, int line, const char *what,
153 const char *expected, const char *actual)
157 fprintf(stderr, "%s:%d: Failed assertion:\n", file, line);
158 fprintf(stderr, " Suite: %s\n", current_suite);
159 fprintf(stderr, " Test: %s\n", current_test);
161 fprintf(stderr, " Expression: %s\n", what);
163 fprintf(stderr, " Expected: %s\n", expected);
164 fprintf(stderr, " Actual: %s\n", actual);
166 fprintf(stderr, " Message: %s\n", expected);
169 fprintf(stderr, " Assertion: %s\n", what);
171 fprintf(stderr, "\n");
175 cct_check_double_eq(const char *file, int line, const char *expression,
176 double expected, double actual)
178 if (fabs(expected - actual) < DBL_EPSILON) {
179 cct_check_passed(file, line, expression);
182 char *exp_str = format("%.1f", expected);
183 char *act_str = format("%.1f", actual);
184 cct_check_failed(file, line, expression, exp_str, act_str);
191 cct_check_int_eq(const char *file, int line, const char *expression,
192 int64_t expected, int64_t actual)
194 if (expected == actual) {
195 cct_check_passed(file, line, expression);
198 #if defined(HAVE_LONG_LONG) && !defined(__MINGW32__)
199 char *exp_str = format("%lld", (long long)expected);
200 char *act_str = format("%lld", (long long)actual);
202 char *exp_str = format("%ld", (long)expected);
203 char *act_str = format("%ld", (long)actual);
205 cct_check_failed(file, line, expression, exp_str, act_str);
213 cct_check_str_eq(const char *file, int line, const char *expression,
214 char *expected, char *actual,
215 bool free1, bool free2)
219 if (expected && actual && str_eq(actual, expected)) {
220 cct_check_passed(file, line, expression);
223 char *exp_str = expected ? format("\"%s\"", expected) : x_strdup("(null)");
224 char *act_str = actual ? format("\"%s\"", actual) : x_strdup("(null)");
225 cct_check_failed(file, line, expression, exp_str, act_str);
241 cct_check_args_eq(const char *file, int line, const char *expression,
242 struct args *expected, struct args *actual,
243 bool free1, bool free2)
247 if (expected && actual && args_equal(actual, expected)) {
248 cct_check_passed(file, line, expression);
251 char *exp_str = expected ? args_to_string(expected) : x_strdup("(null)");
252 char *act_str = actual ? args_to_string(actual) : x_strdup("(null)");
253 cct_check_failed(file, line, expression, exp_str, act_str);
269 cct_chdir(const char *path)
271 if (chdir(path) != 0) {
272 fprintf(stderr, "chdir: %s: %s", path, strerror(errno));
278 cct_wipe(const char *path)
280 // TODO: rewrite using traverse().
282 char *command = format("rm -rf %s", path);
284 char *command = format("rd /s /q %s", path);
286 if (system(command) != 0) {
293 cct_create_fresh_dir(const char *path)
296 if (mkdir(path, 0777) != 0) {
297 fprintf(stderr, "mkdir: %s: %s", path, strerror(errno));;