2 * Copyright (c) 2003-2007 Tim Kientzle
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * Various utility routines useful for test programs.
28 * Each test program is linked against this file.
35 __FBSDID("$FreeBSD$");
37 /* Default is to crash and try to force a core dump on failure. */
38 static int dump_on_failure = 1;
39 /* Default is to print some basic information about each test. */
40 static int quiet_flag = 0;
41 /* Cumulative count of failures. */
42 static int failures = 0;
45 * My own implementation of the standard assert() macro emits the
46 * message in the same format as GCC (file:line: message).
47 * It also includes some additional useful information.
48 * This makes it a lot easier to skim through test failures in
51 * It also supports a few special features specifically to simplify
52 * libarchive test harnesses:
53 * failure(fmt, args) -- Stores a text string that gets
54 * printed if the following assertion fails, good for
55 * explaining subtle tests.
56 * assertA(a, cond) -- If the test fails, also prints out any error
57 * message stored in archive object 'a'.
59 static char msg[4096];
62 /* Common handling of failed tests. */
64 test_failed(struct archive *a)
69 fprintf(stderr, " Description: %s\n", msg);
73 fprintf(stderr, " archive error: %s\n", archive_error_string(a));
76 if (dump_on_failure) {
77 fprintf(stderr, " *** forcing core dump so failure can be debugged ***\n");
83 /* Set up a message to display only after a test fails. */
85 failure(const char *fmt, ...)
89 vsprintf(msg, fmt, ap);
93 /* Generic assert() just displays the failed condition. */
95 test_assert(const char *file, int line, int value, const char *condition, struct archive *a)
101 fprintf(stderr, "%s:%d: Assertion failed\n", file, line);
102 fprintf(stderr, " Condition: %s\n", condition);
106 /* assertEqualInt() displays the values of the two integers. */
108 test_assert_equal_int(const char *file, int line,
109 int v1, const char *e1, int v2, const char *e2, struct archive *a)
115 fprintf(stderr, "%s:%d: Assertion failed: Ints not equal\n",
117 fprintf(stderr, " %s=%d\n", e1, v1);
118 fprintf(stderr, " %s=%d\n", e2, v2);
122 /* assertEqualString() displays the values of the two strings. */
124 test_assert_equal_string(const char *file, int line,
125 const char *v1, const char *e1,
126 const char *v2, const char *e2,
129 if (v1 == NULL || v2 == NULL) {
134 } else if (strcmp(v1, v2) == 0) {
138 fprintf(stderr, "%s:%d: Assertion failed: Strings not equal\n",
140 fprintf(stderr, " %s = \"%s\"\n", e1, v1);
141 fprintf(stderr, " %s = \"%s\"\n", e2, v2);
145 /* assertEqualWString() displays the values of the two strings. */
147 test_assert_equal_wstring(const char *file, int line,
148 const wchar_t *v1, const char *e1,
149 const wchar_t *v2, const char *e2,
152 if (wcscmp(v1, v2) == 0) {
156 fprintf(stderr, "%s:%d: Assertion failed: Unicode strings not equal\n",
158 fwprintf(stderr, L" %s = \"%ls\"\n", e1, v1);
159 fwprintf(stderr, L" %s = \"%ls\"\n", e2, v2);
164 * "list.h" is automatically generated; it just has a lot of lines like:
165 * DEFINE_TEST(function_name)
166 * The common "test.h" includes it to declare all of the test functions.
167 * We reuse it here to define a list of all tests to run.
170 #define DEFINE_TEST(n) { n, #n },
171 struct { void (*func)(void); const char *name; } tests[] = {
175 static int test_run(int i, const char *tmpdir)
177 int failures_before = failures;
180 printf("%d: %s\n", i, tests[i].name);
182 * Always explicitly chdir() in case the last test moved us to
187 "ERROR: Couldn't chdir to temp dir %s\n",
191 /* Create a temp directory for this specific test. */
192 if (mkdir(tests[i].name, 0755)) {
194 "ERROR: Couldn't create temp dir ``%s''\n",
198 if (chdir(tests[i].name)) {
200 "ERROR: Couldn't chdir to temp dir ``%s''\n",
205 return (failures - failures_before);
208 static void usage(void)
210 static const int limit = sizeof(tests) / sizeof(tests[0]);
213 printf("Usage: libarchive_test [options] <test> <test> ...\n");
214 printf("Default is to run all tests.\n");
215 printf("Otherwise, specify the numbers of the tests you wish to run.\n");
216 printf("Options:\n");
217 printf(" -k Keep running after failures.\n");
218 printf(" Default: Core dump after any failure.\n");
219 printf(" -q Quiet.\n");
220 printf("Available tests:\n");
221 for (i = 0; i < limit; i++)
222 printf(" %d: %s\n", i, tests[i].name);
226 int main(int argc, char **argv)
228 static const int limit = sizeof(tests) / sizeof(tests[0]);
229 int i, tests_run = 0, tests_succeeded = 0, opt;
233 while ((opt = getopt(argc, argv, "kq")) != -1) {
250 * Create a temp directory for the following tests.
251 * Include the time the tests started as part of the name,
252 * to make it easier to track the results of multiple tests.
255 for (i = 0; i < 1000; i++) {
256 strftime(tmpdir, sizeof(tmpdir),
257 "/tmp/libarchive_test.%Y-%m-%dT%H.%M.%S",
259 sprintf(tmpdir + strlen(tmpdir), "-%03d", i);
260 if (mkdir(tmpdir,0755) == 0)
264 fprintf(stderr, "ERROR: Unable to create temp directory %s\n",
269 printf("Running libarchive tests in: %s\n", tmpdir);
272 /* Default: Run all tests. */
273 for (i = 0; i < limit; i++) {
274 if (test_run(i, tmpdir) == 0)
279 while (*(++argv) != NULL) {
281 if (**argv < '0' || **argv > '9' || i < 0 || i >= limit) {
282 printf("*** INVALID Test %s\n", *argv);
285 if (test_run(i, tmpdir) == 0)
292 printf("%d of %d tests succeeded.\n", tests_succeeded, tests_run);
293 return (tests_succeeded == tests_run ? 0 : 1);