#define DEFINE_TEST(name) void name(void);
#include "list.h"
-/* Interix doesn't define these in a standard header. */
-#if __INTERIX__
-extern char *optarg;
-extern int optind;
-#endif
-
/* Enable core dump on failure. */
static int dump_on_failure = 0;
/* Default is to remove temp dirs for successful tests. */
* printed if the following assertion fails, good for
* explaining subtle tests.
*/
-static char msg[4096];
+static char msgbuff[4096];
+static const char *msg, *nextmsg;
/*
* For each test source file, we remember how many times each
*/
static const char *failed_filename = NULL;
static struct line {
- int line;
int count;
- int critical;
-} failed_lines[1000];
+ int skip;
+} failed_lines[10000];
/*
* Called at the beginning of each assert() function.
(void)file; /* UNUSED */
(void)line; /* UNUSED */
++assertions;
+ msg = nextmsg;
+ nextmsg = NULL;
/* Uncomment to print file:line after every assertion.
* Verbose, but occasionally useful in tracking down crashes. */
/* printf("Checked %s:%d\n", file, line); */
}
/*
- * Count this failure; return the number of previous failures.
+ * Count this failure; return true if this failure is being reported.
*/
static int
-previous_failures(const char *filename, int line, int critical)
+report_failure(const char *filename, int line, const char *fmt, ...)
{
- unsigned int i;
- int count;
+ ++failures;
+ /* If this is a new file, clear the counts. */
if (failed_filename == NULL || strcmp(failed_filename, filename) != 0)
memset(failed_lines, 0, sizeof(failed_lines));
failed_filename = filename;
- for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].line == line) {
- count = failed_lines[i].count;
- failed_lines[i].count++;
- return (count);
- }
- if (failed_lines[i].line == 0) {
- failed_lines[i].line = line;
- failed_lines[i].count = 1;
- failed_lines[i].critical = critical;
- return (0);
- }
+ /* Report first hit always, every hit if verbose. */
+ if (failed_lines[line].count++ == 0 || verbose) {
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d: ", filename, line);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ return (1);
}
return (0);
}
+/* Complete reporting of failed tests. */
+static void
+finish_failure(void *extra)
+{
+ if (msg != NULL && msg[0] != '\0')
+ fprintf(stderr, " Description: %s\n", msg);
+
+#ifdef EXTRA_DUMP
+ if (extra != NULL)
+ fprintf(stderr, " detail: %s\n", EXTRA_DUMP(extra));
+#else
+ (void)extra; /* UNUSED */
+#endif
+
+ if (dump_on_failure) {
+ fprintf(stderr,
+ " *** forcing core dump so failure can be debugged ***\n");
+ *(char *)(NULL) = 0;
+ exit(1);
+ }
+}
+
/*
* Copy arguments into file-local variables.
*/
{
va_list ap;
- if (previous_failures(test_filename, test_line, 0))
- return;
-
- va_start(ap, fmt);
- fprintf(stderr, " *** SKIPPING: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- ++skips;
-}
-
-/* Common handling of failed tests. */
-static void
-report_failure(void *extra)
-{
- if (msg[0] != '\0') {
- fprintf(stderr, " Description: %s\n", msg);
- msg[0] = '\0';
- }
-
-#ifdef EXTRA_DUMP
- if (extra != NULL)
- fprintf(stderr, " detail: %s\n", EXTRA_DUMP(extra));
-#else
- (void)extra; /* UNUSED */
-#endif
-
- if (dump_on_failure) {
- fprintf(stderr,
- " *** forcing core dump so failure can be debugged ***\n");
- *(char *)(NULL) = 0;
- exit(1);
+ if (report_failure(test_filename, test_line, "SKIPPING" )) {
+ va_start(ap,fmt);
+ fprintf(stderr, " Reason: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ /* Don't finish_failure() here. */
}
+ /* Mark as skip, so doesn't count as failed test. */
+ failed_lines[test_line].skip = 1;
+ ++skips;
+ --failures;
}
/*
* The reports above suppress multiple failures from the same source
* line; this reports on any tests that did fail multiple times.
*/
-static int
-summarize_comparator(const void *a0, const void *b0)
-{
- const struct line *a = a0, *b = b0;
- if (a->line == 0 && b->line == 0)
- return (0);
- if (a->line == 0)
- return (1);
- if (b->line == 0)
- return (-1);
- return (a->line - b->line);
-}
-
static void
summarize(void)
{
unsigned int i;
- qsort(failed_lines, sizeof(failed_lines)/sizeof(failed_lines[0]),
- sizeof(failed_lines[0]), summarize_comparator);
for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].line == 0)
+ if (failed_lines[i].count == 0)
break;
- if (failed_lines[i].count > 1 && failed_lines[i].critical)
+ if (failed_lines[i].count > 1 && !failed_lines[i].skip)
fprintf(stderr, "%s:%d: Failed %d times\n",
- failed_filename, failed_lines[i].line,
- failed_lines[i].count);
+ failed_filename, i, failed_lines[i].count);
}
/* Clear the failure history for the next file. */
memset(failed_lines, 0, sizeof(failed_lines));
{
va_list ap;
va_start(ap, fmt);
- vsprintf(msg, fmt, ap);
+ vsprintf(msgbuff, fmt, ap);
va_end(ap);
+ nextmsg = msgbuff;
}
/* Generic assert() just displays the failed condition. */
int
-test_assert(const char *file, int line, int value, const char *condition, void *extra)
+test_assert(const char *file, int line, int value,
+ const char *condition, void *extra)
{
count_assertion(file, line);
- if (value) {
- msg[0] = '\0';
+ if (value)
return (value);
+ if (report_failure(file, line, "Assertion failed: %s", condition)) {
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (value);
- fprintf(stderr, "%s:%d: Assertion failed\n", file, line);
- fprintf(stderr, " Condition: %s\n", condition);
- report_failure(extra);
return (value);
}
count_assertion(file, line);
if (chdir(pathname) == 0)
return (1);
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: chdir(\"%s\") failed\n",
- file, line, pathname);
+ if (report_failure(file, line, "chdir(\"%s\")", pathname)) {
+ finish_failure(NULL);
+ }
return (0);
}
long long v1, const char *e1, long long v2, const char *e2, void *extra)
{
count_assertion(file, line);
- if (v1 == v2) {
- msg[0] = '\0';
+ if (v1 == v2)
return (1);
+ if (report_failure(file, line, "Ints not equal")) {
+ fprintf(stderr, " %s=%lld\n", e1, v1);
+ fprintf(stderr, " %s=%lld\n", e2, v2);
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Ints not equal\n",
- file, line);
- fprintf(stderr, " %s=%lld\n", e1, v1);
- fprintf(stderr, " %s=%lld\n", e2, v2);
- report_failure(extra);
return (0);
}
-static void strdump(const char *p)
+static void strdump(const char *e, const char *p)
{
+ fprintf(stderr, " %s = ", e);
if (p == NULL) {
fprintf(stderr, "(null)");
return;
}
}
fprintf(stderr, "\"");
+ fprintf(stderr, " (length %d)\n", p == NULL ? 0 : (int)strlen(p));
}
/* assertEqualString() displays the values of the two strings. */
void *extra)
{
count_assertion(file, line);
- if (v1 == NULL || v2 == NULL) {
- if (v1 == v2) {
- msg[0] = '\0';
- return (1);
- }
- } else if (strcmp(v1, v2) == 0) {
- msg[0] = '\0';
+ if (v1 == v2)
+ return (1);
+ else if (strcmp(v1, v2) == 0)
return (1);
+ if (report_failure(file, line, "Strings not equal")) {
+ strdump(e1, v1);
+ strdump(e2, v2);
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Strings not equal\n",
- file, line);
- fprintf(stderr, " %s = ", e1);
- strdump(v1);
- fprintf(stderr, " (length %d)\n", v1 == NULL ? 0 : (int)strlen(v1));
- fprintf(stderr, " %s = ", e2);
- strdump(v2);
- fprintf(stderr, " (length %d)\n", v2 == NULL ? 0 : (int)strlen(v2));
- report_failure(extra);
return (0);
}
-static void wcsdump(const wchar_t *w)
+static void wcsdump(const char *e, const wchar_t *w)
{
+ fprintf(stderr, " %s = ", e);
if (w == NULL) {
fprintf(stderr, "(null)");
return;
else
fprintf(stderr, "\\U%08X", c);
}
- fprintf(stderr, "\"");
+ fprintf(stderr, "\"\n");
}
/* assertEqualWString() displays the values of the two strings. */
void *extra)
{
count_assertion(file, line);
- if (v1 == NULL) {
- if (v2 == NULL) {
- msg[0] = '\0';
- return (1);
- }
- } else if (v2 == NULL) {
- if (v1 == NULL) {
- msg[0] = '\0';
- return (1);
- }
- } else if (wcscmp(v1, v2) == 0) {
- msg[0] = '\0';
+ if (v1 == v2)
+ return (1);
+ else if (wcscmp(v1, v2) == 0)
return (1);
+ if (report_failure(file, line, "Unicode strings not equal")) {
+ wcsdump(e1, v1);
+ wcsdump(e2, v2);
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Unicode strings not equal\n",
- file, line);
- fprintf(stderr, " %s = ", e1);
- wcsdump(v1);
- fprintf(stderr, "\n");
- fprintf(stderr, " %s = ", e2);
- wcsdump(v2);
- fprintf(stderr, "\n");
- report_failure(extra);
return (0);
}
size_t offset;
count_assertion(file, line);
- if (v1 == NULL || v2 == NULL) {
- if (v1 == v2) {
- msg[0] = '\0';
- return (1);
- }
- } else if (memcmp(v1, v2, l) == 0) {
- msg[0] = '\0';
+ if (v1 == v2)
+ return (1);
+ else if (memcmp(v1, v2, l) == 0)
return (1);
+ if (report_failure(file, line, "Memory not equal")) {
+ fprintf(stderr, " size %s = %d\n", ld, (int)l);
+ /* Dump 48 bytes (3 lines) so that the first difference is
+ * in the second line. */
+ offset = 0;
+ while (l > 64 && memcmp(v1, v2, 32) == 0) {
+ /* Two lines agree, so step forward one line. */
+ v1 += 16;
+ v2 += 16;
+ l -= 16;
+ offset += 16;
+ }
+ fprintf(stderr, " Dump of %s\n", e1);
+ hexdump(v1, v2, l < 64 ? l : 64, offset);
+ fprintf(stderr, " Dump of %s\n", e2);
+ hexdump(v2, v1, l < 64 ? l : 64, offset);
+ fprintf(stderr, "\n");
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: memory not equal\n",
- file, line);
- fprintf(stderr, " size %s = %d\n", ld, (int)l);
- /* Dump 48 bytes (3 lines) so that the first difference is
- * in the second line. */
- offset = 0;
- while (l > 64 && memcmp(v1, v2, 32) == 0) {
- /* The first two lines agree, so step forward one line. */
- v1 += 16;
- v2 += 16;
- l -= 16;
- offset += 16;
- }
- fprintf(stderr, " Dump of %s\n", e1);
- hexdump(v1, v2, l < 64 ? l : 64, offset);
- fprintf(stderr, " Dump of %s\n", e2);
- hexdump(v2, v1, l < 64 ? l : 64, offset);
- fprintf(stderr, "\n");
- report_failure(extra);
return (0);
}
ssize_t s;
FILE *f;
-
+ count_assertion(test_filename, test_line);
va_start(ap, f1fmt);
vsprintf(f1, f1fmt, ap);
va_end(ap);
if (stat(f1, &st) != 0) {
- fprintf(stderr, "%s:%d: Could not stat: %s\n", test_filename, test_line, f1);
- report_failure(NULL);
+ if (report_failure(test_filename, test_line, "Stat failed: %s", f1)) {
+ finish_failure(NULL);
+ }
return (0);
}
if (st.st_size == 0)
return (1);
- ++failures;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
-
- fprintf(stderr, "%s:%d: File not empty: %s\n", test_filename, test_line, f1);
- fprintf(stderr, " File size: %d\n", (int)st.st_size);
- fprintf(stderr, " Contents:\n");
- f = fopen(f1, "rb");
- if (f == NULL) {
- fprintf(stderr, " Unable to open %s\n", f1);
- } else {
- s = ((off_t)sizeof(buff) < st.st_size) ?
- (ssize_t)sizeof(buff) : (ssize_t)st.st_size;
- s = fread(buff, 1, s, f);
- hexdump(buff, NULL, s, 0);
- fclose(f);
+ if (report_failure(test_filename, test_line, "%s not empty", f1)) {
+ fprintf(stderr, " File size: %d\n", (int)st.st_size);
+ fprintf(stderr, " Contents:\n");
+ f = fopen(f1, "rb");
+ if (f == NULL) {
+ fprintf(stderr, " Unable to open %s\n", f1);
+ } else {
+ s = ((off_t)sizeof(buff) < st.st_size) ?
+ (ssize_t)sizeof(buff) : (ssize_t)st.st_size;
+ s = fread(buff, 1, s, f);
+ hexdump(buff, NULL, s, 0);
+ fclose(f);
+ }
+ finish_failure(NULL);
}
- report_failure(NULL);
return (0);
}
struct stat st;
va_list ap;
-
+ count_assertion(test_filename, test_line);
va_start(ap, f1fmt);
vsprintf(f1, f1fmt, ap);
va_end(ap);
if (stat(f1, &st) != 0) {
- fprintf(stderr, "%s:%d: Could not stat: %s\n",
- test_filename, test_line, f1);
- report_failure(NULL);
- ++failures;
+ if (report_failure(test_filename, test_line, "Stat failed: %s", f1))
+ finish_failure(NULL);
return (0);
}
if (st.st_size != 0)
return (1);
-
- ++failures;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
-
- fprintf(stderr, "%s:%d: File empty: %s\n",
- test_filename, test_line, f1);
- report_failure(NULL);
+ if (report_failure(test_filename, test_line, "File empty: %s", f1))
+ finish_failure(NULL);
return (0);
}
FILE *f1, *f2;
int n1, n2;
+ count_assertion(test_filename, test_line);
va_start(ap, f2pattern);
vsprintf(fn2, f2pattern, ap);
va_end(ap);
}
fclose(f1);
fclose(f2);
- ++failures;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Files are not identical\n",
- test_filename, test_line);
- fprintf(stderr, " file1=\"%s\"\n", fn1);
- fprintf(stderr, " file2=\"%s\"\n", fn2);
- report_failure(test_extra);
+ if (report_failure(test_filename, test_line, "Files not identical")) {
+ fprintf(stderr, " file1=\"%s\"\n", fn1);
+ fprintf(stderr, " file2=\"%s\"\n", fn2);
+ finish_failure(test_extra);
+ }
return (0);
}
if (!access(f, F_OK))
return (1);
#endif
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File doesn't exist\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "File doesn't exist")) {
fprintf(stderr, " file=\"%s\"\n", f);
- report_failure(test_extra);
+ finish_failure(test_extra);
}
return (0);
}
if (access(f, F_OK))
return (1);
#endif
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File exists and shouldn't\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "File exists")) {
fprintf(stderr, " file=\"%s\"\n", f);
- report_failure(test_extra);
+ finish_failure(test_extra);
}
return (0);
}
f = fopen(fn, "rb");
if (f == NULL) {
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File doesn't exist: %s\n",
- test_filename, test_line, fn);
- report_failure(test_extra);
+ if (report_failure(test_filename, test_line, "File doesn't exist: %s", fn)) {
+ finish_failure(test_extra);
}
return (0);
}
free(contents);
return (1);
}
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File contents don't match\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "File contents don't match")) {
fprintf(stderr, " file=\"%s\"\n", fn);
if (n > 0)
hexdump(contents, buff, n > 512 ? 512 : 0, 0);
fprintf(stderr, " File empty, contents should be:\n");
hexdump(buff, NULL, s > 512 ? 512 : 0, 0);
}
- report_failure(test_extra);
+ finish_failure(test_extra);
}
free(contents);
return (0);
}
if (*btxt == '\0' && *ftxt == '\0') {
free(contents);
- msg[0] = '\0';
return (1);
}
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File contents don't match\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "Contents don't match")) {
fprintf(stderr, " file=\"%s\"\n", fn);
if (n > 0)
hexdump(contents, buff, n, 0);
fprintf(stderr, " File empty, contents should be:\n");
hexdump(buff, NULL, s, 0);
}
- report_failure(test_extra);
+ finish_failure(test_extra);
}
free(contents);
- msg[0] = '\0';
return (0);
}
count_assertion(file, line);
r = lstat(path1, &st1);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1))
- fprintf(stderr, "%s:%d: File ``%s'' should exist\n",
- file, line, path1);
+ if (report_failure(file, line, "File %s should exist", path1))
+ finish_failure(NULL);
return (0);
}
r = lstat(path2, &st2);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1))
- fprintf(stderr, "%s:%d: File ``%s'' should exist\n",
- file, line, path2);
+ if (report_failure(file, line, "File %s should exist", path2))
+ finish_failure(NULL);
return (0);
}
if (st1.st_ino != st2.st_ino || st1.st_dev != st2.st_dev) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr,
- "%s:%d: Files ``%s'' and ``%s'' are not hardlinked\n",
- file, line, path1, path2);
- report_failure(NULL);
- }
+ if (report_failure(file, line,
+ "Files %s and %s are not hardlinked", path1, path2))
+ finish_failure(NULL);
return (0);
}
return (1);
r = lstat(pathname, &st);
if (r == 0 && st.st_nlink == nlinks)
return (1);
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: File ``%s'' has %d links, expected %d\n",
- file, line, pathname, st.st_nlink, nlinks);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "File %s has %d links, expected %d",
+ pathname, st.st_nlink, nlinks))
+ finish_failure(NULL);
return (0);
}
r = lstat(pathname, &st);
if (r == 0 && st.st_size == size)
return (1);
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: File ``%s'' has size %ld, expected %ld\n",
- file, line, pathname, (long)st.st_size, (long)size);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "File %s has size %ld, expected %ld",
+ pathname, (long)st.st_size, (long)size))
+ finish_failure(NULL);
return (0);
}
count_assertion(file, line);
r = lstat(pathname, &st);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Dir ``%s'' doesn't exist\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Dir %s doesn't exist", pathname))
+ finish_failure(NULL);
return (0);
}
if (!S_ISDIR(st.st_mode)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: ``%s'' is not a dir\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "%s is not a dir", pathname))
+ finish_failure(NULL);
return (0);
}
- if (mode < 0) {
- msg[0] = '\0';
+ if (mode < 0)
return (1);
- }
if (mode != (st.st_mode & 07777)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Dir ``%s'' has wrong mode\n",
- file, line, pathname);
+ if (report_failure(file, line, "Dir %s has wrong mode", pathname)) {
fprintf(stderr, " Expected: 0%3o\n", mode);
fprintf(stderr, " Found: 0%3o\n", st.st_mode & 07777);
- report_failure(NULL);
+ finish_failure(NULL);
}
return (0);
}
- msg[0] = '\0';
return (1);
}
const char *pathname, const char *contents)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
+ count_assertion(file, line);
// TODO: Vista supports symlinks
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Symlink ``%s'' not supported\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Symlink %s not supported", pathname))
+ finish_failure(NULL);
return (0);
#else
char buff[300];
count_assertion(file, line);
r = lstat(pathname, &st);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Symlink ``%s'' doesn't exist\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Symlink %s doesn't exist", pathname))
+ finish_failure(NULL);
return (0);
}
if (!S_ISLNK(st.st_mode)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: ``%s'' should be a symlink\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "%s should be a symlink", pathname))
+ finish_failure(NULL);
return (0);
}
if (contents == NULL)
return (1);
linklen = readlink(pathname, buff, sizeof(buff));
if (linklen < 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: symlink ``%s'' can't be read\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Can't read symlink %s", pathname))
+ finish_failure(NULL);
return (0);
}
buff[linklen] = '\0';
if (strcmp(buff, contents) != 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Wrong symlink ``%s''\n",
- file, line, pathname);
+ if (report_failure(file, line, "Wrong symlink %s", pathname)) {
fprintf(stderr, " Expected: %s\n", contents);
fprintf(stderr, " Found: %s\n", buff);
- report_failure(NULL);
+ finish_failure(NULL);
}
return (0);
}
count_assertion(file, line);
r = lstat(pathname, &st);
if (r != 0 || !S_ISREG(st.st_mode)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: File ``%s'' doesn't exist\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "File %s doesn't exist", pathname))
+ finish_failure(NULL);
return (0);
}
if (mode < 0)
return (1);
if (mode != (st.st_mode & 07777)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: File ``%s'' has wrong mode\n",
- file, line, pathname);
+ if (report_failure(file, line, "File %s has wrong mode", pathname)) {
fprintf(stderr, " Expected: 0%3o\n", mode);
fprintf(stderr, " Found: 0%3o\n", st.st_mode & 07777);
- report_failure(NULL);
+ finish_failure(NULL);
}
return (0);
}
int
test_assert_make_dir(const char *file, int line, const char *dirname, int mode)
{
- int r;
-
count_assertion(file, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
- r = _mkdir(dirname);
+ if (0 == _mkdir(dirname))
+ return (1);
#else
- r = mkdir(dirname, mode);
-#endif
- if (r == 0) {
- msg[0] = '\0';
+ if (0 == mkdir(dirname, mode))
return (1);
- }
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Could not create directory\n",
- file, line);
- fprintf(stderr, " Dirname: %s\n", dirname);
+#endif
+ if (report_failure(file, line, "Could not create directory %s", dirname))
+ finish_failure(NULL);
return(0);
}
#if defined(_WIN32) && !defined(__CYGWIN__)
/* TODO: Rework this to set file mode as well. */
FILE *f;
+ count_assertion(file, line);
f = fopen(path, "wb");
if (f == NULL) {
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Could not create file ``%s''\n",
- file, line, path);
+ if (report_failure(file, line, "Could not create file %s", path))
+ finish_failure(NULL);
return (0);
}
if (contents != NULL) {
if (strlen(contents)
!= fwrite(contents, 1, strlen(contents), f)) {
fclose(f);
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Could not write file ``%s''\n",
- file, line, path);
+ if (report_failure(file, line, "Could not write file %s", path))
+ finish_failure(NULL);
return (0);
}
}
fclose(f);
- msg[0] = '\0';
return (1);
#else
int fd;
count_assertion(file, line);
fd = open(path, O_CREAT | O_WRONLY, mode >= 0 ? mode : 0644);
if (fd < 0) {
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Could not create file ``%s''\n",
- file, line, path);
+ if (report_failure(file, line, "Could not create %s", path))
+ finish_failure(NULL);
return (0);
}
if (contents != NULL) {
if ((ssize_t)strlen(contents)
!= write(fd, contents, strlen(contents))) {
close(fd);
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Could not write file ``%s''\n",
- file, line, path);
+ if (report_failure(file, line, "Could not write to %s", path))
+ finish_failure(NULL);
return (0);
}
}
close(fd);
- msg[0] = '\0';
return (1);
#endif
}
#else
succeeded = 0;
#endif
- if (succeeded) {
- msg[0] = '\0';
+ if (succeeded)
return (1);
- }
- ++failures;
- if (verbose || !previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Could not create new hardlink\n",
- file, line);
+ if (report_failure(file, line, "Could not create hardlink")) {
fprintf(stderr, " New link: %s\n", newpath);
fprintf(stderr, " Old name: %s\n", linkto);
+ finish_failure(NULL);
}
return(0);
}
test_assert_make_symlink(const char *file, int line,
const char *newpath, const char *linkto)
{
- int succeeded;
-
#if HAVE_CREATESYMBOLICLINK
int targetIsDir = 0; /* TODO: Fix this. */
count_assertion(file, line);
- succeeded = CreateSymbolicLink(newpath, linkto, targetIsDir);
+ if (CreateSymbolicLink(newpath, linkto, targetIsDir))
+ return (1);
#elif HAVE_SYMLINK
count_assertion(file, line);
- succeeded = !symlink(linkto, newpath);
-#else
- succeeded = 0;
-#endif
- if (succeeded) {
- msg[0] = '\0';
+ if (0 == symlink(linkto, newpath))
return (1);
- }
- ++failures;
- if (verbose || !previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Could not create new symlink\n",
- file, line);
+#endif
+ if (report_failure(file, line, "Could not create symlink")) {
fprintf(stderr, " New link: %s\n", newpath);
fprintf(stderr, " Old name: %s\n", linkto);
+ finish_failure(NULL);
}
return(0);
}
return (1);
}
+void
+sleepUntilAfter(time_t t)
+{
+ while (t >= time(NULL))
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ Sleep(500);
+#else
+ sleep(1);
+#endif
+}
+
/*
* Call standard system() call, but build up the command line using
* sprintf() conventions.
return (tests_failed);
}
-
-void
-sleepUntilAfter(time_t t)
-{
- /* If utime() is supported above, there's no sleep here which
- * makes the test faster. */
- while (t >= time(NULL))
-#if defined(_WIN32) && !defined(__CYGWIN__)
- Sleep(500);
-#else
- sleep(1);
-#endif
-}
#endif
#endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
/*
* Redefine DEFINE_TEST for use in defining the test functions.
*/
* $FreeBSD: src/lib/libarchive/config_freebsd.h,v 1.15 2008/09/30 03:53:03 kientzle Exp $
*/
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
/* FreeBSD 5.0 and later have ACL and extattr support. */
#if __FreeBSD__ > 4
#define HAVE_ACL_CREATE_ENTRY 1
#define HAVE_DECL_STRERROR_R 1
#define HAVE_DECL_UINT32_MAX 1
#define HAVE_DECL_UINT64_MAX 1
+#define HAVE_DIRENT_H 1
#define HAVE_EFTYPE 1
#define HAVE_EILSEQ 1
#define HAVE_ERRNO_H 1
#endif
#include <io.h>
#include <windows.h>
+#include <winbase.h>
#ifndef F_OK
#define F_OK (0)
#endif
#define umask _umask
#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
-void *GetFunctionKernel32(const char *name)
-{
- static HINSTANCE lib;
- static int set;
- if (!set) {
- set = 1;
- lib = LoadLibrary("kernel32.dll");
- }
- if (lib == NULL) {
- fprintf(stderr, "Can't load kernel32.dll?!\n");
- return NULL;
- }
- return (void *)GetProcAddress(lib, name);
-}
-
-int __CreateSymbolicLinkA(const char *linkname, const char *target, int flags)
-{
- static BOOLEAN (*f)(LPCSTR, LPCSTR, DWORD);
- static int set;
- if (!set) {
- set = 1;
- f = GetFunctionKernel32("CreateSymbolicLinkA");
- }
- return f == NULL ? 0 : (*f)(linkname, target, flags);
-}
-
-int __CreateHardLinkA(const char *linkname, const char *target)
-{
- static BOOLEAN (*f)(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES);
- static int set;
- if (!set) {
- set = 1;
- f = GetFunctionKernel32("CreateHardLinkA");
- }
- if (f == NULL)
- return 0;
- return (*f)(linkname, target, NULL);
-}
-#endif
-
/*
* This same file is used pretty much verbatim for all test harnesses.
*
#define DEFINE_TEST(name) void name(void);
#include "list.h"
-/* Interix doesn't define these in a standard header. */
-#if __INTERIX__
-extern char *optarg;
-extern int optind;
-#endif
-
/* Enable core dump on failure. */
static int dump_on_failure = 0;
/* Default is to remove temp dirs for successful tests. */
* printed if the following assertion fails, good for
* explaining subtle tests.
*/
-static char msg[4096];
+static char msgbuff[4096];
+static const char *msg, *nextmsg;
/*
* For each test source file, we remember how many times each
*/
static const char *failed_filename = NULL;
static struct line {
- int line;
int count;
- int critical;
-} failed_lines[1000];
+ int skip;
+} failed_lines[10000];
/*
* Called at the beginning of each assert() function.
(void)file; /* UNUSED */
(void)line; /* UNUSED */
++assertions;
+ msg = nextmsg;
+ nextmsg = NULL;
/* Uncomment to print file:line after every assertion.
* Verbose, but occasionally useful in tracking down crashes. */
/* printf("Checked %s:%d\n", file, line); */
}
/*
- * Count this failure; return the number of previous failures.
+ * Count this failure; return true if this failure is being reported.
*/
static int
-previous_failures(const char *filename, int line, int critical)
+report_failure(const char *filename, int line, const char *fmt, ...)
{
- unsigned int i;
- int count;
+ ++failures;
+ /* If this is a new file, clear the counts. */
if (failed_filename == NULL || strcmp(failed_filename, filename) != 0)
memset(failed_lines, 0, sizeof(failed_lines));
failed_filename = filename;
- for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].line == line) {
- count = failed_lines[i].count;
- failed_lines[i].count++;
- return (count);
- }
- if (failed_lines[i].line == 0) {
- failed_lines[i].line = line;
- failed_lines[i].count = 1;
- failed_lines[i].critical = critical;
- return (0);
- }
+ /* Report first hit always, every hit if verbose. */
+ if (failed_lines[line].count++ == 0 || verbose) {
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d: ", filename, line);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ return (1);
}
return (0);
}
+/* Complete reporting of failed tests. */
+static void
+finish_failure(void *extra)
+{
+ if (msg != NULL && msg[0] != '\0')
+ fprintf(stderr, " Description: %s\n", msg);
+
+#ifdef EXTRA_DUMP
+ if (extra != NULL)
+ fprintf(stderr, " detail: %s\n", EXTRA_DUMP(extra));
+#else
+ (void)extra; /* UNUSED */
+#endif
+
+ if (dump_on_failure) {
+ fprintf(stderr,
+ " *** forcing core dump so failure can be debugged ***\n");
+ *(char *)(NULL) = 0;
+ exit(1);
+ }
+}
+
/*
* Copy arguments into file-local variables.
*/
{
va_list ap;
- if (previous_failures(test_filename, test_line, 0))
- return;
-
- va_start(ap, fmt);
- fprintf(stderr, " *** SKIPPING: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- ++skips;
-}
-
-/* Common handling of failed tests. */
-static void
-report_failure(void *extra)
-{
- if (msg[0] != '\0') {
- fprintf(stderr, " Description: %s\n", msg);
- msg[0] = '\0';
- }
-
-#ifdef EXTRA_DUMP
- if (extra != NULL)
- fprintf(stderr, " detail: %s\n", EXTRA_DUMP(extra));
-#else
- (void)extra; /* UNUSED */
-#endif
-
- if (dump_on_failure) {
- fprintf(stderr,
- " *** forcing core dump so failure can be debugged ***\n");
- *(char *)(NULL) = 0;
- exit(1);
+ if (report_failure(test_filename, test_line, "SKIPPING" )) {
+ va_start(ap,fmt);
+ fprintf(stderr, " Reason: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ /* Don't finish_failure() here. */
}
+ /* Mark as skip, so doesn't count as failed test. */
+ failed_lines[test_line].skip = 1;
+ ++skips;
+ --failures;
}
/*
* The reports above suppress multiple failures from the same source
* line; this reports on any tests that did fail multiple times.
*/
-static int
-summarize_comparator(const void *a0, const void *b0)
-{
- const struct line *a = a0, *b = b0;
- if (a->line == 0 && b->line == 0)
- return (0);
- if (a->line == 0)
- return (1);
- if (b->line == 0)
- return (-1);
- return (a->line - b->line);
-}
-
static void
summarize(void)
{
unsigned int i;
- qsort(failed_lines, sizeof(failed_lines)/sizeof(failed_lines[0]),
- sizeof(failed_lines[0]), summarize_comparator);
for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].line == 0)
+ if (failed_lines[i].count == 0)
break;
- if (failed_lines[i].count > 1 && failed_lines[i].critical)
+ if (failed_lines[i].count > 1 && !failed_lines[i].skip)
fprintf(stderr, "%s:%d: Failed %d times\n",
- failed_filename, failed_lines[i].line,
- failed_lines[i].count);
+ failed_filename, i, failed_lines[i].count);
}
/* Clear the failure history for the next file. */
memset(failed_lines, 0, sizeof(failed_lines));
{
va_list ap;
va_start(ap, fmt);
- vsprintf(msg, fmt, ap);
+ vsprintf(msgbuff, fmt, ap);
va_end(ap);
+ nextmsg = msgbuff;
}
/* Generic assert() just displays the failed condition. */
int
-test_assert(const char *file, int line, int value, const char *condition, void *extra)
+test_assert(const char *file, int line, int value,
+ const char *condition, void *extra)
{
count_assertion(file, line);
- if (value) {
- msg[0] = '\0';
+ if (value)
return (value);
+ if (report_failure(file, line, "Assertion failed: %s", condition)) {
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (value);
- fprintf(stderr, "%s:%d: Assertion failed\n", file, line);
- fprintf(stderr, " Condition: %s\n", condition);
- report_failure(extra);
return (value);
}
count_assertion(file, line);
if (chdir(pathname) == 0)
return (1);
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: chdir(\"%s\") failed\n",
- file, line, pathname);
+ if (report_failure(file, line, "chdir(\"%s\")", pathname)) {
+ finish_failure(NULL);
+ }
return (0);
}
long long v1, const char *e1, long long v2, const char *e2, void *extra)
{
count_assertion(file, line);
- if (v1 == v2) {
- msg[0] = '\0';
+ if (v1 == v2)
return (1);
+ if (report_failure(file, line, "Ints not equal")) {
+ fprintf(stderr, " %s=%lld\n", e1, v1);
+ fprintf(stderr, " %s=%lld\n", e2, v2);
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Ints not equal\n",
- file, line);
- fprintf(stderr, " %s=%lld\n", e1, v1);
- fprintf(stderr, " %s=%lld\n", e2, v2);
- report_failure(extra);
return (0);
}
-static void strdump(const char *p)
+static void strdump(const char *e, const char *p)
{
+ fprintf(stderr, " %s = ", e);
if (p == NULL) {
fprintf(stderr, "(null)");
return;
}
}
fprintf(stderr, "\"");
+ fprintf(stderr, " (length %d)\n", p == NULL ? 0 : (int)strlen(p));
}
/* assertEqualString() displays the values of the two strings. */
void *extra)
{
count_assertion(file, line);
- if (v1 == NULL || v2 == NULL) {
- if (v1 == v2) {
- msg[0] = '\0';
- return (1);
- }
- } else if (strcmp(v1, v2) == 0) {
- msg[0] = '\0';
+ if (v1 == v2)
+ return (1);
+ else if (strcmp(v1, v2) == 0)
return (1);
+ if (report_failure(file, line, "Strings not equal")) {
+ strdump(e1, v1);
+ strdump(e2, v2);
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Strings not equal\n",
- file, line);
- fprintf(stderr, " %s = ", e1);
- strdump(v1);
- fprintf(stderr, " (length %d)\n", v1 == NULL ? 0 : (int)strlen(v1));
- fprintf(stderr, " %s = ", e2);
- strdump(v2);
- fprintf(stderr, " (length %d)\n", v2 == NULL ? 0 : (int)strlen(v2));
- report_failure(extra);
return (0);
}
-static void wcsdump(const wchar_t *w)
+static void wcsdump(const char *e, const wchar_t *w)
{
+ fprintf(stderr, " %s = ", e);
if (w == NULL) {
fprintf(stderr, "(null)");
return;
else
fprintf(stderr, "\\U%08X", c);
}
- fprintf(stderr, "\"");
+ fprintf(stderr, "\"\n");
}
/* assertEqualWString() displays the values of the two strings. */
void *extra)
{
count_assertion(file, line);
- if (v1 == NULL) {
- if (v2 == NULL) {
- msg[0] = '\0';
- return (1);
- }
- } else if (v2 == NULL) {
- if (v1 == NULL) {
- msg[0] = '\0';
- return (1);
- }
- } else if (wcscmp(v1, v2) == 0) {
- msg[0] = '\0';
+ if (v1 == v2)
return (1);
+ else if (wcscmp(v1, v2) == 0)
+ return (1);
+ if (report_failure(file, line, "Unicode strings not equal")) {
+ wcsdump(e1, v1);
+ wcsdump(e2, v2);
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Unicode strings not equal\n",
- file, line);
- fprintf(stderr, " %s = ", e1);
- wcsdump(v1);
- fprintf(stderr, "\n");
- fprintf(stderr, " %s = ", e2);
- wcsdump(v2);
- fprintf(stderr, "\n");
- report_failure(extra);
return (0);
}
size_t offset;
count_assertion(file, line);
- if (v1 == NULL || v2 == NULL) {
- if (v1 == v2) {
- msg[0] = '\0';
- return (1);
- }
- } else if (memcmp(v1, v2, l) == 0) {
- msg[0] = '\0';
+ if (v1 == v2)
+ return (1);
+ else if (memcmp(v1, v2, l) == 0)
return (1);
+ if (report_failure(file, line, "Memory not equal")) {
+ fprintf(stderr, " size %s = %d\n", ld, (int)l);
+ /* Dump 48 bytes (3 lines) so that the first difference is
+ * in the second line. */
+ offset = 0;
+ while (l > 64 && memcmp(v1, v2, 32) == 0) {
+ /* Two lines agree, so step forward one line. */
+ v1 += 16;
+ v2 += 16;
+ l -= 16;
+ offset += 16;
+ }
+ fprintf(stderr, " Dump of %s\n", e1);
+ hexdump(v1, v2, l < 64 ? l : 64, offset);
+ fprintf(stderr, " Dump of %s\n", e2);
+ hexdump(v2, v1, l < 64 ? l : 64, offset);
+ fprintf(stderr, "\n");
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: memory not equal\n",
- file, line);
- fprintf(stderr, " size %s = %d\n", ld, (int)l);
- /* Dump 48 bytes (3 lines) so that the first difference is
- * in the second line. */
- offset = 0;
- while (l > 64 && memcmp(v1, v2, 32) == 0) {
- /* The first two lines agree, so step forward one line. */
- v1 += 16;
- v2 += 16;
- l -= 16;
- offset += 16;
- }
- fprintf(stderr, " Dump of %s\n", e1);
- hexdump(v1, v2, l < 64 ? l : 64, offset);
- fprintf(stderr, " Dump of %s\n", e2);
- hexdump(v2, v1, l < 64 ? l : 64, offset);
- fprintf(stderr, "\n");
- report_failure(extra);
return (0);
}
ssize_t s;
FILE *f;
-
+ count_assertion(test_filename, test_line);
va_start(ap, f1fmt);
vsprintf(f1, f1fmt, ap);
va_end(ap);
if (stat(f1, &st) != 0) {
- fprintf(stderr, "%s:%d: Could not stat: %s\n", test_filename, test_line, f1);
- report_failure(NULL);
+ if (report_failure(test_filename, test_line, "Stat failed: %s", f1)) {
+ finish_failure(NULL);
+ }
return (0);
}
if (st.st_size == 0)
return (1);
- ++failures;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
-
- fprintf(stderr, "%s:%d: File not empty: %s\n", test_filename, test_line, f1);
- fprintf(stderr, " File size: %d\n", (int)st.st_size);
- fprintf(stderr, " Contents:\n");
- f = fopen(f1, "rb");
- if (f == NULL) {
- fprintf(stderr, " Unable to open %s\n", f1);
- } else {
- s = ((off_t)sizeof(buff) < st.st_size) ?
- (ssize_t)sizeof(buff) : (ssize_t)st.st_size;
- s = fread(buff, 1, s, f);
- hexdump(buff, NULL, s, 0);
- fclose(f);
+ if (report_failure(test_filename, test_line, "%s not empty", f1)) {
+ fprintf(stderr, " File size: %d\n", (int)st.st_size);
+ fprintf(stderr, " Contents:\n");
+ f = fopen(f1, "rb");
+ if (f == NULL) {
+ fprintf(stderr, " Unable to open %s\n", f1);
+ } else {
+ s = ((off_t)sizeof(buff) < st.st_size) ?
+ (ssize_t)sizeof(buff) : (ssize_t)st.st_size;
+ s = fread(buff, 1, s, f);
+ hexdump(buff, NULL, s, 0);
+ fclose(f);
+ }
+ finish_failure(NULL);
}
- report_failure(NULL);
return (0);
}
struct stat st;
va_list ap;
-
+ count_assertion(test_filename, test_line);
va_start(ap, f1fmt);
vsprintf(f1, f1fmt, ap);
va_end(ap);
if (stat(f1, &st) != 0) {
- fprintf(stderr, "%s:%d: Could not stat: %s\n",
- test_filename, test_line, f1);
- report_failure(NULL);
- ++failures;
+ if (report_failure(test_filename, test_line, "Stat failed: %s", f1))
+ finish_failure(NULL);
return (0);
}
if (st.st_size != 0)
return (1);
-
- ++failures;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
-
- fprintf(stderr, "%s:%d: File empty: %s\n",
- test_filename, test_line, f1);
- report_failure(NULL);
+ if (report_failure(test_filename, test_line, "File empty: %s", f1))
+ finish_failure(NULL);
return (0);
}
FILE *f1, *f2;
int n1, n2;
+ count_assertion(test_filename, test_line);
va_start(ap, f2pattern);
vsprintf(fn2, f2pattern, ap);
va_end(ap);
}
fclose(f1);
fclose(f2);
- ++failures;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Files are not identical\n",
- test_filename, test_line);
- fprintf(stderr, " file1=\"%s\"\n", fn1);
- fprintf(stderr, " file2=\"%s\"\n", fn2);
- report_failure(test_extra);
+ if (report_failure(test_filename, test_line, "Files not identical")) {
+ fprintf(stderr, " file1=\"%s\"\n", fn1);
+ fprintf(stderr, " file2=\"%s\"\n", fn2);
+ finish_failure(test_extra);
+ }
return (0);
}
if (!access(f, F_OK))
return (1);
#endif
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File doesn't exist\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "File doesn't exist")) {
fprintf(stderr, " file=\"%s\"\n", f);
- report_failure(test_extra);
+ finish_failure(test_extra);
}
return (0);
}
if (access(f, F_OK))
return (1);
#endif
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File exists and shouldn't\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "File exists")) {
fprintf(stderr, " file=\"%s\"\n", f);
- report_failure(test_extra);
+ finish_failure(test_extra);
}
return (0);
}
f = fopen(fn, "rb");
if (f == NULL) {
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File doesn't exist: %s\n",
- test_filename, test_line, fn);
- report_failure(test_extra);
+ if (report_failure(test_filename, test_line, "File doesn't exist: %s", fn)) {
+ finish_failure(test_extra);
}
return (0);
}
free(contents);
return (1);
}
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File contents don't match\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "File contents don't match")) {
fprintf(stderr, " file=\"%s\"\n", fn);
if (n > 0)
hexdump(contents, buff, n > 512 ? 512 : 0, 0);
fprintf(stderr, " File empty, contents should be:\n");
hexdump(buff, NULL, s > 512 ? 512 : 0, 0);
}
- report_failure(test_extra);
+ finish_failure(test_extra);
}
free(contents);
return (0);
free(contents);
return (1);
}
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File contents don't match\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "Contents don't match")) {
fprintf(stderr, " file=\"%s\"\n", fn);
if (n > 0)
hexdump(contents, buff, n, 0);
fprintf(stderr, " File empty, contents should be:\n");
hexdump(buff, NULL, s, 0);
}
- report_failure(test_extra);
+ finish_failure(test_extra);
}
free(contents);
return (0);
count_assertion(file, line);
r = lstat(path1, &st1);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1))
- fprintf(stderr, "%s:%d: File ``%s'' should exist\n",
- file, line, path1);
+ if (report_failure(file, line, "File %s should exist", path1))
+ finish_failure(NULL);
return (0);
}
r = lstat(path2, &st2);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1))
- fprintf(stderr, "%s:%d: File ``%s'' should exist\n",
- file, line, path2);
+ if (report_failure(file, line, "File %s should exist", path2))
+ finish_failure(NULL);
return (0);
}
if (st1.st_ino != st2.st_ino || st1.st_dev != st2.st_dev) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr,
- "%s:%d: Files ``%s'' and ``%s'' are not hardlinked\n",
- file, line, path1, path2);
- report_failure(NULL);
- }
+ if (report_failure(file, line,
+ "Files %s and %s are not hardlinked", path1, path2))
+ finish_failure(NULL);
return (0);
}
return (1);
r = lstat(pathname, &st);
if (r == 0 && st.st_nlink == nlinks)
return (1);
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: File ``%s'' has %d links, expected %d\n",
- file, line, pathname, st.st_nlink, nlinks);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "File %s has %d links, expected %d",
+ pathname, st.st_nlink, nlinks))
+ finish_failure(NULL);
return (0);
}
r = lstat(pathname, &st);
if (r == 0 && st.st_size == size)
return (1);
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: File ``%s'' has size %ld, expected %ld\n",
- file, line, pathname, (long)st.st_size, (long)size);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "File %s has size %ld, expected %ld",
+ pathname, (long)st.st_size, (long)size))
+ finish_failure(NULL);
return (0);
}
count_assertion(file, line);
r = lstat(pathname, &st);
- if (r != 0 || !S_ISDIR(st.st_mode)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Dir ``%s'' doesn't exist\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (r != 0) {
+ if (report_failure(file, line, "Dir %s doesn't exist", pathname))
+ finish_failure(NULL);
return (0);
}
- if (mode < 0) {
- msg[0] = '\0';
- return (1);
+ if (!S_ISDIR(st.st_mode)) {
+ if (report_failure(file, line, "%s is not a dir", pathname))
+ finish_failure(NULL);
+ return (0);
}
+ if (mode < 0)
+ return (1);
if (mode != (st.st_mode & 07777)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Dir ``%s'' has wrong mode\n",
- file, line, pathname);
+ if (report_failure(file, line, "Dir %s has wrong mode", pathname)) {
fprintf(stderr, " Expected: 0%3o\n", mode);
fprintf(stderr, " Found: 0%3o\n", st.st_mode & 07777);
- report_failure(NULL);
+ finish_failure(NULL);
}
return (0);
}
- msg[0] = '\0';
return (1);
}
const char *pathname, const char *contents)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
+ count_assertion(file, line);
// TODO: Vista supports symlinks
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Symlink ``%s'' not supported\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Symlink %s not supported", pathname))
+ finish_failure(NULL);
return (0);
#else
char buff[300];
count_assertion(file, line);
r = lstat(pathname, &st);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Symlink ``%s'' doesn't exist\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Symlink %s doesn't exist", pathname))
+ finish_failure(NULL);
return (0);
}
if (!S_ISLNK(st.st_mode)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: ``%s'' should be a symlink\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "%s should be a symlink", pathname))
+ finish_failure(NULL);
return (0);
}
if (contents == NULL)
return (1);
linklen = readlink(pathname, buff, sizeof(buff));
if (linklen < 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: symlink ``%s'' can't be read\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Can't read symlink %s", pathname))
+ finish_failure(NULL);
return (0);
}
buff[linklen] = '\0';
if (strcmp(buff, contents) != 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Wrong symlink ``%s''\n",
- file, line, pathname);
+ if (report_failure(file, line, "Wrong symlink %s", pathname)) {
fprintf(stderr, " Expected: %s\n", contents);
fprintf(stderr, " Found: %s\n", buff);
- report_failure(NULL);
+ finish_failure(NULL);
}
return (0);
}
count_assertion(file, line);
r = lstat(pathname, &st);
if (r != 0 || !S_ISREG(st.st_mode)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: File ``%s'' doesn't exist\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "File %s doesn't exist", pathname))
+ finish_failure(NULL);
return (0);
}
if (mode < 0)
return (1);
if (mode != (st.st_mode & 07777)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Dir ``%s'' has wrong mode\n",
- file, line, pathname);
+ if (report_failure(file, line, "File %s has wrong mode", pathname)) {
fprintf(stderr, " Expected: 0%3o\n", mode);
fprintf(stderr, " Found: 0%3o\n", st.st_mode & 07777);
- report_failure(NULL);
+ finish_failure(NULL);
}
return (0);
}
int
test_assert_make_dir(const char *file, int line, const char *dirname, int mode)
{
- int r;
-
count_assertion(file, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
- r = _mkdir(dirname);
+ if (0 == _mkdir(dirname))
+ return (1);
#else
- r = mkdir(dirname, mode);
-#endif
- if (r == 0) {
- msg[0] = '\0';
+ if (0 == mkdir(dirname, mode))
return (1);
+#endif
+ if (report_failure(file, line, "Could not create directory %s", dirname))
+ finish_failure(NULL);
+ return(0);
+}
+
+int
+test_assert_make_file(const char *file, int line,
+ const char *path, int mode, const char *contents)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* TODO: Rework this to set file mode as well. */
+ FILE *f;
+ count_assertion(file, line);
+ f = fopen(path, "wb");
+ if (f == NULL) {
+ if (report_failure(file, line, "Could not create file %s", path))
+ finish_failure(NULL);
+ return (0);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
+ if (contents != NULL) {
+ if (strlen(contents)
+ != fwrite(contents, 1, strlen(contents), f)) {
+ fclose(f);
+ if (report_failure(file, line, "Could not write file %s", path))
+ finish_failure(NULL);
+ return (0);
+ }
+ }
+ fclose(f);
+ return (1);
+#else
+ int fd;
+ count_assertion(file, line);
+ fd = open(path, O_CREAT | O_WRONLY, mode >= 0 ? mode : 0644);
+ if (fd < 0) {
+ if (report_failure(file, line, "Could not create %s", path))
+ finish_failure(NULL);
return (0);
- fprintf(stderr, "%s:%d: Could not create directory\n",
- file, line);
- fprintf(stderr, " Dirname: %s\n", dirname);
- return(0);
+ }
+ if (contents != NULL) {
+ if ((ssize_t)strlen(contents)
+ != write(fd, contents, strlen(contents))) {
+ close(fd);
+ if (report_failure(file, line, "Could not write to %s", path))
+ finish_failure(NULL);
+ return (0);
+ }
+ }
+ close(fd);
+ return (1);
+#endif
}
int
test_assert_make_hardlink(const char *file, int line,
- const char *newpath, const char *linkto)
+ const char *newpath, const char *linkto)
{
int succeeded;
count_assertion(file, line);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- succeeded = __CreateHardLinkA(newpath, linkto);
+#if HAVE_CREATEHARDLINK
+ succeeded = CreateHardLink(newpath, linkto, NULL);
#elif HAVE_LINK
succeeded = !link(linkto, newpath);
#else
succeeded = 0;
#endif
- if (succeeded) {
- msg[0] = '\0';
+ if (succeeded)
return (1);
- }
- ++failures;
- if (verbose || !previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Could not create new hardlink\n",
- file, line);
+ if (report_failure(file, line, "Could not create hardlink")) {
fprintf(stderr, " New link: %s\n", newpath);
fprintf(stderr, " Old name: %s\n", linkto);
+ finish_failure(NULL);
}
return(0);
}
test_assert_make_symlink(const char *file, int line,
const char *newpath, const char *linkto)
{
- int succeeded;
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- int targetIsDir = 0;
+#if HAVE_CREATESYMBOLICLINK
+ int targetIsDir = 0; /* TODO: Fix this. */
count_assertion(file, line);
- succeeded = __CreateSymbolicLinkA(newpath, linkto, targetIsDir);
+ if (CreateSymbolicLink(newpath, linkto, targetIsDir))
+ return (1);
#elif HAVE_SYMLINK
count_assertion(file, line);
- succeeded = !symlink(linkto, newpath);
-#else
- succeeded = 0;
-#endif
- if (succeeded) {
- msg[0] = '\0';
+ if (0 == symlink(linkto, newpath))
return (1);
- }
- ++failures;
- if (verbose || !previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Could not create new symlink\n",
- file, line);
+#endif
+ if (report_failure(file, line, "Could not create symlink")) {
fprintf(stderr, " New link: %s\n", newpath);
fprintf(stderr, " Old name: %s\n", linkto);
+ finish_failure(NULL);
}
return(0);
}
return (1);
}
+void
+sleepUntilAfter(time_t t)
+{
+ while (t >= time(NULL))
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ Sleep(500);
+#else
+ sleep(1);
+#endif
+}
+
/*
* Call standard system() call, but build up the command line using
* sprintf() conventions.
* the mainline code.
*/
+/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
#define strdup _strdup
#define LOCALE_DE "deu"
#define LOCALE_DE "de_DE.UTF-8"
#endif
+/* Visual Studio */
#ifdef _MSC_VER
#define snprintf sprintf_s
#endif
+/* Cygwin */
#if defined(__CYGWIN__)
/* Cygwin-1.7.x is lazy about populating nlinks, so don't
* expect it to be accurate. */
# define NLINKS_INACCURATE_FOR_DIRS
#endif
+/* FreeBSD */
#ifdef __FreeBSD__
#include <sys/cdefs.h> /* For __FBSDID */
#else
-/* Some non-FreeBSD platforms such as newlib-derived ones like
- * cygwin, have __FBSDID, so this definition must be guarded.
- */
+/* Surprisingly, some non-FreeBSD platforms define __FBSDID. */
#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
/* An implementation of the standard assert() macro */
#define assert(e) test_assert(__FILE__, __LINE__, (e), #e, NULL)
-
+/* chdir() and error if it fails */
#define assertChdir(path) \
test_assert_chdir(__FILE__, __LINE__, path)
/* Assert two integers are the same. Reports value of each one if not. */
#define assertEqualInt(v1,v2) \
test_assert_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
test_assert_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Create a directory, report error if it fails. */
#define assertMakeDir(dirname, mode) \
test_assert_make_dir(__FILE__, __LINE__, dirname, mode)
+#define assertMakeFile(path, mode, contents) \
+ test_assert_make_file(__FILE__, __LINE__, path, mode, contents)
#define assertMakeHardlink(newfile, oldfile) \
test_assert_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
-void test_setup(const char *, int);
-void test_skipping(const char *fmt, ...);
int test_assert(const char *, int, int, const char *, void *);
int test_assert_chdir(const char *, int, const char *);
int test_assert_empty_file(const char *, ...);
-int test_assert_non_empty_file(const char *, ...);
int test_assert_equal_file(const char *, const char *, ...);
int test_assert_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
+int test_assert_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int test_assert_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
int test_assert_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
-int test_assert_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int test_assert_file_contents(const void *, int, const char *, ...);
-int test_assert_text_file_contents(const char *buff, const char *f);
int test_assert_file_exists(const char *, ...);
int test_assert_file_hardlinks(const char *, int, const char *, const char *);
-int test_assert_file_not_exists(const char *, ...);
int test_assert_file_nlinks(const char *, int, const char *, int);
+int test_assert_file_not_exists(const char *, ...);
int test_assert_file_size(const char *, int, const char *, long);
int test_assert_is_dir(const char *, int, const char *, int);
int test_assert_is_reg(const char *, int, const char *, int);
int test_assert_is_symlink(const char *, int, const char *, const char *);
int test_assert_make_dir(const char *, int, const char *, int);
+int test_assert_make_file(const char *, int, const char *, int, const char *);
int test_assert_make_hardlink(const char *, int, const char *newpath, const char *);
int test_assert_make_symlink(const char *, int, const char *newpath, const char *);
+int test_assert_non_empty_file(const char *, ...);
+int test_assert_text_file_contents(const char *buff, const char *f);
int test_assert_umask(const char *, int, int);
+void test_setup(const char *, int);
+void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
int systemf(const char * fmt, ...);
+/* Delay until time() returns a value after this. */
+void sleepUntilAfter(time_t);
+
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
acl = acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx");
assert((void *)acl != NULL);
/* Create a test file and try to set an ACL on it. */
- fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777);
+ fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
failure("Could not create test file?!");
if (!assert(fd >= 0)) {
acl_free(acl);
* doesn't, we'll simply skip the remaining tests.
*/
/* Create a test file and try to set an ACL on it. */
- fd = open("pretest", O_RDWR | O_CREAT | O_BINARY, 0777);
+ fd = open("pretest", O_RDWR | O_CREAT, 0777);
failure("Could not create test file?!");
if (!assert(fd >= 0))
return;
* permissions, not file permissions), but is known broken on
* some versions of FreeBSD.
*/
- fd = open("pretest2", O_RDWR | O_CREAT | O_BINARY, 00000);
+ fd = open("pretest2", O_RDWR | O_CREAT, 00000);
failure("Could not create test file?!");
if (!assert(fd >= 0))
return;
#define S_ISREG(m) ((m) & _S_IFREG)
#endif
#define access _access
-#undef chdir
#define chdir _chdir
#ifndef fileno
#define fileno _fileno
#define DEFINE_TEST(name) void name(void);
#include "list.h"
-/* Interix doesn't define these in a standard header. */
-#if __INTERIX__
-extern char *optarg;
-extern int optind;
-#endif
-
/* Enable core dump on failure. */
static int dump_on_failure = 0;
/* Default is to remove temp dirs for successful tests. */
* printed if the following assertion fails, good for
* explaining subtle tests.
*/
-static char msg[4096];
+static char msgbuff[4096];
+static const char *msg, *nextmsg;
/*
* For each test source file, we remember how many times each
*/
static const char *failed_filename = NULL;
static struct line {
- int line;
int count;
- int critical;
-} failed_lines[1000];
+ int skip;
+} failed_lines[10000];
/*
* Called at the beginning of each assert() function.
(void)file; /* UNUSED */
(void)line; /* UNUSED */
++assertions;
+ msg = nextmsg;
+ nextmsg = NULL;
/* Uncomment to print file:line after every assertion.
* Verbose, but occasionally useful in tracking down crashes. */
/* printf("Checked %s:%d\n", file, line); */
}
/*
- * Count this failure; return the number of previous failures.
+ * Count this failure; return true if this failure is being reported.
*/
static int
-previous_failures(const char *filename, int line, int critical)
+report_failure(const char *filename, int line, const char *fmt, ...)
{
- unsigned int i;
- int count;
+ ++failures;
+ /* If this is a new file, clear the counts. */
if (failed_filename == NULL || strcmp(failed_filename, filename) != 0)
memset(failed_lines, 0, sizeof(failed_lines));
failed_filename = filename;
- for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].line == line) {
- count = failed_lines[i].count;
- failed_lines[i].count++;
- return (count);
- }
- if (failed_lines[i].line == 0) {
- failed_lines[i].line = line;
- failed_lines[i].count = 1;
- failed_lines[i].critical = critical;
- return (0);
- }
+ /* Report first hit always, every hit if verbose. */
+ if (failed_lines[line].count++ == 0 || verbose) {
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d: ", filename, line);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ return (1);
}
return (0);
}
+/* Complete reporting of failed tests. */
+static void
+finish_failure(void *extra)
+{
+ if (msg != NULL && msg[0] != '\0')
+ fprintf(stderr, " Description: %s\n", msg);
+
+#ifdef EXTRA_DUMP
+ if (extra != NULL)
+ fprintf(stderr, " detail: %s\n", EXTRA_DUMP(extra));
+#else
+ (void)extra; /* UNUSED */
+#endif
+
+ if (dump_on_failure) {
+ fprintf(stderr,
+ " *** forcing core dump so failure can be debugged ***\n");
+ *(char *)(NULL) = 0;
+ exit(1);
+ }
+}
+
/*
* Copy arguments into file-local variables.
*/
{
va_list ap;
- if (previous_failures(test_filename, test_line, 0))
- return;
-
- va_start(ap, fmt);
- fprintf(stderr, " *** SKIPPING: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- ++skips;
-}
-
-/* Common handling of failed tests. */
-static void
-report_failure(void *extra)
-{
- if (msg[0] != '\0') {
- fprintf(stderr, " Description: %s\n", msg);
- msg[0] = '\0';
- }
-
-#ifdef EXTRA_DUMP
- if (extra != NULL)
- fprintf(stderr, " detail: %s\n", EXTRA_DUMP(extra));
-#else
- (void)extra; /* UNUSED */
-#endif
-
- if (dump_on_failure) {
- fprintf(stderr,
- " *** forcing core dump so failure can be debugged ***\n");
- *(char *)(NULL) = 0;
- exit(1);
+ if (report_failure(test_filename, test_line, "SKIPPING" )) {
+ va_start(ap,fmt);
+ fprintf(stderr, " Reason: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ /* Don't finish_failure() here. */
}
+ /* Mark as skip, so doesn't count as failed test. */
+ failed_lines[test_line].skip = 1;
+ ++skips;
+ --failures;
}
/*
* The reports above suppress multiple failures from the same source
* line; this reports on any tests that did fail multiple times.
*/
-static int
-summarize_comparator(const void *a0, const void *b0)
-{
- const struct line *a = a0, *b = b0;
- if (a->line == 0 && b->line == 0)
- return (0);
- if (a->line == 0)
- return (1);
- if (b->line == 0)
- return (-1);
- return (a->line - b->line);
-}
-
static void
summarize(void)
{
unsigned int i;
- qsort(failed_lines, sizeof(failed_lines)/sizeof(failed_lines[0]),
- sizeof(failed_lines[0]), summarize_comparator);
for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].line == 0)
+ if (failed_lines[i].count == 0)
break;
- if (failed_lines[i].count > 1 && failed_lines[i].critical)
+ if (failed_lines[i].count > 1 && !failed_lines[i].skip)
fprintf(stderr, "%s:%d: Failed %d times\n",
- failed_filename, failed_lines[i].line,
- failed_lines[i].count);
+ failed_filename, i, failed_lines[i].count);
}
/* Clear the failure history for the next file. */
memset(failed_lines, 0, sizeof(failed_lines));
{
va_list ap;
va_start(ap, fmt);
- vsprintf(msg, fmt, ap);
+ vsprintf(msgbuff, fmt, ap);
va_end(ap);
+ nextmsg = msgbuff;
}
/* Generic assert() just displays the failed condition. */
int
-test_assert(const char *file, int line, int value, const char *condition, void *extra)
+test_assert(const char *file, int line, int value,
+ const char *condition, void *extra)
{
count_assertion(file, line);
- if (value) {
- msg[0] = '\0';
+ if (value)
return (value);
+ if (report_failure(file, line, "Assertion failed: %s", condition)) {
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (value);
- fprintf(stderr, "%s:%d: Assertion failed\n", file, line);
- fprintf(stderr, " Condition: %s\n", condition);
- report_failure(extra);
return (value);
}
count_assertion(file, line);
if (chdir(pathname) == 0)
return (1);
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: chdir(\"%s\") failed\n",
- file, line, pathname);
+ if (report_failure(file, line, "chdir(\"%s\")", pathname)) {
+ finish_failure(NULL);
+ }
return (0);
}
long long v1, const char *e1, long long v2, const char *e2, void *extra)
{
count_assertion(file, line);
- if (v1 == v2) {
- msg[0] = '\0';
+ if (v1 == v2)
return (1);
+ if (report_failure(file, line, "Ints not equal")) {
+ fprintf(stderr, " %s=%lld\n", e1, v1);
+ fprintf(stderr, " %s=%lld\n", e2, v2);
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Ints not equal\n",
- file, line);
- fprintf(stderr, " %s=%lld\n", e1, v1);
- fprintf(stderr, " %s=%lld\n", e2, v2);
- report_failure(extra);
return (0);
}
-static void strdump(const char *p)
+static void strdump(const char *e, const char *p)
{
+ fprintf(stderr, " %s = ", e);
if (p == NULL) {
fprintf(stderr, "(null)");
return;
}
}
fprintf(stderr, "\"");
+ fprintf(stderr, " (length %d)\n", p == NULL ? 0 : (int)strlen(p));
}
/* assertEqualString() displays the values of the two strings. */
void *extra)
{
count_assertion(file, line);
- if (v1 == NULL || v2 == NULL) {
- if (v1 == v2) {
- msg[0] = '\0';
- return (1);
- }
- } else if (strcmp(v1, v2) == 0) {
- msg[0] = '\0';
+ if (v1 == v2)
return (1);
+ else if (strcmp(v1, v2) == 0)
+ return (1);
+ if (report_failure(file, line, "Strings not equal")) {
+ strdump(e1, v1);
+ strdump(e2, v2);
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Strings not equal\n",
- file, line);
- fprintf(stderr, " %s = ", e1);
- strdump(v1);
- fprintf(stderr, " (length %d)\n", v1 == NULL ? 0 : (int)strlen(v1));
- fprintf(stderr, " %s = ", e2);
- strdump(v2);
- fprintf(stderr, " (length %d)\n", v2 == NULL ? 0 : (int)strlen(v2));
- report_failure(extra);
return (0);
}
-static void wcsdump(const wchar_t *w)
+static void wcsdump(const char *e, const wchar_t *w)
{
+ fprintf(stderr, " %s = ", e);
if (w == NULL) {
fprintf(stderr, "(null)");
return;
else
fprintf(stderr, "\\U%08X", c);
}
- fprintf(stderr, "\"");
+ fprintf(stderr, "\"\n");
}
/* assertEqualWString() displays the values of the two strings. */
void *extra)
{
count_assertion(file, line);
- if (v1 == NULL) {
- if (v2 == NULL) {
- msg[0] = '\0';
- return (1);
- }
- } else if (v2 == NULL) {
- if (v1 == NULL) {
- msg[0] = '\0';
- return (1);
- }
- } else if (wcscmp(v1, v2) == 0) {
- msg[0] = '\0';
+ if (v1 == v2)
return (1);
+ else if (wcscmp(v1, v2) == 0)
+ return (1);
+ if (report_failure(file, line, "Unicode strings not equal")) {
+ wcsdump(e1, v1);
+ wcsdump(e2, v2);
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Unicode strings not equal\n",
- file, line);
- fprintf(stderr, " %s = ", e1);
- wcsdump(v1);
- fprintf(stderr, "\n");
- fprintf(stderr, " %s = ", e2);
- wcsdump(v2);
- fprintf(stderr, "\n");
- report_failure(extra);
return (0);
}
size_t offset;
count_assertion(file, line);
- if (v1 == NULL || v2 == NULL) {
- if (v1 == v2) {
- msg[0] = '\0';
- return (1);
- }
- } else if (memcmp(v1, v2, l) == 0) {
- msg[0] = '\0';
+ if (v1 == v2)
+ return (1);
+ else if (memcmp(v1, v2, l) == 0)
return (1);
+ if (report_failure(file, line, "Memory not equal")) {
+ fprintf(stderr, " size %s = %d\n", ld, (int)l);
+ /* Dump 48 bytes (3 lines) so that the first difference is
+ * in the second line. */
+ offset = 0;
+ while (l > 64 && memcmp(v1, v2, 32) == 0) {
+ /* Two lines agree, so step forward one line. */
+ v1 += 16;
+ v2 += 16;
+ l -= 16;
+ offset += 16;
+ }
+ fprintf(stderr, " Dump of %s\n", e1);
+ hexdump(v1, v2, l < 64 ? l : 64, offset);
+ fprintf(stderr, " Dump of %s\n", e2);
+ hexdump(v2, v1, l < 64 ? l : 64, offset);
+ fprintf(stderr, "\n");
+ finish_failure(extra);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: memory not equal\n",
- file, line);
- fprintf(stderr, " size %s = %d\n", ld, (int)l);
- /* Dump 48 bytes (3 lines) so that the first difference is
- * in the second line. */
- offset = 0;
- while (l > 64 && memcmp(v1, v2, 32) == 0) {
- /* The first two lines agree, so step forward one line. */
- v1 += 16;
- v2 += 16;
- l -= 16;
- offset += 16;
- }
- fprintf(stderr, " Dump of %s\n", e1);
- hexdump(v1, v2, l < 64 ? l : 64, offset);
- fprintf(stderr, " Dump of %s\n", e2);
- hexdump(v2, v1, l < 64 ? l : 64, offset);
- fprintf(stderr, "\n");
- report_failure(extra);
return (0);
}
ssize_t s;
FILE *f;
-
+ count_assertion(test_filename, test_line);
va_start(ap, f1fmt);
vsprintf(f1, f1fmt, ap);
va_end(ap);
if (stat(f1, &st) != 0) {
- fprintf(stderr, "%s:%d: Could not stat: %s\n", test_filename, test_line, f1);
- report_failure(NULL);
+ if (report_failure(test_filename, test_line, "Stat failed: %s", f1)) {
+ finish_failure(NULL);
+ }
return (0);
}
if (st.st_size == 0)
return (1);
- ++failures;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
-
- fprintf(stderr, "%s:%d: File not empty: %s\n", test_filename, test_line, f1);
- fprintf(stderr, " File size: %d\n", (int)st.st_size);
- fprintf(stderr, " Contents:\n");
- f = fopen(f1, "rb");
- if (f == NULL) {
- fprintf(stderr, " Unable to open %s\n", f1);
- } else {
- s = ((off_t)sizeof(buff) < st.st_size) ?
- (ssize_t)sizeof(buff) : (ssize_t)st.st_size;
- s = fread(buff, 1, s, f);
- hexdump(buff, NULL, s, 0);
- fclose(f);
+ if (report_failure(test_filename, test_line, "%s not empty", f1)) {
+ fprintf(stderr, " File size: %d\n", (int)st.st_size);
+ fprintf(stderr, " Contents:\n");
+ f = fopen(f1, "rb");
+ if (f == NULL) {
+ fprintf(stderr, " Unable to open %s\n", f1);
+ } else {
+ s = ((off_t)sizeof(buff) < st.st_size) ?
+ (ssize_t)sizeof(buff) : (ssize_t)st.st_size;
+ s = fread(buff, 1, s, f);
+ hexdump(buff, NULL, s, 0);
+ fclose(f);
+ }
+ finish_failure(NULL);
}
- report_failure(NULL);
return (0);
}
struct stat st;
va_list ap;
-
+ count_assertion(test_filename, test_line);
va_start(ap, f1fmt);
vsprintf(f1, f1fmt, ap);
va_end(ap);
if (stat(f1, &st) != 0) {
- fprintf(stderr, "%s:%d: Could not stat: %s\n",
- test_filename, test_line, f1);
- report_failure(NULL);
- ++failures;
+ if (report_failure(test_filename, test_line, "Stat failed: %s", f1))
+ finish_failure(NULL);
return (0);
}
if (st.st_size != 0)
return (1);
-
- ++failures;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
-
- fprintf(stderr, "%s:%d: File empty: %s\n",
- test_filename, test_line, f1);
- report_failure(NULL);
+ if (report_failure(test_filename, test_line, "File empty: %s", f1))
+ finish_failure(NULL);
return (0);
}
FILE *f1, *f2;
int n1, n2;
+ count_assertion(test_filename, test_line);
va_start(ap, f2pattern);
vsprintf(fn2, f2pattern, ap);
va_end(ap);
}
fclose(f1);
fclose(f2);
- ++failures;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Files are not identical\n",
- test_filename, test_line);
- fprintf(stderr, " file1=\"%s\"\n", fn1);
- fprintf(stderr, " file2=\"%s\"\n", fn2);
- report_failure(test_extra);
+ if (report_failure(test_filename, test_line, "Files not identical")) {
+ fprintf(stderr, " file1=\"%s\"\n", fn1);
+ fprintf(stderr, " file2=\"%s\"\n", fn2);
+ finish_failure(test_extra);
+ }
return (0);
}
if (!access(f, F_OK))
return (1);
#endif
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File doesn't exist\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "File doesn't exist")) {
fprintf(stderr, " file=\"%s\"\n", f);
- report_failure(test_extra);
+ finish_failure(test_extra);
}
return (0);
}
if (access(f, F_OK))
return (1);
#endif
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File exists and shouldn't\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "File exists")) {
fprintf(stderr, " file=\"%s\"\n", f);
- report_failure(test_extra);
+ finish_failure(test_extra);
}
return (0);
}
f = fopen(fn, "rb");
if (f == NULL) {
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File doesn't exist: %s\n",
- test_filename, test_line, fn);
- report_failure(test_extra);
+ if (report_failure(test_filename, test_line, "File doesn't exist: %s", fn)) {
+ finish_failure(test_extra);
}
return (0);
}
free(contents);
return (1);
}
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File contents don't match\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "File contents don't match")) {
fprintf(stderr, " file=\"%s\"\n", fn);
if (n > 0)
hexdump(contents, buff, n > 512 ? 512 : 0, 0);
fprintf(stderr, " File empty, contents should be:\n");
hexdump(buff, NULL, s > 512 ? 512 : 0, 0);
}
- report_failure(test_extra);
+ finish_failure(test_extra);
}
free(contents);
return (0);
free(contents);
return (1);
}
- ++failures;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File contents don't match\n",
- test_filename, test_line);
+ if (report_failure(test_filename, test_line, "Contents don't match")) {
fprintf(stderr, " file=\"%s\"\n", fn);
if (n > 0)
hexdump(contents, buff, n, 0);
fprintf(stderr, " File empty, contents should be:\n");
hexdump(buff, NULL, s, 0);
}
- report_failure(test_extra);
+ finish_failure(test_extra);
}
free(contents);
return (0);
count_assertion(file, line);
r = lstat(path1, &st1);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1))
- fprintf(stderr, "%s:%d: File ``%s'' should exist\n",
- file, line, path1);
+ if (report_failure(file, line, "File %s should exist", path1))
+ finish_failure(NULL);
return (0);
}
r = lstat(path2, &st2);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1))
- fprintf(stderr, "%s:%d: File ``%s'' should exist\n",
- file, line, path2);
+ if (report_failure(file, line, "File %s should exist", path2))
+ finish_failure(NULL);
return (0);
}
if (st1.st_ino != st2.st_ino || st1.st_dev != st2.st_dev) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr,
- "%s:%d: Files ``%s'' and ``%s'' are not hardlinked\n",
- file, line, path1, path2);
- report_failure(NULL);
- }
+ if (report_failure(file, line,
+ "Files %s and %s are not hardlinked", path1, path2))
+ finish_failure(NULL);
return (0);
}
return (1);
r = lstat(pathname, &st);
if (r == 0 && st.st_nlink == nlinks)
return (1);
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: File ``%s'' has %d links, expected %d\n",
- file, line, pathname, st.st_nlink, nlinks);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "File %s has %d links, expected %d",
+ pathname, st.st_nlink, nlinks))
+ finish_failure(NULL);
return (0);
}
r = lstat(pathname, &st);
if (r == 0 && st.st_size == size)
return (1);
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: File ``%s'' has size %ld, expected %ld\n",
- file, line, pathname, (long)st.st_size, (long)size);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "File %s has size %ld, expected %ld",
+ pathname, (long)st.st_size, (long)size))
+ finish_failure(NULL);
return (0);
}
count_assertion(file, line);
r = lstat(pathname, &st);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Dir ``%s'' doesn't exist\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Dir %s doesn't exist", pathname))
+ finish_failure(NULL);
return (0);
}
if (!S_ISDIR(st.st_mode)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: ``%s'' is not a dir\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "%s is not a dir", pathname))
+ finish_failure(NULL);
return (0);
}
- if (mode < 0) {
- msg[0] = '\0';
+ if (mode < 0)
return (1);
- }
if (mode != (st.st_mode & 07777)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Dir ``%s'' has wrong mode\n",
- file, line, pathname);
+ if (report_failure(file, line, "Dir %s has wrong mode", pathname)) {
fprintf(stderr, " Expected: 0%3o\n", mode);
fprintf(stderr, " Found: 0%3o\n", st.st_mode & 07777);
- report_failure(NULL);
+ finish_failure(NULL);
}
return (0);
}
- msg[0] = '\0';
return (1);
}
const char *pathname, const char *contents)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
+ count_assertion(file, line);
// TODO: Vista supports symlinks
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Symlink ``%s'' not supported\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Symlink %s not supported", pathname))
+ finish_failure(NULL);
return (0);
#else
char buff[300];
count_assertion(file, line);
r = lstat(pathname, &st);
if (r != 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Symlink ``%s'' doesn't exist\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Symlink %s doesn't exist", pathname))
+ finish_failure(NULL);
return (0);
}
if (!S_ISLNK(st.st_mode)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: ``%s'' should be a symlink\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "%s should be a symlink", pathname))
+ finish_failure(NULL);
return (0);
}
if (contents == NULL)
return (1);
linklen = readlink(pathname, buff, sizeof(buff));
if (linklen < 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: symlink ``%s'' can't be read\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "Can't read symlink %s", pathname))
+ finish_failure(NULL);
return (0);
}
buff[linklen] = '\0';
if (strcmp(buff, contents) != 0) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Wrong symlink ``%s''\n",
- file, line, pathname);
+ if (report_failure(file, line, "Wrong symlink %s", pathname)) {
fprintf(stderr, " Expected: %s\n", contents);
fprintf(stderr, " Found: %s\n", buff);
- report_failure(NULL);
+ finish_failure(NULL);
}
return (0);
}
count_assertion(file, line);
r = lstat(pathname, &st);
if (r != 0 || !S_ISREG(st.st_mode)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: File ``%s'' doesn't exist\n",
- file, line, pathname);
- report_failure(NULL);
- }
+ if (report_failure(file, line, "File %s doesn't exist", pathname))
+ finish_failure(NULL);
return (0);
}
if (mode < 0)
return (1);
if (mode != (st.st_mode & 07777)) {
- ++failures;
- if (!previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Dir ``%s'' has wrong mode\n",
- file, line, pathname);
+ if (report_failure(file, line, "File %s has wrong mode", pathname)) {
fprintf(stderr, " Expected: 0%3o\n", mode);
fprintf(stderr, " Found: 0%3o\n", st.st_mode & 07777);
- report_failure(NULL);
+ finish_failure(NULL);
}
return (0);
}
int
test_assert_make_dir(const char *file, int line, const char *dirname, int mode)
{
- int r;
-
count_assertion(file, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
- r = _mkdir(dirname);
+ if (0 == _mkdir(dirname))
+ return (1);
#else
- r = mkdir(dirname, mode);
-#endif
- if (r == 0) {
- msg[0] = '\0';
+ if (0 == mkdir(dirname, mode))
return (1);
+#endif
+ if (report_failure(file, line, "Could not create directory %s", dirname))
+ finish_failure(NULL);
+ return(0);
+}
+
+int
+test_assert_make_file(const char *file, int line,
+ const char *path, int mode, const char *contents)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* TODO: Rework this to set file mode as well. */
+ FILE *f;
+ count_assertion(file, line);
+ f = fopen(path, "wb");
+ if (f == NULL) {
+ if (report_failure(file, line, "Could not create file %s", path))
+ finish_failure(NULL);
+ return (0);
}
- ++failures;
- if (!verbose && previous_failures(file, line, 1))
+ if (contents != NULL) {
+ if (strlen(contents)
+ != fwrite(contents, 1, strlen(contents), f)) {
+ fclose(f);
+ if (report_failure(file, line, "Could not write file %s", path))
+ finish_failure(NULL);
+ return (0);
+ }
+ }
+ fclose(f);
+ return (1);
+#else
+ int fd;
+ count_assertion(file, line);
+ fd = open(path, O_CREAT | O_WRONLY, mode >= 0 ? mode : 0644);
+ if (fd < 0) {
+ if (report_failure(file, line, "Could not create %s", path))
+ finish_failure(NULL);
return (0);
- fprintf(stderr, "%s:%d: Could not create directory\n",
- file, line);
- fprintf(stderr, " Dirname: %s\n", dirname);
- return(0);
+ }
+ if (contents != NULL) {
+ if ((ssize_t)strlen(contents)
+ != write(fd, contents, strlen(contents))) {
+ close(fd);
+ if (report_failure(file, line, "Could not write to %s", path))
+ finish_failure(NULL);
+ return (0);
+ }
+ }
+ close(fd);
+ return (1);
+#endif
}
int
test_assert_make_hardlink(const char *file, int line,
- const char *newpath, const char *linkto)
+ const char *newpath, const char *linkto)
{
int succeeded;
#else
succeeded = 0;
#endif
- if (succeeded) {
- msg[0] = '\0';
+ if (succeeded)
return (1);
- }
- ++failures;
- if (verbose || !previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Could not create new hardlink\n",
- file, line);
+ if (report_failure(file, line, "Could not create hardlink")) {
fprintf(stderr, " New link: %s\n", newpath);
fprintf(stderr, " Old name: %s\n", linkto);
+ finish_failure(NULL);
}
return(0);
}
test_assert_make_symlink(const char *file, int line,
const char *newpath, const char *linkto)
{
- int succeeded;
-
#if HAVE_CREATESYMBOLICLINK
int targetIsDir = 0; /* TODO: Fix this. */
count_assertion(file, line);
- succeeded = CreateSymbolicLink(newpath, linkto, targetIsDir);
+ if (CreateSymbolicLink(newpath, linkto, targetIsDir))
+ return (1);
#elif HAVE_SYMLINK
count_assertion(file, line);
- succeeded = !symlink(linkto, newpath);
-#else
- succeeded = 0;
-#endif
- if (succeeded) {
- msg[0] = '\0';
+ if (0 == symlink(linkto, newpath))
return (1);
- }
- ++failures;
- if (verbose || !previous_failures(file, line, 1)) {
- fprintf(stderr, "%s:%d: Could not create new symlink\n",
- file, line);
+#endif
+ if (report_failure(file, line, "Could not create symlink")) {
fprintf(stderr, " New link: %s\n", newpath);
fprintf(stderr, " Old name: %s\n", linkto);
+ finish_failure(NULL);
}
return(0);
}
return (1);
}
+void
+sleepUntilAfter(time_t t)
+{
+ while (t >= time(NULL))
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ Sleep(500);
+#else
+ sleep(1);
+#endif
+}
+
/*
* Call standard system() call, but build up the command line using
* sprintf() conventions.
* the mainline code.
*/
+/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
#include "../bsdtar_windows.h"
#define strdup _strdup
#define LOCALE_DE "de_DE.UTF-8"
#endif
+/* Visual Studio */
#ifdef _MSC_VER
#define snprintf sprintf_s
#endif
+/* Cygwin */
#if defined(__CYGWIN__)
/* Cygwin-1.7.x is lazy about populating nlinks, so don't
* expect it to be accurate. */
# define NLINKS_INACCURATE_FOR_DIRS
#endif
+/* FreeBSD */
#ifdef __FreeBSD__
#include <sys/cdefs.h> /* For __FBSDID */
#else
-/* Some non-FreeBSD platforms such as newlib-derived ones like
- * cygwin, have __FBSDID, so this definition must be guarded.
- */
+/* Surprisingly, some non-FreeBSD platforms define __FBSDID. */
#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
#endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
/*
* Redefine DEFINE_TEST for use in defining the test functions.
*/
/* An implementation of the standard assert() macro */
#define assert(e) test_assert(__FILE__, __LINE__, (e), #e, NULL)
-
+/* chdir() and error if it fails */
#define assertChdir(path) \
test_assert_chdir(__FILE__, __LINE__, path)
/* Assert two integers are the same. Reports value of each one if not. */
#define assertEqualInt(v1,v2) \
test_assert_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
test_assert_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Create a directory, report error if it fails. */
#define assertMakeDir(dirname, mode) \
test_assert_make_dir(__FILE__, __LINE__, dirname, mode)
+#define assertMakeFile(path, mode, contents) \
+ test_assert_make_file(__FILE__, __LINE__, path, mode, contents)
#define assertMakeHardlink(newfile, oldfile) \
test_assert_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
-void test_setup(const char *, int);
-void test_skipping(const char *fmt, ...);
int test_assert(const char *, int, int, const char *, void *);
int test_assert_chdir(const char *, int, const char *);
int test_assert_empty_file(const char *, ...);
-int test_assert_non_empty_file(const char *, ...);
int test_assert_equal_file(const char *, const char *, ...);
int test_assert_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
+int test_assert_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int test_assert_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
int test_assert_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
-int test_assert_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int test_assert_file_contents(const void *, int, const char *, ...);
-int test_assert_text_file_contents(const char *buff, const char *f);
int test_assert_file_exists(const char *, ...);
int test_assert_file_hardlinks(const char *, int, const char *, const char *);
-int test_assert_file_not_exists(const char *, ...);
int test_assert_file_nlinks(const char *, int, const char *, int);
+int test_assert_file_not_exists(const char *, ...);
int test_assert_file_size(const char *, int, const char *, long);
int test_assert_is_dir(const char *, int, const char *, int);
int test_assert_is_reg(const char *, int, const char *, int);
int test_assert_is_symlink(const char *, int, const char *, const char *);
int test_assert_make_dir(const char *, int, const char *, int);
+int test_assert_make_file(const char *, int, const char *, int, const char *);
int test_assert_make_hardlink(const char *, int, const char *newpath, const char *);
int test_assert_make_symlink(const char *, int, const char *newpath, const char *);
+int test_assert_non_empty_file(const char *, ...);
+int test_assert_text_file_contents(const char *buff, const char *f);
int test_assert_umask(const char *, int, int);
+void test_setup(const char *, int);
+void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
int systemf(const char * fmt, ...);
+/* Delay until time() returns a value after this. */
+void sleepUntilAfter(time_t);
+
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);