public
Description: Beanstalk is a simple, fast work queue.
Homepage: http://xph.us/software/beanstalkd/
Clone URL: git://github.com/kr/beanstalkd.git
Click here to lend your support to: beanstalkd and make a donation at www.pledgie.com !
beanstalkd / cut.c
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 1 /*
2 * libcut.inc
3 * CUT 2.1
4 *
5 * Copyright (c) 2001-2002 Samuel A. Falvo II, William D. Tanksley
6 * See CUT-LICENSE.TXT for details.
7 *
8 * Based on WDT's 'TestAssert' package.
9 *
10 * $log$
11 */
12
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <stdarg.h>
8313430c » Keith Rarick 2009-05-05 Fix compiler warnings. 17 #include <unistd.h>
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 18 #include <sys/wait.h>
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 19 #include <errno.h>
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 20 #include "cut.h"
21
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 22
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 23 #define BUF_SIZE 1024
24
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 25 #ifndef BOOL /* Just in case -- helps in portability */
26 #define BOOL int
27 #endif
28
29 #ifndef FALSE
30 #define FALSE (0)
31 #endif
32
33 #ifndef TRUE
34 #define TRUE 1
35 #endif
36
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 37 typedef struct test_output *test_output;
38
39 struct test_output {
40 test_output next;
41 int status;
42 const char *desc;
43 const char *group_name;
44 const char *test_name;
45 FILE *file;
46 };
47
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 48 static int breakpoint = 0;
a4fb87ad » Keith Rarick 2008-12-15 Count and summarize failure... 49 static int count = 0, count_failures = 0, count_errors = 0;
d9077f46 » Keith Rarick 2008-12-15 Don't try to call this duri... 50 static cut_fn cur_takedown = 0;
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 51 static test_output problem_reports = 0;
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 52 static const char *program;
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 53
54 static void
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 55 die(int code, const char *fmt, ...)
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 56 {
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 57 va_list v;
58
59 putc('\n', stderr);
60
61 va_start(v, fmt);
62 vfprintf(stderr, fmt, v);
63 va_end(v);
64
65 if (fmt && *fmt) fputs(": ", stderr);
66 fprintf(stderr, "%s\n", strerror(errno));
67 exit(code);
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 68 }
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 69
70 /* I/O Functions */
71
72 static void print_string( char *string )
73 {
74 printf( "%s", string );
75 fflush( stdout );
76 }
77
78 static void print_string_as_error( char *filename, int lineNumber, char *string )
79 {
c5cd9f0d » Keith Rarick 2008-12-15 More concise failure descri... 80 printf( " %s:%d: %s", filename, lineNumber, string );
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 81 fflush( stdout );
82 }
83
84 static void print_integer( int i )
85 {
86 printf( "%d", i );
87 fflush( stdout );
88 }
89
90 static void print_integer_in_field( int i, int width )
91 {
92 printf( "%*d", width, i );
93 fflush( stdout );
94 }
95
96 static void new_line( void )
97 {
98 printf( "\n" );
99 fflush( stdout );
100 }
101
102 static void print_character( char ch )
103 {
104 printf( "%c", ch );
105 fflush( stdout );
106 }
107
108 /* CUT Initialization and Takedown Functions */
109
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 110 void cut_init(const char *prog_name, int brkpoint )
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 111 {
112 breakpoint = brkpoint;
113 count = 0;
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 114 program = prog_name;
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 115
116 if( brkpoint >= 0 )
117 {
118 print_string( "Breakpoint at test " );
119 print_integer( brkpoint );
120 new_line();
121 }
122 }
123
124 void cut_exit( void )
125 {
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 126 int r, s;
127 char buf[BUF_SIZE];
128 test_output to;
129
a4fb87ad » Keith Rarick 2008-12-15 Count and summarize failure... 130 printf("\n");
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 131 for (to = problem_reports; to; to = to->next) {
132 printf("\n%s in %s/%s", to->desc, to->group_name, to->test_name);
133 if (!WIFEXITED(to->status) || (WEXITSTATUS(to->status) != 255)) {
134 if (WIFEXITED(to->status)) {
135 printf(" (Exit Status %d)", WEXITSTATUS(to->status));
136 }
137 if (WIFSIGNALED(to->status)) {
138 printf(" (Signal %d)", WTERMSIG(to->status));
139 }
140 }
141 printf("\n");
142 rewind(to->file);
8313430c » Keith Rarick 2009-05-05 Fix compiler warnings. 143 while ((r = fread(buf, 1, BUF_SIZE, to->file))) {
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 144 s = fwrite(buf, 1, r, stdout);
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 145 if (r != s) die(3, "fwrite");
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 146 }
147 }
148
a4fb87ad » Keith Rarick 2008-12-15 Count and summarize failure... 149 printf("\n%d tests; %d failures; %d errors.\n", count, count_failures,
150 count_errors);
151 exit(!!(count_failures + count_errors));
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 152 }
153
154 /* Test Progress Accounting functions */
155
9b63f7ac » Keith Rarick 2008-12-14 Provide better isolation fo... 156 static void
157 cut_mark_point(char out, char *filename, int lineNumber )
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 158 {
4c1e5f7b » Keith Rarick 2008-12-15 The char contains informati... 159 if ((count % 10) == 0) {
160 if ((count % 50) == 0) new_line();
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 161 print_integer_in_field( count, 5 );
162 }
163
4c1e5f7b » Keith Rarick 2008-12-15 The char contains informati... 164 print_character(out);
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 165 count++;
4c1e5f7b » Keith Rarick 2008-12-15 The char contains informati... 166
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 167 if( count == breakpoint )
168 {
169 print_string_as_error( filename, lineNumber, "Breakpoint hit" );
170 new_line();
171 cut_exit();
172 }
173 }
174
175
176 void __cut_assert(
177 char *filename,
178 int lineNumber,
179 char *message,
180 char *expression,
181 BOOL success
182 )
183 {
9b63f7ac » Keith Rarick 2008-12-14 Provide better isolation fo... 184 if (success) return;
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 185
c5cd9f0d » Keith Rarick 2008-12-15 More concise failure descri... 186 print_string_as_error( filename, lineNumber, "(" );
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 187 print_string( expression );
c5cd9f0d » Keith Rarick 2008-12-15 More concise failure descri... 188 print_string(") ");
189 print_string( message );
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 190 new_line();
191
d9077f46 » Keith Rarick 2008-12-15 Don't try to call this duri... 192 if (cur_takedown) cur_takedown();
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 193 fflush(stdout);
194 fflush(stderr);
9b63f7ac » Keith Rarick 2008-12-14 Provide better isolation fo... 195 exit(-1);
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 196 }
197
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 198 typedef void(*collect_fn)(void *);
199
200 static FILE *
201 collect(pid_t *pid, collect_fn fn, void *data)
202 {
203 int r;
204 FILE *out;
205
206 out = tmpfile();
207 if (!out) return 0;
208
209 fflush(stdout);
210 fflush(stderr);
211
8313430c » Keith Rarick 2009-05-05 Fix compiler warnings. 212 if ((*pid = fork())) {
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 213 if (*pid < 0) return 0;
214 return out;
215 } else {
216 r = dup2(fileno(out), fileno(stdout));
217 if (r < 0) die(3, "dup2");
218 r = fclose(out);
219 if (r) die(3, "fclose");
220 out = 0;
221
222 fn(data);
223 exit(0);
224 }
225 }
226
227 static void
228 run_in_child(void *data)
229 {
230 int r;
231 cut_fn *fns = data, bringup = fns[0], test = fns[1], takedown = fns[2];
232
233 r = dup2(fileno(stdout), fileno(stderr));
234 if (r < 0) die(3, "dup2");
235 bringup();
236 cur_takedown = takedown;
237 test();
238 takedown();
239 fflush(stdout);
240 fflush(stderr);
241 }
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 242
9b63f7ac » Keith Rarick 2008-12-14 Provide better isolation fo... 243 void
244 __cut_run(char *group_name, cut_fn bringup, cut_fn takedown, char *test_name,
245 cut_fn test, char *filename, int lineno)
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 246 {
5192ce55 » Keith Rarick 2009-05-15 Ditch that symbol table hac... 247 pid_t pid = -1;
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 248 int status, r;
249 FILE *out;
250 test_output to;
251 char *problem_desc = 0;
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 252 cut_fn fns[3] = { bringup, test, takedown };
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 253
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 254 out = collect(&pid, run_in_child, fns);
255 if (!out) die(1, " %s:%d: collect", filename, lineno);
256 if (pid < 0) die(3, "fork");
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 257
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 258 r = waitpid(pid, &status, 0);
259 if (r != pid) die(3, "wait");
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 260
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 261 if (!status) {
262 cut_mark_point('.', filename, lineno );
263 } else if (WIFEXITED(status) && (WEXITSTATUS(status) == 255)) {
264 cut_mark_point('F', filename, lineno );
265 count_failures++;
266 problem_desc = "Failure";
9b63f7ac » Keith Rarick 2008-12-14 Provide better isolation fo... 267 } else {
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 268 cut_mark_point('E', filename, lineno );
269 count_errors++;
270 problem_desc = "Error";
271 }
e1c702e7 » Keith Rarick 2008-12-15 Collate test output at the ... 272
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 273 if (!problem_desc) {
274 fclose(out);
275 return;
c3d1fa7a » Keith Rarick 2008-12-14 Refactor cut runtime librar... 276 }
fd1e24a8 » Keith Rarick 2008-12-15 Look up static symbols. 277
278 /* collect the output */
279 to = malloc(sizeof(struct test_output));
280 if (!to) die(3, "malloc");
281
282 to->desc = problem_desc;
283 to->status = status;
284 to->group_name = group_name;
285 to->test_name = test_name;
286 to->file = out;
287 to->next = problem_reports;
288 problem_reports = to;
04e3ec42 » Keith Rarick 2008-12-14 Refactor to generate less c... 289 }