]> git.ipfire.org Git - thirdparty/git.git/blobdiff - reftable/stack_test.c
Merge branch 'jt/reftable-geometric-compaction'
[thirdparty/git.git] / reftable / stack_test.c
index 7336757cf534058dd6f3e8346d15874036c5b763..1df3ffce5261f2cf63c3719198e0e2d71df13bb8 100644 (file)
@@ -38,7 +38,17 @@ static int count_dir_entries(const char *dirname)
                return 0;
 
        while ((d = readdir(dir))) {
-               if (!strcmp(d->d_name, "..") || !strcmp(d->d_name, "."))
+               /*
+                * Besides skipping over "." and "..", we also need to
+                * skip over other files that have a leading ".". This
+                * is due to behaviour of NFS, which will rename files
+                * to ".nfs*" to emulate delete-on-last-close.
+                *
+                * In any case this should be fine as the reftable
+                * library will never write files with leading dots
+                * anyway.
+                */
+               if (starts_with(d->d_name, "."))
                        continue;
                len++;
        }
@@ -232,7 +242,7 @@ static void test_reftable_stack_uptodate(void)
        EXPECT_ERR(err);
 
        err = reftable_stack_add(st2, &write_test_ref, &ref2);
-       EXPECT(err == REFTABLE_LOCK_ERROR);
+       EXPECT(err == REFTABLE_OUTDATED_ERROR);
 
        err = reftable_stack_reload(st2);
        EXPECT_ERR(err);
@@ -315,7 +325,7 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)
                 * we can ensure that we indeed honor this setting and have
                 * better control over when exactly auto compaction runs.
                 */
-               st->disable_auto_compact = i != n;
+               st->config.disable_auto_compact = i != n;
 
                err = reftable_stack_new_addition(&add, st);
                EXPECT_ERR(err);
@@ -343,6 +353,49 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)
        clear_dir(dir);
 }
 
+static void test_reftable_stack_auto_compaction_fails_gracefully(void)
+{
+       struct reftable_ref_record ref = {
+               .refname = "refs/heads/master",
+               .update_index = 1,
+               .value_type = REFTABLE_REF_VAL1,
+               .value.val1 = {0x01},
+       };
+       struct reftable_write_options cfg = {0};
+       struct reftable_stack *st;
+       struct strbuf table_path = STRBUF_INIT;
+       char *dir = get_tmp_dir(__LINE__);
+       int err;
+
+       err = reftable_new_stack(&st, dir, cfg);
+       EXPECT_ERR(err);
+
+       err = reftable_stack_add(st, write_test_ref, &ref);
+       EXPECT_ERR(err);
+       EXPECT(st->merged->stack_len == 1);
+       EXPECT(st->stats.attempts == 0);
+       EXPECT(st->stats.failures == 0);
+
+       /*
+        * Lock the newly written table such that it cannot be compacted.
+        * Adding a new table to the stack should not be impacted by this, even
+        * though auto-compaction will now fail.
+        */
+       strbuf_addf(&table_path, "%s/%s.lock", dir, st->readers[0]->name);
+       write_file_buf(table_path.buf, "", 0);
+
+       ref.update_index = 2;
+       err = reftable_stack_add(st, write_test_ref, &ref);
+       EXPECT_ERR(err);
+       EXPECT(st->merged->stack_len == 2);
+       EXPECT(st->stats.attempts == 1);
+       EXPECT(st->stats.failures == 1);
+
+       reftable_stack_destroy(st);
+       strbuf_release(&table_path);
+       clear_dir(dir);
+}
+
 static void test_reftable_stack_validate_refname(void)
 {
        struct reftable_write_options cfg = { 0 };
@@ -444,6 +497,7 @@ static void test_reftable_stack_add(void)
        struct reftable_write_options cfg = {
                .exact_log_message = 1,
                .default_permissions = 0660,
+               .disable_auto_compact = 1,
        };
        struct reftable_stack *st = NULL;
        char *dir = get_tmp_dir(__LINE__);
@@ -455,7 +509,6 @@ static void test_reftable_stack_add(void)
 
        err = reftable_new_stack(&st, dir, cfg);
        EXPECT_ERR(err);
-       st->disable_auto_compact = 1;
 
        for (i = 0; i < N; i++) {
                char buf[256];
@@ -717,59 +770,13 @@ static void test_reftable_stack_hash_id(void)
        clear_dir(dir);
 }
 
-static void test_log2(void)
-{
-       EXPECT(1 == fastlog2(3));
-       EXPECT(2 == fastlog2(4));
-       EXPECT(2 == fastlog2(5));
-}
-
-static void test_sizes_to_segments(void)
-{
-       uint64_t sizes[] = { 2, 3, 4, 5, 7, 9 };
-       /* .................0  1  2  3  4  5 */
-
-       size_t seglen = 0;
-       struct segment *segs =
-               sizes_to_segments(&seglen, sizes, ARRAY_SIZE(sizes));
-       EXPECT(segs[2].log == 3);
-       EXPECT(segs[2].start == 5);
-       EXPECT(segs[2].end == 6);
-
-       EXPECT(segs[1].log == 2);
-       EXPECT(segs[1].start == 2);
-       EXPECT(segs[1].end == 5);
-       reftable_free(segs);
-}
-
-static void test_sizes_to_segments_empty(void)
-{
-       size_t seglen = 0;
-       struct segment *segs = sizes_to_segments(&seglen, NULL, 0);
-       EXPECT(seglen == 0);
-       reftable_free(segs);
-}
-
-static void test_sizes_to_segments_all_equal(void)
-{
-       uint64_t sizes[] = { 5, 5 };
-       size_t seglen = 0;
-       struct segment *segs =
-               sizes_to_segments(&seglen, sizes, ARRAY_SIZE(sizes));
-       EXPECT(seglen == 1);
-       EXPECT(segs[0].start == 0);
-       EXPECT(segs[0].end == 2);
-       reftable_free(segs);
-}
-
 static void test_suggest_compaction_segment(void)
 {
-       uint64_t sizes[] = { 128, 64, 17, 16, 9, 9, 9, 16, 16 };
-       /* .................0    1    2  3   4  5  6 */
+       uint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 };
        struct segment min =
                suggest_compaction_segment(sizes, ARRAY_SIZE(sizes));
-       EXPECT(min.start == 2);
-       EXPECT(min.end == 7);
+       EXPECT(min.start == 1);
+       EXPECT(min.end == 10);
 }
 
 static void test_suggest_compaction_segment_nothing(void)
@@ -880,9 +887,21 @@ static void test_empty_add(void)
        reftable_stack_destroy(st2);
 }
 
+static int fastlog2(uint64_t sz)
+{
+       int l = 0;
+       if (sz == 0)
+               return 0;
+       for (; sz; sz /= 2)
+               l++;
+       return l - 1;
+}
+
 static void test_reftable_stack_auto_compaction(void)
 {
-       struct reftable_write_options cfg = { 0 };
+       struct reftable_write_options cfg = {
+               .disable_auto_compact = 1,
+       };
        struct reftable_stack *st = NULL;
        char *dir = get_tmp_dir(__LINE__);
 
@@ -892,7 +911,6 @@ static void test_reftable_stack_auto_compaction(void)
        err = reftable_new_stack(&st, dir, cfg);
        EXPECT_ERR(err);
 
-       st->disable_auto_compact = 1; /* call manually below for coverage. */
        for (i = 0; i < N; i++) {
                char name[100];
                struct reftable_ref_record ref = {
@@ -941,7 +959,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)
                 * we can ensure that we indeed honor this setting and have
                 * better control over when exactly auto compaction runs.
                 */
-               st->disable_auto_compact = i != n;
+               st->config.disable_auto_compact = i != n;
 
                strbuf_reset(&refname);
                strbuf_addf(&refname, "branch-%04d", i);
@@ -1068,7 +1086,6 @@ static void test_reftable_stack_compaction_concurrent_clean(void)
 int stack_test_main(int argc, const char *argv[])
 {
        RUN_TEST(test_empty_add);
-       RUN_TEST(test_log2);
        RUN_TEST(test_names_equal);
        RUN_TEST(test_parse_names);
        RUN_TEST(test_read_file);
@@ -1085,12 +1102,10 @@ int stack_test_main(int argc, const char *argv[])
        RUN_TEST(test_reftable_stack_tombstone);
        RUN_TEST(test_reftable_stack_transaction_api);
        RUN_TEST(test_reftable_stack_transaction_api_performs_auto_compaction);
+       RUN_TEST(test_reftable_stack_auto_compaction_fails_gracefully);
        RUN_TEST(test_reftable_stack_update_index_check);
        RUN_TEST(test_reftable_stack_uptodate);
        RUN_TEST(test_reftable_stack_validate_refname);
-       RUN_TEST(test_sizes_to_segments);
-       RUN_TEST(test_sizes_to_segments_all_equal);
-       RUN_TEST(test_sizes_to_segments_empty);
        RUN_TEST(test_suggest_compaction_segment);
        RUN_TEST(test_suggest_compaction_segment_nothing);
        return 0;