From b822d3bb5d5084330a198d28a798c70775b836bb Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Thu, 15 May 2008 18:14:57 -0400 Subject: [PATCH] Overhaul this test a bit so that the right entries get stored as hardlinks, regardless of what order the underlying filesystem returns the files in. This basically just involves segregating the different groups of entries into separate dirs and specifying those dirs -- in the correct order -- on the command line, instead of relying entirely on the tree traversal. This should fix a persistent test failure that's been reported on Linux when using newer filesystems. SVN-Revision: 58 --- tar/test/test_copy.c | 190 ++++++++++++++++++++++++------------------- 1 file changed, 108 insertions(+), 82 deletions(-) diff --git a/tar/test/test_copy.c b/tar/test/test_copy.c index e0bbb064a..52b9b7866 100644 --- a/tar/test/test_copy.c +++ b/tar/test/test_copy.c @@ -35,11 +35,16 @@ create_tree(void) assertEqualInt(0, mkdir("original", 0775)); chdir("original"); + assertEqualInt(0, mkdir("f", 0775)); + assertEqualInt(0, mkdir("l", 0775)); + assertEqualInt(0, mkdir("m", 0775)); + assertEqualInt(0, mkdir("s", 0775)); + assertEqualInt(0, mkdir("d", 0775)); - buff[0] = 'f'; - buff[1] = '_'; for (i = 0; i < 200; i++) { - /* Create a file named "f_abcdef..." */ + buff[0] = 'f'; + buff[1] = '/'; + /* Create a file named "f/abcdef..." */ buff[i + 2] = 'a' + (i % 26); buff[i + 3] = '\0'; fd = open(buff, O_CREAT | O_WRONLY, 0644); @@ -47,23 +52,27 @@ create_tree(void) assertEqualInt(i + 3, write(fd, buff, strlen(buff))); close(fd); - /* Create a link named "l_abcdef..." to the above. */ + /* Create a link named "l/abcdef..." to the above. */ strcpy(buff2, buff); buff2[0] = 'l'; assertEqualInt(0, link(buff, buff2)); - /* Create a link named "m_abcdef..." to the above. */ + /* Create a link named "m/abcdef..." to the above. */ strcpy(buff2, buff); buff2[0] = 'm'; assertEqualInt(0, link(buff, buff2)); - /* Create a symlink named "s_abcdef..." to the above. */ - buff2[0] = 's'; - assertEqualInt(0, symlink(buff, buff2)); - - /* Create a dir named "d_abcdef...". */ - buff2[0] = 'd'; - assertEqualInt(0, mkdir(buff2, 0775)); + /* Create a symlink named "s/abcdef..." to the above. */ + strcpy(buff2 + 3, buff); + buff[0] = 's'; + buff2[0] = '.'; + buff2[1] = '.'; + buff2[2] = '/'; + assertEqualInt(0, symlink(buff2, buff)); + + /* Create a dir named "d/abcdef...". */ + buff[0] = 'd'; + assertEqualInt(0, mkdir(buff, 0775)); } chdir(".."); @@ -77,35 +86,44 @@ verify_tree(int limit) { struct stat st, st2; char filename[260]; + char name1[260]; + char name2[260]; char contents[260]; - int i, r; + int i, j, r; int fd; int len; - const char *p; + const char *p, *dp; DIR *d; struct dirent *de; /* Generate the names we know should be there and verify them. */ - for (i = 0; i < 200; i++) { - /* Verify a file named "f_abcdef..." */ - filename[0] = 'f'; - filename[1] = '_'; - filename[i + 2] = 'a' + (i % 26); - filename[i + 3] = '\0'; + for (i = 1; i < 200; i++) { + /* Generate a base name of the correct length. */ + for (j = 0; j < i; ++j) + filename[j] = 'a' + (j % 26); +#if 0 + for (n = i; n > 0; n /= 10) + filename[--j] = '0' + (n % 10); +#endif + filename[i] = '\0'; + + /* Verify a file named "f/abcdef..." */ + strcpy(name1, "f/"); + strcat(name1, filename); if (limit != LIMIT_USTAR || strlen(filename) <= 100) { - fd = open(filename, O_RDONLY); + fd = open(name1, O_RDONLY); failure("Couldn't open \"%s\": %s", - filename, strerror(errno)); + name1, strerror(errno)); if (assert(fd >= 0)) { len = read(fd, contents, i + 10); close(fd); - assertEqualInt(len, i + 3); + assertEqualInt(len, i + 2); /* Verify contents of 'contents' */ contents[len] = '\0'; failure("Each test file contains its own name"); - assertEqualString(filename, contents); - /* stat() file and get dev/ino for next check */ - assertEqualInt(0, lstat(filename, &st)); + assertEqualString(name1, contents); + /* stat() for dev/ino for next check */ + assertEqualInt(0, lstat(name1, &st)); } } @@ -114,18 +132,19 @@ verify_tree(int limit) * "original/" as part of the name, so the link * names here can't exceed 91 chars. */ - if (limit != LIMIT_USTAR || strlen(filename) <= 91) { - /* Verify hardlink "l_abcdef..." */ - filename[0] = 'l'; - assertEqualInt(0, (r = lstat(filename, &st2))); + strcpy(name2, "l/"); + strcat(name2, filename); + if (limit != LIMIT_USTAR || strlen(name2) <= 100) { + /* Verify hardlink "l/abcdef..." */ + assertEqualInt(0, (r = lstat(name2, &st2))); if (r == 0) { assertEqualInt(st2.st_dev, st.st_dev); assertEqualInt(st2.st_ino, st.st_ino); } /* Verify hardlink "m_abcdef..." */ - filename[0] = 'm'; - assertEqualInt(0, (r = lstat(filename, &st2))); + name2[0] = 'm'; + assertEqualInt(0, (r = lstat(name2, &st2))); if (r == 0) { assertEqualInt(st2.st_dev, st.st_dev); assertEqualInt(st2.st_ino, st.st_ino); @@ -136,30 +155,32 @@ verify_tree(int limit) * Symlink text doesn't include the 'original/' prefix, * so the limit here is 100 characters. */ - /* Verify symlink "s_abcdef..." */ - filename[0] = 's'; - if (limit != LIMIT_USTAR || strlen(filename) <= 100) { + /* Verify symlink "s/abcdef..." */ + strcpy(name2, "../s/"); + strcat(name2, filename); + if (limit != LIMIT_USTAR || strlen(name2) <= 100) { /* This is a symlink. */ failure("Couldn't stat %s (length %d)", filename, strlen(filename)); - if (assertEqualInt(0, lstat(filename, &st2))) { + if (assertEqualInt(0, lstat(name2 + 3, &st2))) { assert(S_ISLNK(st2.st_mode)); /* This is a symlink to the file above. */ - failure("Couldn't stat %s", filename); - if (assertEqualInt(0, stat(filename, &st2))) { + failure("Couldn't stat %s", name2 + 3); + if (assertEqualInt(0, stat(name2 + 3, &st2))) { assertEqualInt(st2.st_dev, st.st_dev); assertEqualInt(st2.st_ino, st.st_ino); } } } - /* Verify dir "d_abcdef...". */ - filename[0] = 'd'; + /* Verify dir "d/abcdef...". */ + strcpy(name1, "d/"); + strcat(name1, filename); if (limit != LIMIT_USTAR || strlen(filename) < 100) { /* This is a dir. */ failure("Couldn't stat %s (length %d)", - filename, strlen(filename)); - if (assertEqualInt(0, lstat(filename, &st2))) { + name1, strlen(filename)); + if (assertEqualInt(0, lstat(name1, &st2))) { if (assert(S_ISDIR(st2.st_mode))) { /* TODO: opendir/readdir this * directory and make sure @@ -171,43 +192,47 @@ verify_tree(int limit) } /* Now make sure nothing is there that shouldn't be. */ - d = opendir("."); - while ((de = readdir(d)) != NULL) { - p = de->d_name; - switch(p[0]) { - case 'l': case 'm': - if (limit == LIMIT_USTAR) { - failure("strlen(p) = %d", strlen(p)); - assert(strlen(p) < 92); - } - case 'd': - if (limit == LIMIT_USTAR) { - failure("strlen(p)=%d", strlen(p)); - assert(strlen(p) < 100); - } - case 'f': case 's': - if (limit == LIMIT_USTAR) { - failure("strlen(p)=%d", strlen(p)); - assert(strlen(p) < 101); + for (dp = "dflms"; *dp != '\0'; ++dp) { + char dir[2]; + dir[0] = *dp; dir[1] = '\0'; + d = opendir(dir); + while ((de = readdir(d)) != NULL) { + p = de->d_name; + switch(dp[0]) { + case 'l': case 'm': + if (limit == LIMIT_USTAR) { + failure("strlen(p) = %d", strlen(p)); + assert(strlen(p) <= 100); + } + case 'd': + if (limit == LIMIT_USTAR) { + failure("strlen(p)=%d", strlen(p)); + assert(strlen(p) < 100); + } + case 'f': case 's': + if (limit == LIMIT_USTAR) { + failure("strlen(p)=%d", strlen(p)); + assert(strlen(p) < 101); + } + /* Our files have very particular filename patterns. */ + if (p[0] != '.' || (p[1] != '.' && p[1] != '\0')) { + for (i = 0; p[i] != '\0' && i < 200; i++) { + failure("i=%d, p[i]='%c' 'a'+(i%%26)='%c'", i, p[i], 'a' + (i % 26)); + assertEqualInt(p[i], 'a' + (i % 26)); + } + assert(p[i] == '\0'); + } + break; + case '.': + assert(p[1] == '\0' || (p[1] == '.' && p[2] == '\0')); + break; + default: + failure("File %s shouldn't be here", p); + assert(0); } - /* Our files have very particular filename patterns. */ - assert(p[1] == '_' && p[2] == 'a'); - assert(p[2] == 'a'); - p += 2; - for (i = 0; p[i] != '\0' && i < 200; i++) - assert(p[i] == 'a' + (i % 26)); - assert(p[i] == '\0'); - break; - case '.': - assert(p[1] == '\0' || (p[1] == '.' && p[2] == '\0')); - break; - default: - failure("File %s shouldn't be here", p); - assert(0); } - + closedir(d); } - closedir(d); } static void @@ -216,12 +241,12 @@ copy_basic(void) int r; assertEqualInt(0, mkdir("plain", 0775)); - chdir("plain"); + assertEqualInt(0, chdir("plain")); /* * Use the tar program to create an archive. */ - r = systemf("%s cf archive -C .. original >pack.out 2>pack.err", + r = systemf("%s cf archive -C ../original f d l m s >pack.out 2>pack.err", testprog); failure("Error invoking \"%s cf\"", testprog); assertEqualInt(r, 0); @@ -241,9 +266,8 @@ copy_basic(void) assertEmptyFile("unpack.err"); assertEmptyFile("unpack.out"); - chdir("original"); verify_tree(LIMIT_NONE); - chdir("../.."); + assertEqualInt(0, chdir("..")); } static void @@ -253,18 +277,20 @@ copy_ustar(void) int r; assertEqualInt(0, mkdir(target, 0775)); - chdir(target); + assertEqualInt(0, chdir(target)); /* * Use the tar program to create an archive. */ - r = systemf("%s cf archive --format=ustar -C .. original >pack.out 2>pack.err", + r = systemf("%s cf archive --format=ustar -C ../original f d l m s >pack.out 2>pack.err", testprog); failure("Error invoking \"%s cf archive --format=ustar\"", testprog); assertEqualInt(r, 0); /* Verify that nothing went to stdout. */ assertEmptyFile("pack.out"); + /* Stderr is non-empty, since there are a bunch of files + * with filenames too long to archive. */ /* * Use tar to unpack the archive into another directory. -- 2.47.3