]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Merge some of the bsdtar_test refactoring into libarchive_test and
authorTim Kientzle <kientzle@gmail.com>
Sun, 26 Jul 2009 23:49:56 +0000 (19:49 -0400)
committerTim Kientzle <kientzle@gmail.com>
Sun, 26 Jul 2009 23:49:56 +0000 (19:49 -0400)
start updating individual test cases.

SVN-Revision: 1282

libarchive/test/main.c
libarchive/test/test.h
libarchive/test/test_read_extract.c
libarchive/test/test_read_format_mtree.c
libarchive/test/test_write_disk.c
libarchive/test/test_write_disk_failures.c
libarchive/test/test_write_disk_perms.c

index b6f569901941c16e78eaa4bf4de6a1cb3da51f40..764b91de74f9167f3f191fb6a3d82e3becd19d64 100644 (file)
 #if !defined(__GNUC__)
 #include <crtdbg.h>
 #endif
+#include <io.h>
 #include <windows.h>
 #include <winbase.h>
+#ifndef F_OK
+#define F_OK (0)
+#endif
+#ifndef S_ISDIR
+#define S_ISDIR(m)  ((m) & _S_IFDIR)
+#endif
+#ifndef S_ISREG
+#define S_ISREG(m)  ((m) & _S_IFREG)
+#endif
+#define access _access
+#ifndef fileno
+#define fileno _fileno
+#endif
+//#define fstat _fstat64
+#define getcwd _getcwd
+#define lstat stat
+//#define lstat _stat64
+//#define stat _stat64
+#define rmdir _rmdir
+#define strdup _strdup
+#define umask _umask
 #endif
 
 /*
@@ -283,7 +305,7 @@ test_assert(const char *file, int line, int value, const char *condition, void *
                msg[0] = '\0';
                return (value);
        }
-       failures ++;
+       ++failures;
        if (!verbose && previous_failures(file, line, 1))
                return (value);
        fprintf(stderr, "%s:%d: Assertion failed\n", file, line);
@@ -292,23 +314,38 @@ test_assert(const char *file, int line, int value, const char *condition, void *
        return (value);
 }
 
+int
+test_assert_chdir(const char *file, int line, const char *pathname)
+{
+       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);
+       return (0);
+
+}
+
 /* assertEqualInt() displays the values of the two integers. */
 int
 test_assert_equal_int(const char *file, int line,
-    int v1, const char *e1, int v2, const char *e2, void *extra)
+    long long v1, const char *e1, long long v2, const char *e2, void *extra)
 {
        count_assertion(file, line);
        if (v1 == v2) {
                msg[0] = '\0';
                return (1);
        }
-       failures ++;
+       ++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=%d\n", e1, v1);
-       fprintf(stderr, "      %s=%d\n", e2, v2);
+       fprintf(stderr, "      %s=%lld\n", e1, v1);
+       fprintf(stderr, "      %s=%lld\n", e2, v2);
        report_failure(extra);
        return (0);
 }
@@ -354,7 +391,7 @@ test_assert_equal_string(const char *file, int line,
                msg[0] = '\0';
                return (1);
        }
-       failures ++;
+       ++failures;
        if (!verbose && previous_failures(file, line, 1))
                return (0);
        fprintf(stderr, "%s:%d: Assertion failed: Strings not equal\n",
@@ -412,7 +449,7 @@ test_assert_equal_wstring(const char *file, int line,
                msg[0] = '\0';
                return (1);
        }
-       failures ++;
+       ++failures;
        if (!verbose && previous_failures(file, line, 1))
                return (0);
        fprintf(stderr, "%s:%d: Assertion failed: Unicode strings not equal\n",
@@ -485,7 +522,7 @@ test_assert_equal_mem(const char *file, int line,
                msg[0] = '\0';
                return (1);
        }
-       failures ++;
+       ++failures;
        if (!verbose && previous_failures(file, line, 1))
                return (0);
        fprintf(stderr, "%s:%d: Assertion failed: memory not equal\n",
@@ -533,7 +570,7 @@ test_assert_empty_file(const char *f1fmt, ...)
        if (st.st_size == 0)
                return (1);
 
-       failures ++;
+       ++failures;
        if (!verbose && previous_failures(test_filename, test_line, 1))
                return (0);
 
@@ -570,13 +607,13 @@ test_assert_non_empty_file(const char *f1fmt, ...)
                fprintf(stderr, "%s:%d: Could not stat: %s\n",
                    test_filename, test_line, f1);
                report_failure(NULL);
-               failures++;
+               ++failures;
                return (0);
        }
        if (st.st_size != 0)
                return (1);
 
-       failures ++;
+       ++failures;
        if (!verbose && previous_failures(test_filename, test_line, 1))
                return (0);
 
@@ -619,7 +656,7 @@ test_assert_equal_file(const char *fn1, const char *f2pattern, ...)
        }
        fclose(f1);
        fclose(f2);
-       failures ++;
+       ++failures;
        if (!verbose && previous_failures(test_filename, test_line, 1))
                return (0);
        fprintf(stderr, "%s:%d: Files are not identical\n",
@@ -636,12 +673,19 @@ test_assert_file_exists(const char *fpattern, ...)
        char f[1024];
        va_list ap;
 
+       count_assertion(test_filename, test_line);
        va_start(ap, fpattern);
        vsprintf(f, fpattern, ap);
        va_end(ap);
 
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       if (!_access(f, 0))
+               return (1);
+#else
        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);
@@ -657,12 +701,19 @@ test_assert_file_not_exists(const char *fpattern, ...)
        char f[1024];
        va_list ap;
 
+       count_assertion(test_filename, test_line);
        va_start(ap, fpattern);
        vsprintf(f, fpattern, ap);
        va_end(ap);
 
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       if (_access(f, 0))
+               return (1);
+#else
        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);
@@ -682,13 +733,14 @@ test_assert_file_contents(const void *buff, int s, const char *fpattern, ...)
        FILE *f;
        int n;
 
+       count_assertion(test_filename, test_line);
        va_start(ap, fpattern);
        vsprintf(fn, fpattern, ap);
        va_end(ap);
 
        f = fopen(fn, "rb");
        if (f == NULL) {
-               failures ++;
+               ++failures;
                if (!previous_failures(test_filename, test_line, 1)) {
                        fprintf(stderr, "%s:%d: File doesn't exist: %s\n",
                            test_filename, test_line, fn);
@@ -703,7 +755,62 @@ test_assert_file_contents(const void *buff, int s, const char *fpattern, ...)
                free(contents);
                return (1);
        }
-       failures ++;
+       ++failures;
+       if (!previous_failures(test_filename, test_line, 1)) {
+               fprintf(stderr, "%s:%d: File contents don't match\n",
+                   test_filename, test_line);
+               fprintf(stderr, "  file=\"%s\"\n", fn);
+               if (n > 0)
+                       hexdump(contents, buff, n > 512 ? 512 : 0, 0);
+               else {
+                       fprintf(stderr, "  File empty, contents should be:\n");
+                       hexdump(buff, NULL, s > 512 ? 512 : 0, 0);
+               }
+               report_failure(test_extra);
+       }
+       free(contents);
+       return (0);
+}
+
+/* assertTextFileContents() asserts the contents of a text file. */
+int
+test_assert_text_file_contents(const char *buff, const char *fn)
+{
+       char *contents;
+       const char *btxt, *ftxt;
+       FILE *f;
+       int n, s;
+
+       count_assertion(test_filename, test_line);
+       f = fopen(fn, "r");
+       s = strlen(buff);
+       contents = malloc(s * 2 + 128);
+       n = fread(contents, 1, s * 2 + 128 - 1, f);
+       if (n >= 0)
+               contents[n] = '\0';
+       fclose(f);
+       /* Compare texts. */
+       btxt = buff;
+       ftxt = (const char *)contents;
+       while (*btxt != '\0' && *ftxt != '\0') {
+               if (*btxt == *ftxt) {
+                       ++btxt;
+                       ++ftxt;
+                       continue;
+               }
+               if (btxt[0] == '\n' && ftxt[0] == '\r' && ftxt[1] == '\n') {
+                       /* Pass over different new line characters. */
+                       ++btxt;
+                       ftxt += 2;
+                       continue;
+               }
+               break;
+       }
+       if (*btxt == '\0' && *ftxt == '\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);
@@ -720,6 +827,208 @@ test_assert_file_contents(const void *buff, int s, const char *fpattern, ...)
        return (0);
 }
 
+int
+test_assert_file_hardlinks(const char *file, int line,
+                                                  const char *path1, const char *path2)
+{
+       struct stat st1, st2;
+       int r;
+
+       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);
+               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);
+               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);
+               }
+               return (0);
+       }
+       return (1);
+}
+
+int
+test_assert_file_nlinks(const char *file, int line,
+    const char *pathname, int nlinks)
+{
+       struct stat st;
+       int r;
+
+       count_assertion(file, line);
+       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);
+       }
+       return (0);
+}
+
+int
+test_assert_file_size(const char *file, int line,
+    const char *pathname, long size)
+{
+       struct stat st;
+       int r;
+
+       count_assertion(file, line);
+       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);
+       }
+       return (0);
+}
+
+int
+test_assert_is_dir(const char *file, int line, const char *pathname, int mode)
+{
+       struct stat st;
+       int r;
+
+       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);
+               }
+               return (0);
+       }
+       if (mode < 0) {
+               msg[0] = '\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);
+                       fprintf(stderr, "  Expected: 0%3o\n", mode);
+                       fprintf(stderr, "  Found: 0%3o\n", st.st_mode & 07777);
+                       report_failure(NULL);
+               }
+               return (0);
+       }
+       msg[0] = '\0';
+       return (1);
+}
+
+int
+test_assert_is_symlink(const char *file, int line,
+    const char *pathname, const char *contents)
+{
+       char buff[300];
+       struct stat st;
+       ssize_t linklen;
+       int r;
+
+       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);
+               }
+               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);
+               }
+               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);
+               }
+               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);
+                       fprintf(stderr, "   Expected: %s\n", contents);
+                       fprintf(stderr, "   Found: %s\n", buff);
+                       report_failure(NULL);
+               }
+               return (0);
+       }
+       return (1);
+}
+
+int
+test_assert_is_reg(const char *file, int line, const char *pathname, int mode)
+{
+       struct stat st;
+       int r;
+
+       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);
+               }
+               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);
+                       fprintf(stderr, "  Expected: 0%3o\n", mode);
+                       fprintf(stderr, "  Found: 0%3o\n", st.st_mode & 07777);
+                       report_failure(NULL);
+               }
+               return (0);
+       }
+       return (1);
+}
+
 int
 test_assert_make_dir(const char *file, int line, const char *dirname, int mode)
 {
@@ -727,7 +1036,7 @@ test_assert_make_dir(const char *file, int line, const char *dirname, int mode)
 
        count_assertion(file, line);
 #if defined(_WIN32) && !defined(__CYGWIN__)
-       r = mkdir(dirname);
+       r = _mkdir(dirname);
 #else
        r = mkdir(dirname, mode);
 #endif
@@ -735,7 +1044,7 @@ test_assert_make_dir(const char *file, int line, const char *dirname, int mode)
                msg[0] = '\0';
                return (1);
        }
-       failures++;
+       ++failures;
        if (!verbose && previous_failures(file, line, 1))
                return (0);
        fprintf(stderr, "%s:%d: Could not create directory\n",
@@ -744,6 +1053,70 @@ test_assert_make_dir(const char *file, int line, const char *dirname, int mode)
        return(0);
 }
 
+int
+test_assert_make_hardlink(const char *file, int line,
+                                                 const char *newpath, const char *linkto)
+{
+       int succeeded;
+
+       count_assertion(file, line);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       succeeded = CreateHardLink(newpath, linkto, NULL);
+#else
+       succeeded = !link(linkto, newpath);
+#endif
+       if (succeeded) {
+               msg[0] = '\0';
+               return (1);
+       }
+       ++failures;
+       if (verbose || !previous_failures(file, line, 1)) {
+               fprintf(stderr, "%s:%d: Could not create new hardlink\n",
+                       file, line);
+               fprintf(stderr, "   New link: %s\n", newpath);
+               fprintf(stderr, "   Old name: %s\n", linkto);
+       }
+       return(0);
+}
+
+
+int
+test_assert_make_symlink(const char *file, int line,
+                                                 const char *newpath, const char *linkto)
+{
+       int succeeded;
+
+       count_assertion(file, line);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       int targetIsDir = 0; /* TODO: Fix this. */
+       succeeded = CreateSymbolicLink(newpath, linkto, targetIsDir);
+#else
+       succeeded = !symlink(linkto, newpath);
+#endif
+       if (succeeded) {
+               msg[0] = '\0';
+               return (1);
+       }
+       ++failures;
+       if (verbose || !previous_failures(file, line, 1)) {
+               fprintf(stderr, "%s:%d: Could not create new symlink\n",
+                       file, line);
+               fprintf(stderr, "   New link: %s\n", newpath);
+               fprintf(stderr, "   Old name: %s\n", linkto);
+       }
+       return(0);
+}
+
+int
+test_assert_umask(const char *file, int line, int mask)
+{
+       count_assertion(file, line);
+       (void)file; /* UNUSED */
+       (void)line; /* UNUSED */
+       umask(mask);
+       return (1);
+}
+
 /*
  * Call standard system() call, but build up the command line using
  * sprintf() conventions.
@@ -795,13 +1168,13 @@ slurpfile(size_t * sizep, const char *fmt, ...)
                fclose(f);
                return (NULL);
        }
-       p = malloc(st.st_size + 1);
+       p = malloc((size_t)st.st_size + 1);
        if (p == NULL) {
                fprintf(stderr, "Can't allocate %ld bytes of memory to read file %s\n", (long int)st.st_size, filename);
                fclose(f);
                return (NULL);
        }
-       bytes_read = fread(p, 1, st.st_size, f);
+       bytes_read = fread(p, 1, (size_t)st.st_size, f);
        if (bytes_read < st.st_size) {
                fprintf(stderr, "Can't read file %s\n", filename);
                fclose(f);
@@ -836,6 +1209,7 @@ struct { void (*func)(void); const char *name; } tests[] = {
 static int test_run(int i, const char *tmpdir)
 {
        int failures_before = failures;
+       int oldumask;
 
        if (!quiet_flag) {
                printf("%d: %s\n", i, tests[i].name);
@@ -846,7 +1220,7 @@ static int test_run(int i, const char *tmpdir)
         * Always explicitly chdir() in case the last test moved us to
         * a strange place.
         */
-       if (chdir(tmpdir)) {
+       if (!assertChdir(tmpdir)) {
                fprintf(stderr,
                    "ERROR: Couldn't chdir to temp dir %s\n",
                    tmpdir);
@@ -860,7 +1234,7 @@ static int test_run(int i, const char *tmpdir)
                exit(1);
        }
        /* Chdir() to that work directory. */
-       if (chdir(tests[i].name)) {
+       if (!assertChdir(tests[i].name)) {
                fprintf(stderr,
                    "ERROR: Couldn't chdir to temp dir ``%s''\n",
                    tests[i].name);
@@ -868,13 +1242,17 @@ static int test_run(int i, const char *tmpdir)
        }
        /* Explicitly reset the locale before each test. */
        setlocale(LC_ALL, "C");
+       /* Record the umask before we run the test. */
+       umask(oldumask = umask(0));
        /* Run the actual test. */
        (*tests[i].func)();
+       /* Restore umask */
+       umask(oldumask);
        /* Summarize the results of this test. */
        summarize();
        /* If there were no failures, we can remove the work dir. */
        if (failures == failures_before) {
-               if (!keep_temp_files && chdir(tmpdir) == 0) {
+               if (!keep_temp_files && assertChdir(tmpdir)) {
 #if defined(_WIN32) && !defined(__CYGWIN__)
                        systemf("rmdir /S /Q %s", tests[i].name);
 #else
@@ -971,36 +1349,6 @@ extract_reference_file(const char *name)
        fclose(in);
 }
 
-
-/* Since gzip is by far the most popular external compression program
- * available, we try to use it in the read_program and write_program
- * tests.  But if it's not available, then we can't use it.  This
- * function just tries to run gzip/gunzip to see if they're available.
- * If not, some of the external compression program tests will be
- * skipped. */
-const char *
-external_gzip_program(int un)
-{
-       static int tested = 0;
-       static const char *compress_prog = NULL;
-       static const char *decompress_prog = NULL;
-       /* Args vary depending on the command interpreter we're using. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-       static const char *args = "-V >NUL 2>NUL"; /* Win32 cmd.exe */
-#else
-       static const char *args = "-V >/dev/null 2>/dev/null"; /* POSIX 'sh' */
-#endif
-
-       if (!tested) {
-               if (systemf("gunzip %s", args) == 0)
-                       decompress_prog = "gunzip";
-               if (systemf("gzip %s", args) == 0)
-                       compress_prog = "gzip";
-               tested = 1;
-       }
-       return (un ? decompress_prog : compress_prog);
-}
-
 static char *
 get_refdir(const char *d)
 {
@@ -1312,8 +1660,41 @@ int main(int argc, char **argv)
 
        /* If the final tmpdir is empty, we can remove it. */
        /* This should be the usual case when all tests succeed. */
-       chdir("..");
+       assertChdir("..");
        rmdir(tmpdir);
 
        return (tests_failed);
 }
+
+/*
+ * Special support specifically for libarchive.
+ */
+
+/* Since gzip is by far the most popular external compression program
+ * available, we try to use it in the read_program and write_program
+ * tests.  But if it's not available, then we can't use it.  This
+ * function just tries to run gzip/gunzip to see if they're available.
+ * If not, some of the external compression program tests will be
+ * skipped. */
+const char *
+external_gzip_program(int un)
+{
+       static int tested = 0;
+       static const char *compress_prog = NULL;
+       static const char *decompress_prog = NULL;
+       /* Args vary depending on the command interpreter we're using. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       static const char *args = "-V >NUL 2>NUL"; /* Win32 cmd.exe */
+#else
+       static const char *args = "-V >/dev/null 2>/dev/null"; /* POSIX 'sh' */
+#endif
+
+       if (!tested) {
+               if (systemf("gunzip %s", args) == 0)
+                       decompress_prog = "gunzip";
+               if (systemf("gzip %s", args) == 0)
+                       compress_prog = "gzip";
+               tested = 1;
+       }
+       return (un ? decompress_prog : compress_prog);
+}
index 972b2823ec1a6aeff385d2e9d9d71bcb3b360d73..b4c0a8fa192a8d3e2d09bde8eaa8d03f0264bca2 100644 (file)
 #else
 #include <direct.h>
 #endif
+#if defined(__CYGWIN__)
+/* In cygwin-1.7.x, the .nlinks field of directories is
+ * deliberately inaccurate, because to populate it requires
+ * stat'ing every file in the directory, which is slow.
+ * So, as an optimization cygwin doesn't do that in newer
+ * releases; all correct applications on any platform should
+ * never rely on it being > 1, so this optimization doesn't
+ * impact the operation of correctly coded applications.
+ * Therefore, the cpio test should not check its accuracy
+ */
+# define NLINKS_INACCURATE_FOR_DIRS
+#endif
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>  /* Windows requires this before sys/stat.h */
 #include <sys/stat.h>
 #if !defined(_WIN32) || defined(__CYGWIN__)
 #include <unistd.h>
 /* An implementation of the standard assert() macro */
 #define assert(e)   test_assert(__FILE__, __LINE__, (e), #e, NULL)
 
+#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 that file contents match a string; supports printf-style arguments. */
 #define assertFileContents             \
   test_setup(__FILE__, __LINE__);test_assert_file_contents
+#define assertFileHardlinks(path1, path2)      \
+  test_assert_file_hardlinks(__FILE__, __LINE__, path1, path2)
+#define assertFileNLinks(pathname, nlinks)  \
+  test_assert_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
+#define assertFileSize(pathname, size)  \
+  test_assert_file_size(__FILE__, __LINE__, pathname, size)
+#define assertTextFileContents         \
+  test_setup(__FILE__, __LINE__);test_assert_text_file_contents
+#define assertIsDir(pathname, mode)            \
+  test_assert_is_dir(__FILE__, __LINE__, pathname, mode)
+#define assertIsSymlink(pathname, contents)    \
+  test_assert_is_symlink(__FILE__, __LINE__, pathname, contents)
+#define assertIsReg(pathname, mode)            \
+  test_assert_is_reg(__FILE__, __LINE__, pathname, mode)
 /* Create a directory, report error if it fails. */
 #define assertMakeDir(dirname, mode)   \
   test_assert_make_dir(__FILE__, __LINE__, dirname, mode)
+#define assertMakeHardlink(newfile, oldfile)   \
+  test_assert_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
+#define assertMakeSymlink(newfile, linkto)     \
+  test_assert_make_symlink(__FILE__, __LINE__, newfile, linkto)
+#define assertUmask(mask)      \
+  test_assert_umask(__FILE__, __LINE__, mask)
 
 /*
  * This would be simple with C99 variadic macros, but I don't want to
@@ -151,17 +186,28 @@ 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, int, const char *, int, const char *, void *);
+int test_assert_equal_int(const char *, int, long long, const char *, long long, 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_size(const char *, int, const char *, long);
+int test_assert_is_dir(const char *, int, const char *, int);
+int test_assert_is_symlink(const char *, int, const char *, const char *);
+int test_assert_is_reg(const char *, int, const char *, int);
 int test_assert_make_dir(const char *, int, const char *, int);
+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_umask(const char *, int, int);
 
 /* Like sprintf, then system() */
 int systemf(const char * fmt, ...);
@@ -173,13 +219,13 @@ char *slurpfile(size_t *, const char *fmt, ...);
 /* Extracts named reference file to the current directory. */
 void extract_reference_file(const char *);
 
-/* Get external gzip program name */
-const char *external_gzip_program(int un);
-
 /*
  * Special interfaces for libarchive test harness.
  */
 
+/* Get external gzip program name */
+const char *external_gzip_program(int un);
+
 #include "archive.h"
 #include "archive_entry.h"
 
index 9017af922ae8a8109fa97796c05da4fc65ab5570..c402d5246b51c5309fc6b4f15735f418ea7c0aa9 100644 (file)
@@ -32,16 +32,9 @@ DEFINE_TEST(test_read_extract)
 {
        struct archive_entry *ae;
        struct archive *a;
-#if !defined(_WIN32) || defined(__CYGWIN__)
-       struct stat st;
-#endif
        size_t used;
        int i;
        char *buff, *file_buff;
-#if !defined(_WIN32) || defined(__CYGWIN__)
-       int fd;
-       ssize_t bytes_read;
-#endif
 
        buff = malloc(BUFF_SIZE);
        file_buff = malloc(FILE_BUFF_SIZE);
@@ -144,55 +137,27 @@ DEFINE_TEST(test_read_extract)
         * so the permissions should have been restored exactly,
         * including resetting the gid bit on those platforms
         * where gid is inherited by subdirs. */
-       assert(0 == stat("dir_0775", &st));
        failure("This was 0775 in archive, and should be 0775 on disk");
-       assertEqualInt(st.st_mode, S_IFDIR | 0775);
+       assertIsDir("dir_0775", 0775);
        /* Everything else was extracted without ARCHIVE_EXTRACT_PERM,
         * so there may be some sloppiness about gid bits on directories. */
-       assert(0 == stat("file", &st));
-       failure("st.st_mode=%o should be %o", st.st_mode, S_IFREG | 0755);
-       assertEqualInt(st.st_mode, S_IFREG | 0755);
-       failure("The file extracted to disk is the wrong size.");
-       assert(st.st_size == FILE_BUFF_SIZE);
-       fd = open("file", O_RDONLY | O_BINARY);
-       failure("The file on disk could not be opened.");
-       assert(fd != 0);
-       bytes_read = read(fd, buff, FILE_BUFF_SIZE);
-       close(fd);
-       failure("The file contents read from disk are the wrong size");
-       assert(bytes_read == FILE_BUFF_SIZE);
-       failure("The file contents on disk do not match the file contents that were put into the archive.");
-       assert(memcmp(buff, file_buff, FILE_BUFF_SIZE) == 0);
-       assert(0 == stat("dir", &st));
-       failure("This was 0777 in archive, but umask should make it 0755");
+       assertIsReg("file", 0755);
+       assertFileSize("file", FILE_BUFF_SIZE);
+       assertFileContents(file_buff, FILE_BUFF_SIZE, "file");
        /* If EXTRACT_PERM wasn't used, be careful to ignore sgid bit
         * when checking dir modes, as some systems inherit sgid bit
         * from the parent dir. */
-       assertEqualInt(0755, st.st_mode & 0777);
-       assert(0 == stat("dir/file", &st));
-       assert(st.st_mode == (S_IFREG | 0700));
-       assert(0 == stat("dir2", &st));
-       assertEqualInt(0755, st.st_mode & 0777);
-       assert(0 == stat("dir2/file", &st));
-       assert(st.st_mode == (S_IFREG | 0000));
-       assert(0 == stat("dir3", &st));
-       assertEqualInt(0710, st.st_mode & 0777);
-       assert(0 == stat("dir4", &st));
-       assertEqualInt(0755, st.st_mode & 0777);
-       assert(0 == stat("dir4/a", &st));
-       assertEqualInt(0755, st.st_mode & 0777);
-       assert(0 == stat("dir4/b", &st));
-       assertEqualInt(0755, st.st_mode & 0777);
-       assert(0 == stat("dir4/c", &st));
-       assertEqualInt(0711, st.st_mode & 0777);
-       assert(0 == lstat("symlink", &st));
-       assert(S_ISLNK(st.st_mode));
-#if HAVE_LCHMOD
-       /* Systems that lack lchmod() can't set symlink perms, so skip this. */
-       assert((st.st_mode & 07777) == 0755);
-#endif
-       assert(0 == stat("symlink", &st));
-       assert(st.st_mode == (S_IFREG | 0755));
+       failure("This was 0777 in archive, but umask should make it 0755");
+       assertIsDir("dir", 0755);
+       assertIsReg("dir/file", 0700);
+       assertIsDir("dir2", 0755);
+       assertIsReg("dir2/file", 0000);
+       assertIsDir("dir3", 0710);
+       assertIsDir("dir4", 0755);
+       assertIsDir("dir4/a", 0755);
+       assertIsDir("dir4/b", 0755);
+       assertIsDir("dir4/c", 0711);
+       assertIsSymlink("symlink", NULL); /* TODO: Assert value of symlink */
 #endif
 
        free(buff);
index 330cde62914e3b9a04eeae262d5b89a612d439f6..2bc7747656e30c794ca2e5544d2e6bad0a3e1951 100644 (file)
@@ -60,8 +60,8 @@ DEFINE_TEST(test_read_format_mtree)
         * the routine which open a directory that we create
         * "dir" and "dir2" directories.
         */
-       assertEqualInt(0, mkdir("dir", 0775));
-       assertEqualInt(0, mkdir("dir2", 0775));
+       assertMakeDir("dir", 0775);
+       assertMakeDir("dir2", 0775);
 
        assert((a = archive_read_new()) != NULL);
        assertEqualIntA(a, ARCHIVE_OK,
index 672266222dd682646a4710962bc4790f2ac43493..cead3f7a2fee87921034d23a926f478b5f680efd 100644 (file)
@@ -96,14 +96,10 @@ static void create_reg_file(struct archive_entry *ae, const char *msg)
        assertEqualInt(0, archive_write_finish(ad));
 #endif
        /* Test the entries on disk. */
-       assert(0 == stat(archive_entry_pathname(ae), &st));
-       failure("st.st_mode=%o archive_entry_mode(ae)=%o",
-           st.st_mode, archive_entry_mode(ae));
-#if !defined(_WIN32) || defined(__CYGWIN__)
-       assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK));
-#endif
-       assertEqualInt(st.st_size, sizeof(data));
+       assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777);
+       assertFileSize(archive_entry_pathname(ae), sizeof(data));
        /* test_write_disk_times has more detailed tests of this area. */
+       assert(0 == stat(archive_entry_pathname(ae), &st));
         assertEqualInt(st.st_mtime, 123456789);
         failure("No atime was specified, so atime should get set to current time");
        now = time(NULL);
@@ -114,10 +110,8 @@ static void create_reg_file2(struct archive_entry *ae, const char *msg)
 {
        const int datasize = 100000;
        char *data;
-       char *compare;
        struct archive *ad;
-       struct stat st;
-       int i, fd;
+       int i;
 
        data = malloc(datasize);
        for (i = 0; i < datasize; i++)
@@ -137,26 +131,12 @@ static void create_reg_file2(struct archive_entry *ae, const char *msg)
                    archive_write_data_block(ad, data + i, 1000, i));
        }
        assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
-#if ARCHIVE_VERSION_NUMBER < 2000000
-       archive_write_finish(ad);
-#else
        assertEqualInt(0, archive_write_finish(ad));
-#endif
-       /* Test the entries on disk. */
-       assert(0 == stat(archive_entry_pathname(ae), &st));
-       failure("st.st_mode=%o archive_entry_mode(ae)=%o",
-           st.st_mode, archive_entry_mode(ae));
-#if !defined(_WIN32) || defined(__CYGWIN__)
-       assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK));
-#endif
-       assertEqualInt(st.st_size, i);
 
-       compare = malloc(datasize);
-       fd = open(archive_entry_pathname(ae), O_RDONLY | O_BINARY);
-       assertEqualInt(datasize, read(fd, compare, datasize));
-       close(fd);
-       assert(memcmp(compare, data, datasize) == 0);
-       free(compare);
+       /* Test the entries on disk. */
+       assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777);
+       assertFileSize(archive_entry_pathname(ae), i);
+       assertFileContents(data, datasize, archive_entry_pathname(ae));
        free(data);
 }
 
index 6040be0e3f601473646cdd11794f8917ee6f522b..f1cab1689ea27b029612467aa5dcb32d1cb637cf 100644 (file)
@@ -45,7 +45,7 @@ DEFINE_TEST(test_write_disk_failures)
        umask(UMASK);
 
        /* A directory that we can't write to. */
-       assertEqualInt(0, mkdir("dir", 0555));
+       assertMakeDir("dir", 0555);
 
        /* Can we? */
        fd = open("dir/testfile", O_WRONLY | O_CREAT | O_BINARY, 0777);
index 5ed36ff257938b2a3df4289cc69dac5ee367bedb..94ceb1f105b6dd72520c07376e83b28d6556b189 100644 (file)
@@ -182,7 +182,7 @@ DEFINE_TEST(test_write_disk_perms)
 
        /* Overwrite an existing dir. */
        /* For dir, the first perms should get left. */
-       assert(mkdir("dir_overwrite_0744", 0744) == 0);
+       assertMakeDir("dir_overwrite_0744", 0744);
        /* Check original perms. */
        assert(0 == stat("dir_overwrite_0744", &st));
        failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode);