]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Refactor hardlink/symlink support in test harness: we now have
authorTim Kientzle <kientzle@gmail.com>
Sat, 12 Sep 2009 05:24:28 +0000 (01:24 -0400)
committerTim Kientzle <kientzle@gmail.com>
Sat, 12 Sep 2009 05:24:28 +0000 (01:24 -0400)
assertIsHardlink() and assertIsNotHardlink().  On the symlink side,
I've added a run-time platform probe canSymlink() that tests the
local platform the first time it is called and remembers the result.
As an experiment, refactor test_basic.c to omit symlinks from the
tests if the current platform lacks symlink support.

SVN-Revision: 1455

cpio/test/main.c
cpio/test/test.h
cpio/test/test_basic.c
cpio/test/test_gcpio_compat.c
cpio/test/test_option_l.c

index 6100ecceaae42463bb325487cac9a29be7589773..15ee5671933f8f099e09f22bd7f6fa1fa2174c1c 100644 (file)
@@ -811,8 +811,8 @@ assertion_text_file_contents(const char *buff, const char *fn)
 
 /* Test that two paths point to the same file. */
 /* As a side-effect, asserts that both files exist. */
-int
-is_file_hardlinks(const char *file, int line,
+static int
+is_hardlink(const char *file, int line,
     const char *path1, const char *path2)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -856,10 +856,10 @@ is_file_hardlinks(const char *file, int line,
 }
 
 int
-assertion_file_hardlinks(const char *file, int line,
-                                                const char *path1, const char *path2)
-{ 
-       if (is_file_hardlinks(file, line, path1, path2))
+assertion_is_hardlink(const char *file, int line,
+    const char *path1, const char *path2)
+{
+       if (is_hardlink(file, line, path1, path2))
                return (1);
        failure_start(file, line,
            "Files %s and %s are not hardlinked", path1, path2);
@@ -867,6 +867,18 @@ assertion_file_hardlinks(const char *file, int line,
        return (0);
 }
 
+int
+assertion_is_not_hardlink(const char *file, int line,
+    const char *path1, const char *path2)
+{
+       if (!is_hardlink(file, line, path1, path2))
+               return (1);
+       failure_start(file, line,
+           "Files %s and %s should not be hardlinked", path1, path2);
+       failure_finish(NULL);
+       return (0);
+}
+
 /* Verify a/b/mtime of 'pathname'. */
 /* If 'recent', verify that it's within last 10 seconds. */
 static int
@@ -1122,17 +1134,14 @@ assertion_is_reg(const char *file, int line, const char *pathname, int mode)
        return (1);
 }
 
-/* Verify that 'pathname' is a symbolic link.  If 'contents' is
+/* Check whether 'pathname' is a symbolic link.  If 'contents' is
  * non-NULL, verify that the symlink has those contents. */
-int
-assertion_is_symlink(const char *file, int line,
+static int
+is_symlink(const char *file, int line,
     const char *pathname, const char *contents)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
        assertion_count(file, line);
-       /* TODO: Vista supports symlinks */
-       failure_start(file, line, "Symlink %s not supported", pathname);
-       failure_finish(NULL);
        return (0);
 #else
        char buff[300];
@@ -1148,11 +1157,8 @@ assertion_is_symlink(const char *file, int line,
                failure_finish(NULL);
                return (0);
        }
-       if (!S_ISLNK(st.st_mode)) {
-               failure_start(file, line, "%s should be a symlink", pathname);
-               failure_finish(NULL);
+       if (!S_ISLNK(st.st_mode))
                return (0);
-       }
        if (contents == NULL)
                return (1);
        linklen = readlink(pathname, buff, sizeof(buff));
@@ -1162,17 +1168,29 @@ assertion_is_symlink(const char *file, int line,
                return (0);
        }
        buff[linklen] = '\0';
-       if (strcmp(buff, contents) != 0) {
-               failure_start(file, line, "Wrong symlink %s", pathname);
-               logprintf("   Expected: %s\n", contents);
-               logprintf("   Found: %s\n", buff);
-               failure_finish(NULL);
+       if (strcmp(buff, contents) != 0)
                return (0);
-       }
        return (1);
 #endif
 }
 
+/* Assert that path is a symlink that (optionally) contains contents. */
+int
+assertion_is_symlink(const char *file, int line,
+    const char *path, const char *contents)
+{
+       if (is_symlink(file, line, path, contents))
+               return (1);
+       if (contents)
+               failure_start(file, line, "File %s is not a symlink to %s",
+                   path, contents);
+       else
+               failure_start(file, line, "File %s is not a symlink", path);
+       failure_finish(NULL);
+       return (0);
+}
+
+
 /* Create a directory and report any errors. */
 int
 assertion_make_dir(const char *file, int line, const char *dirname, int mode)
@@ -1303,6 +1321,32 @@ assertion_umask(const char *file, int line, int mask)
  *
  */
 
+/*
+ * Check whether platform supports symlinks.  This is intended
+ * for tests to use in deciding whether to bother testing symlink
+ * support; if the platform doesn't support symlinks, there's no point
+ * in checking whether the program being tested can create them.
+ */
+int
+canSymlink(void)
+{
+       /* Remember the test result */
+       static int value = 0, tested = 1;
+       if (tested)
+               return (value);
+
+       ++tested;
+       assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       value = my_CreateSymbolicLinkA("canSymlink.1", "canSymlink.0", 0)
+           && is_symlink(__FILE__, __LINE__, "canSymlink.1", "canSymlink.0");
+#elif HAVE_SYMLINK
+       value = (0 == symlink("canSymlink.0", "canSymlink.1"))
+           && is_symlink(__FILE__, __LINE__, "canSymlink.1","canSymlink.0");
+#endif
+       return (value);
+}
+
 /*
  * Sleep as needed; useful for verifying disk timestamp changes by
  * ensuring that the wall-clock time has actually changed before we
index 5d89a45c406ff01287bc204c5238d0ca6d73add7..e2e83b3ef798d11276c9512e91d176df564bfb94 100644 (file)
 /* Assert that file contents match a string; supports printf-style arguments. */
 #define assertFileContents             \
   assertion_setup(__FILE__, __LINE__);assertion_file_contents
-#define assertFileHardlinks(path1, path2)      \
-  assertion_file_hardlinks(__FILE__, __LINE__, path1, path2)
 #define assertFileMtime(pathname, sec, nsec)   \
   assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
 #define assertFileMtimeRecent(pathname) \
   assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
 #define assertIsDir(pathname, mode)            \
   assertion_is_dir(__FILE__, __LINE__, pathname, mode)
+#define assertIsHardlink(path1, path2) \
+  assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
+#define assertIsNotHardlink(path1, path2)      \
+  assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
 #define assertIsReg(pathname, mode)            \
   assertion_is_reg(__FILE__, __LINE__, pathname, mode)
 #define assertIsSymlink(pathname, contents)    \
 #define assertUmask(mask)      \
   assertion_umask(__FILE__, __LINE__, mask)
 
-/*
- */
-#define isFileHardlinks(path1, path2)  \
-  is_file_hardlinks(__FILE__, __LINE__, path1, path2)
-
 /*
  * This would be simple with C99 variadic macros, but I don't want to
  * require that.  Instead, I insert a function call before each
@@ -226,13 +223,14 @@ int assertion_file_birthtime(const char *, int, const char *, long, long);
 int assertion_file_birthtime_recent(const char *, int, const char *);
 int assertion_file_contents(const void *, int, const char *, ...);
 int assertion_file_exists(const char *, ...);
-int assertion_file_hardlinks(const char *, int, const char *, const char *);
 int assertion_file_mtime(const char *, int, const char *, long, long);
 int assertion_file_mtime_recent(const char *, int, const char *);
 int assertion_file_nlinks(const char *, int, const char *, int);
 int assertion_file_not_exists(const char *, ...);
 int assertion_file_size(const char *, int, const char *, long);
 int assertion_is_dir(const char *, int, const char *, int);
+int assertion_is_hardlink(const char *, int, const char *, const char *);
+int assertion_is_not_hardlink(const char *, int, const char *, const char *);
 int assertion_is_reg(const char *, int, const char *, int);
 int assertion_is_symlink(const char *, int, const char *, const char *);
 int assertion_make_dir(const char *, int, const char *, int);
@@ -244,7 +242,6 @@ int assertion_text_file_contents(const char *buff, const char *f);
 int assertion_umask(const char *, int, int);
 void assertion_setup(const char *, int);
 
-int is_file_hardlinks(const char *, int, const char *, const char *);
 void test_skipping(const char *fmt, ...);
 
 /* Like sprintf, then system() */
@@ -253,6 +250,9 @@ int systemf(const char * fmt, ...);
 /* Delay until time() returns a value after this. */
 void sleepUntilAfter(time_t);
 
+/* Return true if this platform can create symlinks. */
+int canSymlink(void);
+
 /* 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, ...);
index 65fe82444c3f29282c73e024353a2f617ac064d1..b56e80785f0764fc51d2ad6049089cef3e47abeb 100644 (file)
@@ -38,12 +38,11 @@ verify_files(void)
        assertFileNLinks("file", 2);
 
        /* Another name for the same file. */
-       assertFileHardlinks("linkfile", "file");
+       assertIsHardlink("linkfile", "file");
 
        /* Symlink */
-#if !defined(_WIN32) || defined(__CYGWIN__)
-       assertIsSymlink("symlink", "file");
-#endif
+       if (canSymlink())
+               assertIsSymlink("symlink", "file");
 
        /* Another file with 1 link and different permissions. */
        assertIsReg("file2", 0777);
@@ -124,6 +123,7 @@ passthrough(const char *target)
 DEFINE_TEST(test_basic)
 {
        FILE *filelist;
+       const char *msg;
 
        assertUmask(0);
 
@@ -141,8 +141,10 @@ DEFINE_TEST(test_basic)
        fprintf(filelist, "linkfile\n");
 
        /* Symlink to above file. */
-       assertMakeSymlink("symlink", "file");
-       fprintf(filelist, "symlink\n");
+       if (canSymlink()) {
+               assertMakeSymlink("symlink", "file");
+               fprintf(filelist, "symlink\n");
+       }
 
        /* Another file with different permissions. */
        assertMakeFile("file2", 0777, "1234567890");
@@ -157,20 +159,14 @@ DEFINE_TEST(test_basic)
        assertUmask(022);
 
        /* Archive/dearchive with a variety of options. */
-       basic_cpio("copy", "", "", "2 blocks\n");
-       basic_cpio("copy_odc", "--format=odc", "", "2 blocks\n");
+       msg = canSymlink() ? "2 blocks\n" : "1 block\n";
+       basic_cpio("copy", "", "", msg);
+       basic_cpio("copy_odc", "--format=odc", "", msg);
        basic_cpio("copy_newc", "-H newc", "", "2 blocks\n");
-       basic_cpio("copy_cpio", "-H odc", "", "2 blocks\n");
-#if defined(_WIN32) && !defined(__CYGWIN__)
-       /*
-        * On Windows, symbolic link does not work.
-        * Currentry copying file instead. therefore block size is
-        * different.
-        */
-       basic_cpio("copy_ustar", "-H ustar", "", "10 blocks\n");
-#else
-       basic_cpio("copy_ustar", "-H ustar", "", "9 blocks\n");
-#endif
+       basic_cpio("copy_cpio", "-H odc", "", msg);
+       msg = canSymlink() ? "9 blocks\n" : "8 blocks\n";
+       basic_cpio("copy_ustar", "-H ustar", "", msg);
+
        /* Copy in one step using -p */
        passthrough("passthrough");
 }
index 320ca6604bd850922faa9de3a7427aabfcdadbbb..2a98dfc66939f23416cbf3b44f78d3fe1fdf0019 100644 (file)
@@ -58,7 +58,7 @@ unpack_test(const char *from, const char *options, const char *se)
        assertFileNLinks("file", 2);
 
        /* Another name for the same file. */
-       assertFileHardlinks("linkfile", "file");
+       assertIsHardlink("linkfile", "file");
 
        /* Symlink */
        assertIsSymlink("symlink", "file");
index f2cd5bfbf40c4ccd16a28e409ad552ee1872f1a1..5c76e688e6e911c8a78aa4e686fb83cf4b0a1521 100644 (file)
@@ -38,7 +38,7 @@ DEFINE_TEST(test_option_l)
        assertEqualInt(r, 0);
 
        /* Check that the copy is a true copy and not a link. */
-       assert(!isFileHardlinks("f", "copy/f"));
+       assertIsNotHardlink("f", "copy/f");
 
        /* Copy the file to the "link" dir with the -l option. */
        r = systemf("echo f | %s -pld link >link.out 2>link.err",
@@ -46,5 +46,5 @@ DEFINE_TEST(test_option_l)
        assertEqualInt(r, 0);
 
        /* Check that this is a link and not a copy. */
-       assertFileHardlinks("f", "link/f");
+       assertIsHardlink("f", "link/f");
 }