return (0);
}
+/* Verify that a text file contains the specified lines, regardless of order */
+/* This could be more efficient if we sorted both sets of lines, etc, but
+ * since this is used only for testing and only ever deals with a dozen or so
+ * lines at a time, this relatively crude approach is just fine. */
+int
+assertion_file_contains_lines_any_order(const char *file, int line,
+ const char *pathname, const char *lines[])
+{
+ char *buff;
+ size_t buff_size;
+ size_t expected_count, actual_count, i, j;
+ char **expected;
+ char *p, **actual;
+ char c;
+ int expected_failure = 0, actual_failure = 0;
+
+ assertion_count(file, line);
+
+ buff = slurpfile(&buff_size, "%s", pathname);
+ if (buff == NULL) {
+ failure_start(pathname, line, "Can't read file: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ // Make a copy of the provided lines and count up the expected file size.
+ expected_count = 0;
+ for (i = 0; lines[i] != NULL; ++i) {
+ }
+ expected_count = i;
+ expected = malloc(sizeof(char *) * expected_count);
+ for (i = 0; lines[i] != NULL; ++i) {
+ expected[i] = strdup(lines[i]);
+ }
+
+ // Break the file into lines
+ actual_count = 0;
+ for (c = '\0', p = buff; p < buff + buff_size; ++p) {
+ if (*p == '\x0d' || *p == '\x0a')
+ *p = '\0';
+ if (c == '\0' && *p != '\0')
+ ++actual_count;
+ c = *p;
+ }
+ actual = malloc(sizeof(char *) * actual_count);
+ for (j = 0, p = buff; p < buff + buff_size; p += 1 + strlen(p)) {
+ if (*p != '\0') {
+ actual[j] = p;
+ ++j;
+ }
+ }
+
+ // Erase matching lines from both lists
+ for (i = 0; i < expected_count; ++i) {
+ if (expected[i] == NULL)
+ continue;
+ for (j = 0; j < actual_count; ++j) {
+ if (actual[j] == NULL)
+ continue;
+ if (strcmp(expected[i], actual[j]) == 0) {
+ free(expected[i]);
+ expected[i] = NULL;
+ actual[j] = NULL;
+ break;
+ }
+ }
+ }
+
+ // If there's anything left, it's a failure
+ for (i = 0; i < expected_count; ++i) {
+ if (expected[i] != NULL)
+ ++expected_failure;
+ }
+ for (j = 0; j < actual_count; ++j) {
+ if (actual[j] != NULL)
+ ++actual_failure;
+ }
+ if (expected_failure == 0 && actual_failure == 0) {
+ free(buff);
+ free(expected);
+ free(actual);
+ return (1);
+ }
+ failure_start(file, line, "File doesn't match: %s", pathname);
+ for (i = 0; i < expected_count; ++i) {
+ if (expected[i] != NULL) {
+ free(expected[i]);
+ logprintf(" Expected but not present: %s\n", expected[i]);
+ }
+ }
+ for (j = 0; j < actual_count; ++j) {
+ if (actual[j] != NULL)
+ logprintf(" Present but not expected: %s\n", actual[j]);
+ }
+ failure_finish(NULL);
+ free(buff);
+ free(expected);
+ free(actual);
+ return (0);
+}
+
/* Test that two paths point to the same file. */
/* As a side-effect, asserts that both files exist. */
static int
assertion_file_size(__FILE__, __LINE__, pathname, size)
#define assertTextFileContents \
assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
+#define assertFileContainsLinesAnyOrder(pathname, lines) \
+ assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
#define assertIsDir(pathname, mode) \
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2) \
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
+int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
int assertion_file_contents(const void *, int, const char *, ...);
int assertion_file_exists(const char *, ...);
int assertion_file_mtime(const char *, int, const char *, long, long);
*path2 = fp2;
}
-static const char list1[] =
- "aaa/\r\naaa/file1\r\naaa/xxa/\r\naaa/xxb/\r\naaa/zzc/\r\n"
- "aaa/zzc/file1\r\naaa/xxb/file1\r\naaa/xxa/file1\r\naab/\r\n"
- "aac/\r\nabb/\r\nabc/\r\nabd/\r\n";
-static const char list2[] =
- "bbb/\r\nbbb/file1\r\nbbb/xxa/\r\nbbb/xxb/\r\nbbb/zzc/\r\n"
- "bbb/zzc/file1\r\nbbb/xxb/file1\r\nbbb/xxa/file1\r\nbbc/\r\n"
- "bbd/\r\nbcc/\r\nbcd/\r\nbce/\r\n";
-static const char list3[] =
- "aac/\r\nabc/\r\nbbc/\r\nbcc/\r\nccc/\r\n";
-static const char list4[] =
- "fff/abca\r\nfff/acca\r\n";
-static const char list5[] =
- "aaa/file1\r\naaa/xxa/\r\naaa/xxa/file1\r\naaa/xxb/\r\n"
- "aaa/xxb/file1\r\naaa/zzc/\r\naaa/zzc/file1\r\n";
-static const char list6[] =
- "fff/abca\r\nfff/acca\r\naaa/xxa/\r\naaa/xxa/file1\r\n"
- "aaa/xxb/\r\naaa/xxb/file1\r\n";
+static const char *list1[] = {"aaa/", "aaa/file1", "aaa/xxa/", "aaa/xxb/",
+ "aaa/zzc/", "aaa/zzc/file1", "aaa/xxb/file1", "aaa/xxa/file1",
+ "aab/", "aac/", "abb/", "abc/", "abd/", NULL};
+static const char *list2[] = {"bbb/", "bbb/file1", "bbb/xxa/", "bbb/xxb/",
+ "bbb/zzc/", "bbb/zzc/file1", "bbb/xxb/file1", "bbb/xxa/file1", "bbc/",
+ "bbd/", "bcc/", "bcd/", "bce/", NULL};
+static const char *list3[] = {"aac/", "abc/", "bbc/", "bcc/", "ccc/", NULL};
+static const char *list4[] = {"fff/abca", "fff/acca", NULL};
+static const char *list5[] = {"aaa/file1", "aaa/xxa/", "aaa/xxa/file1",
+ "aaa/xxb/", "aaa/xxb/file1", "aaa/zzc/", "aaa/zzc/file1", NULL};
+static const char *list6[] = {"fff/abca", "fff/acca", "aaa/xxa/",
+ "aaa/xxa/file1", "aaa/xxb/", "aaa/xxb/file1", NULL};
#endif /* _WIN32 && !__CYGWIN__ */
DEFINE_TEST(test_windows)
systemf("%s -cf ../archive1.tar a*", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive1.tar > ../list1", testprog));
- assertFileContents(list1, strlen(list1), "../list1");
+ assertFileContainsLinesAnyOrder("../list1", list1);
assertEqualInt(0,
systemf("%s -cf ../archive2.tar b*", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive2.tar > ../list2", testprog));
- assertFileContents(list2, strlen(list2), "../list2");
+ assertFileContainsLinesAnyOrder("../list2", list2);
assertEqualInt(0,
systemf("%s -cf ../archive3.tar ??c", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive3.tar > ../list3", testprog));
- assertFileContents(list3, strlen(list3), "../list3");
+ assertFileContainsLinesAnyOrder("../list3", list3);
assertEqualInt(0,
systemf("%s -cf ../archive3b.tar *c", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive3b.tar > ../list3b", testprog));
- assertFileContents(list3, strlen(list3), "../list3b");
+ assertFileContainsLinesAnyOrder("../list3b", list3);
assertEqualInt(0,
systemf("%s -cf ../archive4.tar fff/a?ca", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive4.tar > ../list4", testprog));
- assertFileContents(list4, strlen(list4), "../list4");
+ assertFileContainsLinesAnyOrder("../list4", list4);
assertEqualInt(0,
systemf("%s -cf ../archive5.tar aaa\\*", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive5.tar > ../list5", testprog));
- assertFileContents(list5, strlen(list5), "../list5");
+ assertFileContainsLinesAnyOrder("../list5", list5);
assertEqualInt(0,
systemf("%s -cf ../archive6.tar fff\\a?ca aaa\\xx*", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive6.tar > ../list6", testprog));
- assertFileContents(list6, strlen(list6), "../list6");
+ assertFileContainsLinesAnyOrder("../list6", list6);
/*
* Test2: Archive the file start with drive letters.