59
return content;
60
}
61
62
-static void run(const char *expected_output_file, int expected_error_code, ...)
62
+static char *execute(const char *suite, int expected_error_code, const char **args, size_t nargs)
63
{
64
SECURITY_ATTRIBUTES security_attributes = { 0 };
65
PROCESS_INFORMATION process_info = { 0 };
66
STARTUPINFO startup_info = { 0 };
67
+ char binary_path[4096] = { 0 };
68
char cmdline[4096] = { 0 };
68
- char *expected_output = NULL;
69
char *output = NULL;
70
HANDLE stdout_write;
71
HANDLE stdout_read;
72
DWORD exit_code;
73
- va_list ap;
73
+ size_t i;
74
+
75
+ snprintf(binary_path, sizeof(binary_path), "%s/%s_suite.exe",
76
+ selftest_suite_directory, suite);
77
78
/*
79
* Assemble command line arguments. In theory we'd have to properly
80
* quote them. In practice none of our tests actually care.
81
*/
79
- va_start(ap, expected_error_code);
80
- snprintf(cmdline, sizeof(cmdline), "selftest");
81
- while (1) {
82
+ snprintf(cmdline, sizeof(cmdline), suite);
83
+ for (i = 0; i < nargs; i++) {
84
size_t cmdline_len = strlen(cmdline);
83
- const char *arg;
84
-
85
- arg = va_arg(ap, const char *);
86
- if (!arg)
87
- break;
88
-
85
+ const char *arg = args[i];
86
cl_assert(cmdline_len + strlen(arg) < sizeof(cmdline));
87
snprintf(cmdline + cmdline_len, sizeof(cmdline) - cmdline_len,
88
" %s", arg);
89
}
93
- va_end(ap);
90
91
/*
92
* Create a pipe that we will use to read data from the child process.
106
startup_info.hStdError = stdout_write;
107
startup_info.hStdOutput = stdout_write;
108
startup_info.dwFlags |= STARTF_USESTDHANDLES;
113
- cl_assert_equal_b(1, CreateProcess(selftest_binary_path, cmdline, NULL, NULL, TRUE,
109
+ cl_assert_equal_b(1, CreateProcess(binary_path, cmdline, NULL, NULL, TRUE,
110
0, NULL, NULL, &startup_info, &process_info));
111
cl_assert_equal_b(1, CloseHandle(stdout_write));
112
113
output = read_full(stdout_read, 1);
114
cl_assert_equal_b(1, CloseHandle(stdout_read));
115
cl_assert_equal_b(1, GetExitCodeProcess(process_info.hProcess, &exit_code));
116
+ cl_assert_equal_i(exit_code, expected_error_code);
117
+
118
+ return output;
119
+}
120
+
121
+static void assert_output(const char *suite, const char *expected_output_file, int expected_error_code, ...)
122
+{
123
+ char *expected_output = NULL;
124
+ char *output = NULL;
125
+ const char *args[16];
126
+ va_list ap;
127
+ size_t i;
128
+
129
+ va_start(ap, expected_error_code);
130
+ for (i = 0; ; i++) {
131
+ const char *arg = va_arg(ap, const char *);
132
+ if (!arg)
133
+ break;
134
+ cl_assert(i < sizeof(args) / sizeof(*args));
135
+ args[i] = arg;
136
+ }
137
+ va_end(ap);
138
139
+ output = execute(suite, expected_error_code, args, i);
140
expected_output = read_file(cl_fixture(expected_output_file));
141
cl_assert_equal_s(output, expected_output);
123
- cl_assert_equal_i(exit_code, expected_error_code);
142
143
free(expected_output);
144
free(output);
198
return data;
199
}
200
183
-static void run(const char *expected_output_file, int expected_error_code, ...)
201
+static char *execute(const char *suite, int expected_error_code, const char **args, size_t nargs)
202
{
185
- const char *argv[16];
203
int pipe_fds[2];
187
- va_list ap;
204
pid_t pid;
189
- int i;
190
-
191
- va_start(ap, expected_error_code);
192
- argv[0] = "selftest";
193
- for (i = 1; ; i++) {
194
- cl_assert(i < sizeof(argv) / sizeof(*argv));
195
-
196
- argv[i] = va_arg(ap, const char *);
197
- if (!argv[i])
198
- break;
199
- }
200
- va_end(ap);
205
206
cl_must_pass(pipe(pipe_fds));
207
208
pid = fork();
209
if (!pid) {
210
+ const char *final_args[17] = { NULL };
211
+ char binary_path[4096];
212
+ size_t len = 0;
213
+ size_t i;
214
+
215
+ cl_assert(nargs < sizeof(final_args) / sizeof(*final_args));
216
+ final_args[0] = suite;
217
+ for (i = 0; i < nargs; i++)
218
+ final_args[i + 1] = args[i];
219
+
220
if (dup2(pipe_fds[1], STDOUT_FILENO) < 0 ||
221
dup2(pipe_fds[1], STDERR_FILENO) < 0 ||
222
close(0) < 0 ||
224
close(pipe_fds[1]) < 0)
225
exit(1);
226
213
- execv(selftest_binary_path, (char **) argv);
227
+ cl_assert(len + strlen(selftest_suite_directory) < sizeof(binary_path));
228
+ strcpy(binary_path, selftest_suite_directory);
229
+ len += strlen(selftest_suite_directory);
230
+
231
+ cl_assert(len + 1 < sizeof(binary_path));
232
+ binary_path[len] = '/';
233
+ len += 1;
234
+
235
+ cl_assert(len + strlen(suite) < sizeof(binary_path));
236
+ strcpy(binary_path + len, suite);
237
+ len += strlen(suite);
238
+
239
+ cl_assert(len + strlen("_suite") < sizeof(binary_path));
240
+ strcpy(binary_path + len, "_suite");
241
+ len += strlen("_suite");
242
+
243
+ binary_path[len] = '\0';
244
+
245
+ execv(binary_path, (char **) final_args);
246
exit(1);
247
} else if (pid > 0) {
248
pid_t waited_pid;
217
- char *expected_output, *output;
249
+ char *output;
250
int stat;
251
252
cl_must_pass(close(pipe_fds[1]));
258
cl_assert(WIFEXITED(stat));
259
cl_assert_equal_i(WEXITSTATUS(stat), expected_error_code);
260
229
- expected_output = read_file(cl_fixture(expected_output_file));
230
- cl_assert_equal_s(output, expected_output);
231
-
232
- free(expected_output);
233
- free(output);
261
+ return output;
262
} else {
263
cl_fail("Fork failed.");
264
}
265
+
266
+ return NULL;
267
+}
268
+
269
+static void assert_output(const char *suite, const char *expected_output_file, int expected_error_code, ...)
270
+{
271
+ char *expected_output, *output;
272
+ const char *args[16];
273
+ va_list ap;
274
+ size_t i;
275
+
276
+ va_start(ap, expected_error_code);
277
+ for (i = 0; ; i++) {
278
+ cl_assert(i < sizeof(args) / sizeof(*args));
279
+ args[i] = va_arg(ap, const char *);
280
+ if (!args[i])
281
+ break;
282
+ }
283
+ va_end(ap);
284
+
285
+ output = execute(suite, expected_error_code, args, i);
286
+ expected_output = read_file(cl_fixture(expected_output_file));
287
+ cl_assert_equal_s(output, expected_output);
288
+
289
+ free(expected_output);
290
+ free(output);
291
}
292
#endif
293
294
void test_selftest__help(void)
295
{
242
- cl_invoke(run("help", 1, "-h", NULL));
296
+ cl_invoke(assert_output("combined", "help", 1, "-h", NULL));
297
}
298
299
void test_selftest__without_arguments(void)
300
{
247
- cl_invoke(run("without_arguments", 10, NULL));
301
+ cl_invoke(assert_output("combined", "without_arguments", 9, NULL));
302
}
303
304
void test_selftest__specific_test(void)
305
{
252
- cl_invoke(run("specific_test", 1, "-sselftest::suite::bool", NULL));
306
+ cl_invoke(assert_output("combined", "specific_test", 1, "-scombined::bool", NULL));
307
}
308
309
void test_selftest__stop_on_failure(void)
310
{
257
- cl_invoke(run("stop_on_failure", 1, "-Q", NULL));
311
+ cl_invoke(assert_output("combined", "stop_on_failure", 1, "-Q", NULL));
312
}
313
314
void test_selftest__quiet(void)
315
{
262
- cl_invoke(run("quiet", 10, "-q", NULL));
316
+ cl_invoke(assert_output("combined", "quiet", 9, "-q", NULL));
317
}
318
319
void test_selftest__tap(void)
320
{
267
- cl_invoke(run("tap", 10, "-t", NULL));
321
+ cl_invoke(assert_output("combined", "tap", 9, "-t", NULL));
322
}
323
324
void test_selftest__suite_names(void)
325
{
272
- cl_invoke(run("suite_names", 0, "-l", NULL));
326
+ cl_invoke(assert_output("combined", "suite_names", 0, "-l", NULL));
327
}
328
329
void test_selftest__summary_without_filename(void)
330
{
331
struct stat st;
278
- cl_invoke(run("summary_without_filename", 10, "-r", NULL));
332
+ cl_invoke(assert_output("combined", "summary_without_filename", 9, "-r", NULL));
333
/* The summary contains timestamps, so we cannot verify its contents. */
334
cl_must_pass(stat("summary.xml", &st));
335
}
337
void test_selftest__summary_with_filename(void)
338
{
339
struct stat st;
286
- cl_invoke(run("summary_with_filename", 10, "-rdifferent.xml", NULL));
340
+ cl_invoke(assert_output("combined", "summary_with_filename", 9, "-rdifferent.xml", NULL));
341
/* The summary contains timestamps, so we cannot verify its contents. */
342
cl_must_pass(stat("different.xml", &st));
343
}
344
+
345
+void test_selftest__pointer_equal(void)
346
+{
347
+ const char *args[] = {
348
+ "-spointer::equal",
349
+ "-t"
350
+ };
351
+ char *output = execute("pointer", 0, args, 2);
352
+ cl_assert_equal_s(output,
353
+ "TAP version 13\n"
354
+ "# start of suite 1: pointer\n"
355
+ "ok 1 - pointer::equal\n"
356
+ "1..1\n"
357
+ );
358
+ free(output);
359
+}
360
+
361
+void test_selftest__pointer_unequal(void)
362
+{
363
+ const char *args[] = {
364
+ "-spointer::unequal",
365
+ };
366
+ char *output = execute("pointer", 1, args, 1);
367
+ cl_assert(output);
368
+ cl_assert(strstr(output, "Pointer mismatch: "));
369
+ free(output);
370
+}