1*254b1274SAndroid Build Coastguard Worker /* Copyright 2011,2012 Bas van den Berg
2*254b1274SAndroid Build Coastguard Worker *
3*254b1274SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
4*254b1274SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
5*254b1274SAndroid Build Coastguard Worker * You may obtain a copy of the License at
6*254b1274SAndroid Build Coastguard Worker *
7*254b1274SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
8*254b1274SAndroid Build Coastguard Worker *
9*254b1274SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
10*254b1274SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
11*254b1274SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*254b1274SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
13*254b1274SAndroid Build Coastguard Worker * limitations under the License.
14*254b1274SAndroid Build Coastguard Worker */
15*254b1274SAndroid Build Coastguard Worker
16*254b1274SAndroid Build Coastguard Worker #ifndef CTEST_H
17*254b1274SAndroid Build Coastguard Worker #define CTEST_H
18*254b1274SAndroid Build Coastguard Worker
19*254b1274SAndroid Build Coastguard Worker #ifndef UNUSED_PARAM
20*254b1274SAndroid Build Coastguard Worker /**
21*254b1274SAndroid Build Coastguard Worker * \def UNUSED_PARAM(p);
22*254b1274SAndroid Build Coastguard Worker *
23*254b1274SAndroid Build Coastguard Worker * A macro for quelling compiler warnings about unused variables.
24*254b1274SAndroid Build Coastguard Worker */
25*254b1274SAndroid Build Coastguard Worker # define UNUSED_PARAM(p) ((void)&(p))
26*254b1274SAndroid Build Coastguard Worker #endif /* UNUSED_PARM */
27*254b1274SAndroid Build Coastguard Worker
28*254b1274SAndroid Build Coastguard Worker typedef void (*SetupFunc)(void*);
29*254b1274SAndroid Build Coastguard Worker typedef void (*TearDownFunc)(void*);
30*254b1274SAndroid Build Coastguard Worker
31*254b1274SAndroid Build Coastguard Worker struct ctest {
32*254b1274SAndroid Build Coastguard Worker const char* ssname; // suite name
33*254b1274SAndroid Build Coastguard Worker const char* ttname; // test name
34*254b1274SAndroid Build Coastguard Worker void (*run)();
35*254b1274SAndroid Build Coastguard Worker int skip;
36*254b1274SAndroid Build Coastguard Worker
37*254b1274SAndroid Build Coastguard Worker void* data;
38*254b1274SAndroid Build Coastguard Worker SetupFunc setup;
39*254b1274SAndroid Build Coastguard Worker TearDownFunc teardown;
40*254b1274SAndroid Build Coastguard Worker
41*254b1274SAndroid Build Coastguard Worker unsigned int magic;
42*254b1274SAndroid Build Coastguard Worker };
43*254b1274SAndroid Build Coastguard Worker
44*254b1274SAndroid Build Coastguard Worker #define __FNAME(sname, tname) __ctest_##sname##_##tname##_run
45*254b1274SAndroid Build Coastguard Worker #define __TNAME(sname, tname) __ctest_##sname##_##tname
46*254b1274SAndroid Build Coastguard Worker
47*254b1274SAndroid Build Coastguard Worker #define __CTEST_MAGIC (0xdeadbeef)
48*254b1274SAndroid Build Coastguard Worker #ifdef __APPLE__
49*254b1274SAndroid Build Coastguard Worker #define __Test_Section __attribute__ ((unused,section ("__DATA, .ctest")))
50*254b1274SAndroid Build Coastguard Worker #else
51*254b1274SAndroid Build Coastguard Worker #define __Test_Section __attribute__ ((unused,section (".ctest")))
52*254b1274SAndroid Build Coastguard Worker #endif
53*254b1274SAndroid Build Coastguard Worker
54*254b1274SAndroid Build Coastguard Worker #define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
55*254b1274SAndroid Build Coastguard Worker struct ctest __TNAME(sname, tname) __Test_Section = { \
56*254b1274SAndroid Build Coastguard Worker .ssname=#sname, \
57*254b1274SAndroid Build Coastguard Worker .ttname=#tname, \
58*254b1274SAndroid Build Coastguard Worker .run = __FNAME(sname, tname), \
59*254b1274SAndroid Build Coastguard Worker .skip = _skip, \
60*254b1274SAndroid Build Coastguard Worker .data = __data, \
61*254b1274SAndroid Build Coastguard Worker .setup = (SetupFunc)__setup, \
62*254b1274SAndroid Build Coastguard Worker .teardown = (TearDownFunc)__teardown, \
63*254b1274SAndroid Build Coastguard Worker .magic = __CTEST_MAGIC };
64*254b1274SAndroid Build Coastguard Worker
65*254b1274SAndroid Build Coastguard Worker #define CTEST_DATA(sname) struct sname##_data
66*254b1274SAndroid Build Coastguard Worker
67*254b1274SAndroid Build Coastguard Worker #define CTEST_SETUP(sname) \
68*254b1274SAndroid Build Coastguard Worker void __attribute__ ((weak)) sname##_setup(struct sname##_data* data)
69*254b1274SAndroid Build Coastguard Worker
70*254b1274SAndroid Build Coastguard Worker #define CTEST_TEARDOWN(sname) \
71*254b1274SAndroid Build Coastguard Worker void __attribute__ ((weak)) sname##_teardown(struct sname##_data* data)
72*254b1274SAndroid Build Coastguard Worker
73*254b1274SAndroid Build Coastguard Worker #define __CTEST_INTERNAL(sname, tname, _skip) \
74*254b1274SAndroid Build Coastguard Worker void __FNAME(sname, tname)(); \
75*254b1274SAndroid Build Coastguard Worker __CTEST_STRUCT(sname, tname, _skip, NULL, NULL, NULL) \
76*254b1274SAndroid Build Coastguard Worker void __FNAME(sname, tname)()
77*254b1274SAndroid Build Coastguard Worker
78*254b1274SAndroid Build Coastguard Worker #ifdef __APPLE__
79*254b1274SAndroid Build Coastguard Worker #define SETUP_FNAME(sname) NULL
80*254b1274SAndroid Build Coastguard Worker #define TEARDOWN_FNAME(sname) NULL
81*254b1274SAndroid Build Coastguard Worker #else
82*254b1274SAndroid Build Coastguard Worker #define SETUP_FNAME(sname) sname##_setup
83*254b1274SAndroid Build Coastguard Worker #define TEARDOWN_FNAME(sname) sname##_teardown
84*254b1274SAndroid Build Coastguard Worker #endif
85*254b1274SAndroid Build Coastguard Worker
86*254b1274SAndroid Build Coastguard Worker #define __CTEST2_INTERNAL(sname, tname, _skip) \
87*254b1274SAndroid Build Coastguard Worker static struct sname##_data __ctest_##sname##_data; \
88*254b1274SAndroid Build Coastguard Worker CTEST_SETUP(sname); \
89*254b1274SAndroid Build Coastguard Worker CTEST_TEARDOWN(sname); \
90*254b1274SAndroid Build Coastguard Worker void __FNAME(sname, tname)(struct sname##_data* data); \
91*254b1274SAndroid Build Coastguard Worker __CTEST_STRUCT(sname, tname, _skip, &__ctest_##sname##_data, SETUP_FNAME(sname), TEARDOWN_FNAME(sname)) \
92*254b1274SAndroid Build Coastguard Worker void __FNAME(sname, tname)(struct sname##_data* data)
93*254b1274SAndroid Build Coastguard Worker
94*254b1274SAndroid Build Coastguard Worker
95*254b1274SAndroid Build Coastguard Worker void CTEST_LOG(char *fmt, ...);
96*254b1274SAndroid Build Coastguard Worker void CTEST_ERR(char *fmt, ...); // doesn't return
97*254b1274SAndroid Build Coastguard Worker
98*254b1274SAndroid Build Coastguard Worker #define CTEST(sname, tname) __CTEST_INTERNAL(sname, tname, 0)
99*254b1274SAndroid Build Coastguard Worker #define CTEST_SKIP(sname, tname) __CTEST_INTERNAL(sname, tname, 1)
100*254b1274SAndroid Build Coastguard Worker
101*254b1274SAndroid Build Coastguard Worker #define CTEST2(sname, tname) __CTEST2_INTERNAL(sname, tname, 0)
102*254b1274SAndroid Build Coastguard Worker #define CTEST2_SKIP(sname, tname) __CTEST2_INTERNAL(sname, tname, 1)
103*254b1274SAndroid Build Coastguard Worker
104*254b1274SAndroid Build Coastguard Worker
105*254b1274SAndroid Build Coastguard Worker void assert_str(const char* exp, const char* real, const char* caller, int line);
106*254b1274SAndroid Build Coastguard Worker #define ASSERT_STR(exp, real) assert_str(exp, real, __FILE__, __LINE__)
107*254b1274SAndroid Build Coastguard Worker
108*254b1274SAndroid Build Coastguard Worker void assert_data(const unsigned char* exp, int expsize,
109*254b1274SAndroid Build Coastguard Worker const unsigned char* real, int realsize,
110*254b1274SAndroid Build Coastguard Worker const char* caller, int line);
111*254b1274SAndroid Build Coastguard Worker #define ASSERT_DATA(exp, expsize, real, realsize) \
112*254b1274SAndroid Build Coastguard Worker assert_data(exp, expsize, real, realsize, __FILE__, __LINE__)
113*254b1274SAndroid Build Coastguard Worker
114*254b1274SAndroid Build Coastguard Worker void assert_equal(long exp, long real, const char* caller, int line);
115*254b1274SAndroid Build Coastguard Worker #define ASSERT_EQUAL(exp, real) assert_equal(exp, real, __FILE__, __LINE__)
116*254b1274SAndroid Build Coastguard Worker
117*254b1274SAndroid Build Coastguard Worker void assert_not_equal(long exp, long real, const char* caller, int line);
118*254b1274SAndroid Build Coastguard Worker #define ASSERT_NOT_EQUAL(exp, real) assert_not_equal(exp, real, __FILE__, __LINE__)
119*254b1274SAndroid Build Coastguard Worker
120*254b1274SAndroid Build Coastguard Worker void assert_null(void* real, const char* caller, int line);
121*254b1274SAndroid Build Coastguard Worker #define ASSERT_NULL(real) assert_null((void*)real, __FILE__, __LINE__)
122*254b1274SAndroid Build Coastguard Worker
123*254b1274SAndroid Build Coastguard Worker void assert_not_null(const void* real, const char* caller, int line);
124*254b1274SAndroid Build Coastguard Worker #define ASSERT_NOT_NULL(real) assert_not_null(real, __FILE__, __LINE__)
125*254b1274SAndroid Build Coastguard Worker
126*254b1274SAndroid Build Coastguard Worker void assert_true(int real, const char* caller, int line);
127*254b1274SAndroid Build Coastguard Worker #define ASSERT_TRUE(real) assert_true(real, __FILE__, __LINE__)
128*254b1274SAndroid Build Coastguard Worker
129*254b1274SAndroid Build Coastguard Worker void assert_false(int real, const char* caller, int line);
130*254b1274SAndroid Build Coastguard Worker #define ASSERT_FALSE(real) assert_false(real, __FILE__, __LINE__)
131*254b1274SAndroid Build Coastguard Worker
132*254b1274SAndroid Build Coastguard Worker void assert_fail(const char* caller, int line);
133*254b1274SAndroid Build Coastguard Worker #define ASSERT_FAIL() assert_fail(__FILE__, __LINE__)
134*254b1274SAndroid Build Coastguard Worker
135*254b1274SAndroid Build Coastguard Worker #ifdef CTEST_MAIN
136*254b1274SAndroid Build Coastguard Worker
137*254b1274SAndroid Build Coastguard Worker #include <setjmp.h>
138*254b1274SAndroid Build Coastguard Worker #include <stdarg.h>
139*254b1274SAndroid Build Coastguard Worker #include <stdio.h>
140*254b1274SAndroid Build Coastguard Worker #include <string.h>
141*254b1274SAndroid Build Coastguard Worker #include <sys/time.h>
142*254b1274SAndroid Build Coastguard Worker #include <inttypes.h>
143*254b1274SAndroid Build Coastguard Worker #include <unistd.h>
144*254b1274SAndroid Build Coastguard Worker #include <stdint.h>
145*254b1274SAndroid Build Coastguard Worker #include <stdlib.h>
146*254b1274SAndroid Build Coastguard Worker
147*254b1274SAndroid Build Coastguard Worker #ifdef __APPLE__
148*254b1274SAndroid Build Coastguard Worker #include <dlfcn.h>
149*254b1274SAndroid Build Coastguard Worker #endif
150*254b1274SAndroid Build Coastguard Worker
151*254b1274SAndroid Build Coastguard Worker //#define COLOR_OK
152*254b1274SAndroid Build Coastguard Worker
153*254b1274SAndroid Build Coastguard Worker static size_t ctest_errorsize;
154*254b1274SAndroid Build Coastguard Worker static char* ctest_errormsg;
155*254b1274SAndroid Build Coastguard Worker #define MSG_SIZE 4096
156*254b1274SAndroid Build Coastguard Worker static char ctest_errorbuffer[MSG_SIZE];
157*254b1274SAndroid Build Coastguard Worker static jmp_buf ctest_err;
158*254b1274SAndroid Build Coastguard Worker static int color_output = 1;
159*254b1274SAndroid Build Coastguard Worker static const char* suite_name;
160*254b1274SAndroid Build Coastguard Worker
161*254b1274SAndroid Build Coastguard Worker typedef int (*filter_func)(struct ctest*);
162*254b1274SAndroid Build Coastguard Worker
163*254b1274SAndroid Build Coastguard Worker #define ANSI_BLACK "\033[0;30m"
164*254b1274SAndroid Build Coastguard Worker #define ANSI_RED "\033[0;31m"
165*254b1274SAndroid Build Coastguard Worker #define ANSI_GREEN "\033[0;32m"
166*254b1274SAndroid Build Coastguard Worker #define ANSI_YELLOW "\033[0;33m"
167*254b1274SAndroid Build Coastguard Worker #define ANSI_BLUE "\033[0;34m"
168*254b1274SAndroid Build Coastguard Worker #define ANSI_MAGENTA "\033[0;35m"
169*254b1274SAndroid Build Coastguard Worker #define ANSI_CYAN "\033[0;36m"
170*254b1274SAndroid Build Coastguard Worker #define ANSI_GREY "\033[0;37m"
171*254b1274SAndroid Build Coastguard Worker #define ANSI_DARKGREY "\033[01;30m"
172*254b1274SAndroid Build Coastguard Worker #define ANSI_BRED "\033[01;31m"
173*254b1274SAndroid Build Coastguard Worker #define ANSI_BGREEN "\033[01;32m"
174*254b1274SAndroid Build Coastguard Worker #define ANSI_BYELLOW "\033[01;33m"
175*254b1274SAndroid Build Coastguard Worker #define ANSI_BBLUE "\033[01;34m"
176*254b1274SAndroid Build Coastguard Worker #define ANSI_BMAGENTA "\033[01;35m"
177*254b1274SAndroid Build Coastguard Worker #define ANSI_BCYAN "\033[01;36m"
178*254b1274SAndroid Build Coastguard Worker #define ANSI_WHITE "\033[01;37m"
179*254b1274SAndroid Build Coastguard Worker #define ANSI_NORMAL "\033[0m"
180*254b1274SAndroid Build Coastguard Worker
CTEST(suite,test)181*254b1274SAndroid Build Coastguard Worker static CTEST(suite, test) { }
182*254b1274SAndroid Build Coastguard Worker
msg_start(const char * color,const char * title)183*254b1274SAndroid Build Coastguard Worker static void msg_start(const char* color, const char* title) {
184*254b1274SAndroid Build Coastguard Worker int size;
185*254b1274SAndroid Build Coastguard Worker if (color_output) {
186*254b1274SAndroid Build Coastguard Worker size = snprintf(ctest_errormsg, ctest_errorsize, "%s", color);
187*254b1274SAndroid Build Coastguard Worker ctest_errorsize -= size;
188*254b1274SAndroid Build Coastguard Worker ctest_errormsg += size;
189*254b1274SAndroid Build Coastguard Worker }
190*254b1274SAndroid Build Coastguard Worker size = snprintf(ctest_errormsg, ctest_errorsize, " %s: ", title);
191*254b1274SAndroid Build Coastguard Worker ctest_errorsize -= size;
192*254b1274SAndroid Build Coastguard Worker ctest_errormsg += size;
193*254b1274SAndroid Build Coastguard Worker }
194*254b1274SAndroid Build Coastguard Worker
msg_end()195*254b1274SAndroid Build Coastguard Worker static void msg_end() {
196*254b1274SAndroid Build Coastguard Worker int size;
197*254b1274SAndroid Build Coastguard Worker if (color_output) {
198*254b1274SAndroid Build Coastguard Worker size = snprintf(ctest_errormsg, ctest_errorsize, ANSI_NORMAL);
199*254b1274SAndroid Build Coastguard Worker ctest_errorsize -= size;
200*254b1274SAndroid Build Coastguard Worker ctest_errormsg += size;
201*254b1274SAndroid Build Coastguard Worker }
202*254b1274SAndroid Build Coastguard Worker size = snprintf(ctest_errormsg, ctest_errorsize, "\n");
203*254b1274SAndroid Build Coastguard Worker ctest_errorsize -= size;
204*254b1274SAndroid Build Coastguard Worker ctest_errormsg += size;
205*254b1274SAndroid Build Coastguard Worker }
206*254b1274SAndroid Build Coastguard Worker
CTEST_LOG(char * fmt,...)207*254b1274SAndroid Build Coastguard Worker void CTEST_LOG(char *fmt, ...)
208*254b1274SAndroid Build Coastguard Worker {
209*254b1274SAndroid Build Coastguard Worker va_list argp;
210*254b1274SAndroid Build Coastguard Worker msg_start(ANSI_BLUE, "LOG");
211*254b1274SAndroid Build Coastguard Worker
212*254b1274SAndroid Build Coastguard Worker va_start(argp, fmt);
213*254b1274SAndroid Build Coastguard Worker int size = vsnprintf(ctest_errormsg, ctest_errorsize, fmt, argp);
214*254b1274SAndroid Build Coastguard Worker ctest_errorsize -= size;
215*254b1274SAndroid Build Coastguard Worker ctest_errormsg += size;
216*254b1274SAndroid Build Coastguard Worker va_end(argp);
217*254b1274SAndroid Build Coastguard Worker
218*254b1274SAndroid Build Coastguard Worker msg_end();
219*254b1274SAndroid Build Coastguard Worker }
220*254b1274SAndroid Build Coastguard Worker
CTEST_ERR(char * fmt,...)221*254b1274SAndroid Build Coastguard Worker void CTEST_ERR(char *fmt, ...)
222*254b1274SAndroid Build Coastguard Worker {
223*254b1274SAndroid Build Coastguard Worker va_list argp;
224*254b1274SAndroid Build Coastguard Worker msg_start(ANSI_YELLOW, "ERR");
225*254b1274SAndroid Build Coastguard Worker
226*254b1274SAndroid Build Coastguard Worker va_start(argp, fmt);
227*254b1274SAndroid Build Coastguard Worker int size = vsnprintf(ctest_errormsg, ctest_errorsize, fmt, argp);
228*254b1274SAndroid Build Coastguard Worker ctest_errorsize -= size;
229*254b1274SAndroid Build Coastguard Worker ctest_errormsg += size;
230*254b1274SAndroid Build Coastguard Worker va_end(argp);
231*254b1274SAndroid Build Coastguard Worker
232*254b1274SAndroid Build Coastguard Worker msg_end();
233*254b1274SAndroid Build Coastguard Worker longjmp(ctest_err, 1);
234*254b1274SAndroid Build Coastguard Worker }
235*254b1274SAndroid Build Coastguard Worker
assert_str(const char * exp,const char * real,const char * caller,int line)236*254b1274SAndroid Build Coastguard Worker void assert_str(const char* exp, const char* real, const char* caller, int line) {
237*254b1274SAndroid Build Coastguard Worker if ((exp == NULL && real != NULL) ||
238*254b1274SAndroid Build Coastguard Worker (exp != NULL && real == NULL) ||
239*254b1274SAndroid Build Coastguard Worker (exp && real && strcmp(exp, real) != 0)) {
240*254b1274SAndroid Build Coastguard Worker CTEST_ERR("%s:%d expected '%s', got '%s'", caller, line, exp, real);
241*254b1274SAndroid Build Coastguard Worker }
242*254b1274SAndroid Build Coastguard Worker }
243*254b1274SAndroid Build Coastguard Worker
assert_data(const unsigned char * exp,int expsize,const unsigned char * real,int realsize,const char * caller,int line)244*254b1274SAndroid Build Coastguard Worker void assert_data(const unsigned char* exp, int expsize,
245*254b1274SAndroid Build Coastguard Worker const unsigned char* real, int realsize,
246*254b1274SAndroid Build Coastguard Worker const char* caller, int line) {
247*254b1274SAndroid Build Coastguard Worker int i;
248*254b1274SAndroid Build Coastguard Worker if (expsize != realsize) {
249*254b1274SAndroid Build Coastguard Worker CTEST_ERR("%s:%d expected %d bytes, got %d", caller, line, expsize, realsize);
250*254b1274SAndroid Build Coastguard Worker }
251*254b1274SAndroid Build Coastguard Worker for (i=0; i<expsize; i++) {
252*254b1274SAndroid Build Coastguard Worker if (exp[i] != real[i]) {
253*254b1274SAndroid Build Coastguard Worker CTEST_ERR("%s:%d expected 0x%02x at offset %d got 0x%02x",
254*254b1274SAndroid Build Coastguard Worker caller, line, exp[i], i, real[i]);
255*254b1274SAndroid Build Coastguard Worker }
256*254b1274SAndroid Build Coastguard Worker }
257*254b1274SAndroid Build Coastguard Worker }
258*254b1274SAndroid Build Coastguard Worker
assert_equal(long exp,long real,const char * caller,int line)259*254b1274SAndroid Build Coastguard Worker void assert_equal(long exp, long real, const char* caller, int line) {
260*254b1274SAndroid Build Coastguard Worker if (exp != real) {
261*254b1274SAndroid Build Coastguard Worker CTEST_ERR("%s:%d expected %ld, got %ld", caller, line, exp, real);
262*254b1274SAndroid Build Coastguard Worker }
263*254b1274SAndroid Build Coastguard Worker }
264*254b1274SAndroid Build Coastguard Worker
assert_not_equal(long exp,long real,const char * caller,int line)265*254b1274SAndroid Build Coastguard Worker void assert_not_equal(long exp, long real, const char* caller, int line) {
266*254b1274SAndroid Build Coastguard Worker if ((exp) == (real)) {
267*254b1274SAndroid Build Coastguard Worker CTEST_ERR("%s:%d should not be %ld", caller, line, real);
268*254b1274SAndroid Build Coastguard Worker }
269*254b1274SAndroid Build Coastguard Worker }
270*254b1274SAndroid Build Coastguard Worker
assert_null(void * real,const char * caller,int line)271*254b1274SAndroid Build Coastguard Worker void assert_null(void* real, const char* caller, int line) {
272*254b1274SAndroid Build Coastguard Worker if ((real) != NULL) {
273*254b1274SAndroid Build Coastguard Worker CTEST_ERR("%s:%d should be NULL", caller, line);
274*254b1274SAndroid Build Coastguard Worker }
275*254b1274SAndroid Build Coastguard Worker }
276*254b1274SAndroid Build Coastguard Worker
assert_not_null(const void * real,const char * caller,int line)277*254b1274SAndroid Build Coastguard Worker void assert_not_null(const void* real, const char* caller, int line) {
278*254b1274SAndroid Build Coastguard Worker if (real == NULL) {
279*254b1274SAndroid Build Coastguard Worker CTEST_ERR("%s:%d should not be NULL", caller, line);
280*254b1274SAndroid Build Coastguard Worker }
281*254b1274SAndroid Build Coastguard Worker }
282*254b1274SAndroid Build Coastguard Worker
assert_true(int real,const char * caller,int line)283*254b1274SAndroid Build Coastguard Worker void assert_true(int real, const char* caller, int line) {
284*254b1274SAndroid Build Coastguard Worker if ((real) == 0) {
285*254b1274SAndroid Build Coastguard Worker CTEST_ERR("%s:%d should be true", caller, line);
286*254b1274SAndroid Build Coastguard Worker }
287*254b1274SAndroid Build Coastguard Worker }
288*254b1274SAndroid Build Coastguard Worker
assert_false(int real,const char * caller,int line)289*254b1274SAndroid Build Coastguard Worker void assert_false(int real, const char* caller, int line) {
290*254b1274SAndroid Build Coastguard Worker if ((real) != 0) {
291*254b1274SAndroid Build Coastguard Worker CTEST_ERR("%s:%d should be false", caller, line);
292*254b1274SAndroid Build Coastguard Worker }
293*254b1274SAndroid Build Coastguard Worker }
294*254b1274SAndroid Build Coastguard Worker
assert_fail(const char * caller,int line)295*254b1274SAndroid Build Coastguard Worker void assert_fail(const char* caller, int line) {
296*254b1274SAndroid Build Coastguard Worker CTEST_ERR("%s:%d shouldn't come here", caller, line);
297*254b1274SAndroid Build Coastguard Worker }
298*254b1274SAndroid Build Coastguard Worker
299*254b1274SAndroid Build Coastguard Worker
suite_all(struct ctest * t)300*254b1274SAndroid Build Coastguard Worker static int suite_all(struct ctest* t) {
301*254b1274SAndroid Build Coastguard Worker UNUSED_PARAM(t);
302*254b1274SAndroid Build Coastguard Worker return 1;
303*254b1274SAndroid Build Coastguard Worker }
304*254b1274SAndroid Build Coastguard Worker
suite_filter(struct ctest * t)305*254b1274SAndroid Build Coastguard Worker static int suite_filter(struct ctest* t) {
306*254b1274SAndroid Build Coastguard Worker return strncmp(suite_name, t->ssname, strlen(suite_name)) == 0;
307*254b1274SAndroid Build Coastguard Worker }
308*254b1274SAndroid Build Coastguard Worker
getCurrentTime()309*254b1274SAndroid Build Coastguard Worker static uint64_t getCurrentTime() {
310*254b1274SAndroid Build Coastguard Worker struct timeval now;
311*254b1274SAndroid Build Coastguard Worker gettimeofday(&now, NULL);
312*254b1274SAndroid Build Coastguard Worker uint64_t now64 = now.tv_sec;
313*254b1274SAndroid Build Coastguard Worker now64 *= 1000000;
314*254b1274SAndroid Build Coastguard Worker now64 += (now.tv_usec);
315*254b1274SAndroid Build Coastguard Worker return now64;
316*254b1274SAndroid Build Coastguard Worker }
317*254b1274SAndroid Build Coastguard Worker
color_print(const char * color,const char * text)318*254b1274SAndroid Build Coastguard Worker static void color_print(const char* color, const char* text) {
319*254b1274SAndroid Build Coastguard Worker if (color_output)
320*254b1274SAndroid Build Coastguard Worker printf("%s%s"ANSI_NORMAL"\n", color, text);
321*254b1274SAndroid Build Coastguard Worker else
322*254b1274SAndroid Build Coastguard Worker printf("%s\n", text);
323*254b1274SAndroid Build Coastguard Worker }
324*254b1274SAndroid Build Coastguard Worker
325*254b1274SAndroid Build Coastguard Worker #ifdef __APPLE__
find_symbol(struct ctest * test,const char * fname)326*254b1274SAndroid Build Coastguard Worker static void *find_symbol(struct ctest *test, const char *fname)
327*254b1274SAndroid Build Coastguard Worker {
328*254b1274SAndroid Build Coastguard Worker size_t len = strlen(test->ssname) + 1 + strlen(fname);
329*254b1274SAndroid Build Coastguard Worker char *symbol_name = (char *) malloc(len + 1);
330*254b1274SAndroid Build Coastguard Worker memset(symbol_name, 0, len + 1);
331*254b1274SAndroid Build Coastguard Worker snprintf(symbol_name, len + 1, "%s_%s", test->ssname, fname);
332*254b1274SAndroid Build Coastguard Worker
333*254b1274SAndroid Build Coastguard Worker //fprintf(stderr, ">>>> dlsym: loading %s\n", symbol_name);
334*254b1274SAndroid Build Coastguard Worker void *symbol = dlsym(RTLD_DEFAULT, symbol_name);
335*254b1274SAndroid Build Coastguard Worker if (!symbol) {
336*254b1274SAndroid Build Coastguard Worker //fprintf(stderr, ">>>> ERROR: %s\n", dlerror());
337*254b1274SAndroid Build Coastguard Worker }
338*254b1274SAndroid Build Coastguard Worker // returns NULL on error
339*254b1274SAndroid Build Coastguard Worker
340*254b1274SAndroid Build Coastguard Worker free(symbol_name);
341*254b1274SAndroid Build Coastguard Worker return symbol;
342*254b1274SAndroid Build Coastguard Worker }
343*254b1274SAndroid Build Coastguard Worker #endif
344*254b1274SAndroid Build Coastguard Worker
345*254b1274SAndroid Build Coastguard Worker #ifdef CTEST_SEGFAULT
346*254b1274SAndroid Build Coastguard Worker #include <signal.h>
sighandler(int signum)347*254b1274SAndroid Build Coastguard Worker static void sighandler(int signum)
348*254b1274SAndroid Build Coastguard Worker {
349*254b1274SAndroid Build Coastguard Worker char msg[128];
350*254b1274SAndroid Build Coastguard Worker sprintf(msg, "[SIGNAL %d: %s]", signum, sys_siglist[signum]);
351*254b1274SAndroid Build Coastguard Worker color_print(ANSI_BRED, msg);
352*254b1274SAndroid Build Coastguard Worker fflush(stdout);
353*254b1274SAndroid Build Coastguard Worker
354*254b1274SAndroid Build Coastguard Worker /* "Unregister" the signal handler and send the signal back to the process
355*254b1274SAndroid Build Coastguard Worker * so it can terminate as expected */
356*254b1274SAndroid Build Coastguard Worker signal(signum, SIG_DFL);
357*254b1274SAndroid Build Coastguard Worker kill(getpid(), signum);
358*254b1274SAndroid Build Coastguard Worker }
359*254b1274SAndroid Build Coastguard Worker #endif
360*254b1274SAndroid Build Coastguard Worker
ctest_main(int argc,const char * argv[])361*254b1274SAndroid Build Coastguard Worker int ctest_main(int argc, const char *argv[])
362*254b1274SAndroid Build Coastguard Worker {
363*254b1274SAndroid Build Coastguard Worker static int total = 0;
364*254b1274SAndroid Build Coastguard Worker static int num_ok = 0;
365*254b1274SAndroid Build Coastguard Worker static int num_fail = 0;
366*254b1274SAndroid Build Coastguard Worker static int num_skip = 0;
367*254b1274SAndroid Build Coastguard Worker static int index = 1;
368*254b1274SAndroid Build Coastguard Worker static filter_func filter = suite_all;
369*254b1274SAndroid Build Coastguard Worker
370*254b1274SAndroid Build Coastguard Worker #ifdef CTEST_SEGFAULT
371*254b1274SAndroid Build Coastguard Worker signal(SIGSEGV, sighandler);
372*254b1274SAndroid Build Coastguard Worker #endif
373*254b1274SAndroid Build Coastguard Worker
374*254b1274SAndroid Build Coastguard Worker if (argc == 2) {
375*254b1274SAndroid Build Coastguard Worker suite_name = argv[1];
376*254b1274SAndroid Build Coastguard Worker filter = suite_filter;
377*254b1274SAndroid Build Coastguard Worker }
378*254b1274SAndroid Build Coastguard Worker
379*254b1274SAndroid Build Coastguard Worker color_output = isatty(1);
380*254b1274SAndroid Build Coastguard Worker uint64_t t1 = getCurrentTime();
381*254b1274SAndroid Build Coastguard Worker
382*254b1274SAndroid Build Coastguard Worker struct ctest* ctest_begin = &__TNAME(suite, test);
383*254b1274SAndroid Build Coastguard Worker struct ctest* ctest_end = &__TNAME(suite, test);
384*254b1274SAndroid Build Coastguard Worker // find begin and end of section by comparing magics
385*254b1274SAndroid Build Coastguard Worker while (1) {
386*254b1274SAndroid Build Coastguard Worker struct ctest* t = ctest_begin-1;
387*254b1274SAndroid Build Coastguard Worker if (t->magic != __CTEST_MAGIC) break;
388*254b1274SAndroid Build Coastguard Worker ctest_begin--;
389*254b1274SAndroid Build Coastguard Worker }
390*254b1274SAndroid Build Coastguard Worker while (1) {
391*254b1274SAndroid Build Coastguard Worker struct ctest* t = ctest_end+1;
392*254b1274SAndroid Build Coastguard Worker if (t->magic != __CTEST_MAGIC) break;
393*254b1274SAndroid Build Coastguard Worker ctest_end++;
394*254b1274SAndroid Build Coastguard Worker }
395*254b1274SAndroid Build Coastguard Worker ctest_end++; // end after last one
396*254b1274SAndroid Build Coastguard Worker
397*254b1274SAndroid Build Coastguard Worker static struct ctest* test;
398*254b1274SAndroid Build Coastguard Worker for (test = ctest_begin; test != ctest_end; test++) {
399*254b1274SAndroid Build Coastguard Worker if (test == &__ctest_suite_test) continue;
400*254b1274SAndroid Build Coastguard Worker if (filter(test)) total++;
401*254b1274SAndroid Build Coastguard Worker }
402*254b1274SAndroid Build Coastguard Worker
403*254b1274SAndroid Build Coastguard Worker for (test = ctest_begin; test != ctest_end; test++) {
404*254b1274SAndroid Build Coastguard Worker if (test == &__ctest_suite_test) continue;
405*254b1274SAndroid Build Coastguard Worker if (filter(test)) {
406*254b1274SAndroid Build Coastguard Worker ctest_errorbuffer[0] = 0;
407*254b1274SAndroid Build Coastguard Worker ctest_errorsize = MSG_SIZE-1;
408*254b1274SAndroid Build Coastguard Worker ctest_errormsg = ctest_errorbuffer;
409*254b1274SAndroid Build Coastguard Worker printf("TEST %d/%d %s:%s ", index, total, test->ssname, test->ttname);
410*254b1274SAndroid Build Coastguard Worker fflush(stdout);
411*254b1274SAndroid Build Coastguard Worker if (test->skip) {
412*254b1274SAndroid Build Coastguard Worker color_print(ANSI_BYELLOW, "[SKIPPED]");
413*254b1274SAndroid Build Coastguard Worker num_skip++;
414*254b1274SAndroid Build Coastguard Worker } else {
415*254b1274SAndroid Build Coastguard Worker int result = setjmp(ctest_err);
416*254b1274SAndroid Build Coastguard Worker if (result == 0) {
417*254b1274SAndroid Build Coastguard Worker #ifdef __APPLE__
418*254b1274SAndroid Build Coastguard Worker if (!test->setup) {
419*254b1274SAndroid Build Coastguard Worker test->setup = (SetupFunc)find_symbol(test, "setup");
420*254b1274SAndroid Build Coastguard Worker }
421*254b1274SAndroid Build Coastguard Worker if (!test->teardown) {
422*254b1274SAndroid Build Coastguard Worker test->teardown = (SetupFunc)find_symbol(test, "teardown");
423*254b1274SAndroid Build Coastguard Worker }
424*254b1274SAndroid Build Coastguard Worker #endif
425*254b1274SAndroid Build Coastguard Worker
426*254b1274SAndroid Build Coastguard Worker if (test->setup) test->setup(test->data);
427*254b1274SAndroid Build Coastguard Worker if (test->data)
428*254b1274SAndroid Build Coastguard Worker test->run(test->data);
429*254b1274SAndroid Build Coastguard Worker else
430*254b1274SAndroid Build Coastguard Worker test->run();
431*254b1274SAndroid Build Coastguard Worker if (test->teardown) test->teardown(test->data);
432*254b1274SAndroid Build Coastguard Worker // if we got here it's ok
433*254b1274SAndroid Build Coastguard Worker #ifdef COLOR_OK
434*254b1274SAndroid Build Coastguard Worker color_print(ANSI_BGREEN, "[OK]");
435*254b1274SAndroid Build Coastguard Worker #else
436*254b1274SAndroid Build Coastguard Worker printf("[OK]\n");
437*254b1274SAndroid Build Coastguard Worker #endif
438*254b1274SAndroid Build Coastguard Worker num_ok++;
439*254b1274SAndroid Build Coastguard Worker } else {
440*254b1274SAndroid Build Coastguard Worker color_print(ANSI_BRED, "[FAIL]");
441*254b1274SAndroid Build Coastguard Worker num_fail++;
442*254b1274SAndroid Build Coastguard Worker }
443*254b1274SAndroid Build Coastguard Worker if (ctest_errorsize != MSG_SIZE-1) printf("%s", ctest_errorbuffer);
444*254b1274SAndroid Build Coastguard Worker }
445*254b1274SAndroid Build Coastguard Worker index++;
446*254b1274SAndroid Build Coastguard Worker }
447*254b1274SAndroid Build Coastguard Worker }
448*254b1274SAndroid Build Coastguard Worker uint64_t t2 = getCurrentTime();
449*254b1274SAndroid Build Coastguard Worker
450*254b1274SAndroid Build Coastguard Worker const char* color = (num_fail) ? ANSI_BRED : ANSI_GREEN;
451*254b1274SAndroid Build Coastguard Worker char results[80];
452*254b1274SAndroid Build Coastguard Worker sprintf(results, "RESULTS: %d tests (%d ok, %d failed, %d skipped) ran in %"PRIu64" ms", total, num_ok, num_fail, num_skip, (t2 - t1)/1000);
453*254b1274SAndroid Build Coastguard Worker color_print(color, results);
454*254b1274SAndroid Build Coastguard Worker return num_fail;
455*254b1274SAndroid Build Coastguard Worker }
456*254b1274SAndroid Build Coastguard Worker
457*254b1274SAndroid Build Coastguard Worker #endif
458*254b1274SAndroid Build Coastguard Worker
459*254b1274SAndroid Build Coastguard Worker #endif
460