2 Copyright 2020 Google LLC
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file or at
6 https://developers.google.com/open-source/licenses/bsd
13 #include "reftable-reader.h"
16 #include "constants.h"
18 #include "test_framework.h"
19 #include "reftable-tests.h"
21 #include <sys/types.h>
24 static void clear_dir(const char *dirname
)
26 struct strbuf path
= STRBUF_INIT
;
27 strbuf_addstr(&path
, dirname
);
28 remove_dir_recursively(&path
, 0);
29 strbuf_release(&path
);
32 static int count_dir_entries(const char *dirname
)
34 DIR *dir
= opendir(dirname
);
40 while ((d
= readdir(dir
))) {
41 if (!strcmp(d
->d_name
, "..") || !strcmp(d
->d_name
, "."))
50 * Work linenumber into the tempdir, so we can see which tests forget to
53 static char *get_tmp_template(int linenumber
)
55 const char *tmp
= getenv("TMPDIR");
56 static char template[1024];
57 snprintf(template, sizeof(template) - 1, "%s/stack_test-%d.XXXXXX",
58 tmp
? tmp
: "/tmp", linenumber
);
62 static char *get_tmp_dir(int linenumber
)
64 char *dir
= get_tmp_template(linenumber
);
69 static void test_read_file(void)
71 char *fn
= get_tmp_template(__LINE__
);
73 char out
[1024] = "line1\n\nline2\nline3";
76 char *want
[] = { "line1", "line2", "line3" };
80 n
= write(fd
, out
, strlen(out
));
81 EXPECT(n
== strlen(out
));
85 err
= read_lines(fn
, &names
);
88 for (i
= 0; names
[i
]; i
++) {
89 EXPECT(0 == strcmp(want
[i
], names
[i
]));
95 static void test_parse_names(void)
97 char buf
[] = "line\n";
99 parse_names(buf
, strlen(buf
), &names
);
101 EXPECT(NULL
!= names
[0]);
102 EXPECT(0 == strcmp(names
[0], "line"));
103 EXPECT(NULL
== names
[1]);
107 static void test_names_equal(void)
109 char *a
[] = { "a", "b", "c", NULL
};
110 char *b
[] = { "a", "b", "d", NULL
};
111 char *c
[] = { "a", "b", NULL
};
113 EXPECT(names_equal(a
, a
));
114 EXPECT(!names_equal(a
, b
));
115 EXPECT(!names_equal(a
, c
));
118 static int write_test_ref(struct reftable_writer
*wr
, void *arg
)
120 struct reftable_ref_record
*ref
= arg
;
121 reftable_writer_set_limits(wr
, ref
->update_index
, ref
->update_index
);
122 return reftable_writer_add_ref(wr
, ref
);
125 struct write_log_arg
{
126 struct reftable_log_record
*log
;
127 uint64_t update_index
;
130 static int write_test_log(struct reftable_writer
*wr
, void *arg
)
132 struct write_log_arg
*wla
= arg
;
134 reftable_writer_set_limits(wr
, wla
->update_index
, wla
->update_index
);
135 return reftable_writer_add_log(wr
, wla
->log
);
138 static void test_reftable_stack_add_one(void)
140 char *dir
= get_tmp_dir(__LINE__
);
142 struct reftable_write_options cfg
= { 0 };
143 struct reftable_stack
*st
= NULL
;
145 struct reftable_ref_record ref
= {
148 .value_type
= REFTABLE_REF_SYMREF
,
149 .value
.symref
= "master",
151 struct reftable_ref_record dest
= { NULL
};
154 err
= reftable_new_stack(&st
, dir
, cfg
);
157 err
= reftable_stack_add(st
, &write_test_ref
, &ref
);
160 err
= reftable_stack_read_ref(st
, ref
.refname
, &dest
);
162 EXPECT(0 == strcmp("master", dest
.value
.symref
));
164 printf("testing print functionality:\n");
165 err
= reftable_stack_print_directory(dir
, GIT_SHA1_FORMAT_ID
);
168 err
= reftable_stack_print_directory(dir
, GIT_SHA256_FORMAT_ID
);
169 EXPECT(err
== REFTABLE_FORMAT_ERROR
);
171 reftable_ref_record_release(&dest
);
172 reftable_stack_destroy(st
);
176 static void test_reftable_stack_uptodate(void)
178 struct reftable_write_options cfg
= { 0 };
179 struct reftable_stack
*st1
= NULL
;
180 struct reftable_stack
*st2
= NULL
;
181 char *dir
= get_tmp_dir(__LINE__
);
184 struct reftable_ref_record ref1
= {
187 .value_type
= REFTABLE_REF_SYMREF
,
188 .value
.symref
= "master",
190 struct reftable_ref_record ref2
= {
191 .refname
= "branch2",
193 .value_type
= REFTABLE_REF_SYMREF
,
194 .value
.symref
= "master",
198 /* simulate multi-process access to the same stack
199 by creating two stacks for the same directory.
201 err
= reftable_new_stack(&st1
, dir
, cfg
);
204 err
= reftable_new_stack(&st2
, dir
, cfg
);
207 err
= reftable_stack_add(st1
, &write_test_ref
, &ref1
);
210 err
= reftable_stack_add(st2
, &write_test_ref
, &ref2
);
211 EXPECT(err
== REFTABLE_LOCK_ERROR
);
213 err
= reftable_stack_reload(st2
);
216 err
= reftable_stack_add(st2
, &write_test_ref
, &ref2
);
218 reftable_stack_destroy(st1
);
219 reftable_stack_destroy(st2
);
223 static void test_reftable_stack_transaction_api(void)
225 char *dir
= get_tmp_dir(__LINE__
);
227 struct reftable_write_options cfg
= { 0 };
228 struct reftable_stack
*st
= NULL
;
230 struct reftable_addition
*add
= NULL
;
232 struct reftable_ref_record ref
= {
235 .value_type
= REFTABLE_REF_SYMREF
,
236 .value
.symref
= "master",
238 struct reftable_ref_record dest
= { NULL
};
241 err
= reftable_new_stack(&st
, dir
, cfg
);
244 reftable_addition_destroy(add
);
246 err
= reftable_stack_new_addition(&add
, st
);
249 err
= reftable_addition_add(add
, &write_test_ref
, &ref
);
252 err
= reftable_addition_commit(add
);
255 reftable_addition_destroy(add
);
257 err
= reftable_stack_read_ref(st
, ref
.refname
, &dest
);
259 EXPECT(REFTABLE_REF_SYMREF
== dest
.value_type
);
260 EXPECT(0 == strcmp("master", dest
.value
.symref
));
262 reftable_ref_record_release(&dest
);
263 reftable_stack_destroy(st
);
267 static void test_reftable_stack_validate_refname(void)
269 struct reftable_write_options cfg
= { 0 };
270 struct reftable_stack
*st
= NULL
;
272 char *dir
= get_tmp_dir(__LINE__
);
275 struct reftable_ref_record ref
= {
278 .value_type
= REFTABLE_REF_SYMREF
,
279 .value
.symref
= "master",
281 char *additions
[] = { "a", "a/b/c" };
283 err
= reftable_new_stack(&st
, dir
, cfg
);
286 err
= reftable_stack_add(st
, &write_test_ref
, &ref
);
289 for (i
= 0; i
< ARRAY_SIZE(additions
); i
++) {
290 struct reftable_ref_record ref
= {
291 .refname
= additions
[i
],
293 .value_type
= REFTABLE_REF_SYMREF
,
294 .value
.symref
= "master",
297 err
= reftable_stack_add(st
, &write_test_ref
, &ref
);
298 EXPECT(err
== REFTABLE_NAME_CONFLICT
);
301 reftable_stack_destroy(st
);
305 static int write_error(struct reftable_writer
*wr
, void *arg
)
307 return *((int *)arg
);
310 static void test_reftable_stack_update_index_check(void)
312 char *dir
= get_tmp_dir(__LINE__
);
314 struct reftable_write_options cfg
= { 0 };
315 struct reftable_stack
*st
= NULL
;
317 struct reftable_ref_record ref1
= {
320 .value_type
= REFTABLE_REF_SYMREF
,
321 .value
.symref
= "master",
323 struct reftable_ref_record ref2
= {
326 .value_type
= REFTABLE_REF_SYMREF
,
327 .value
.symref
= "master",
330 err
= reftable_new_stack(&st
, dir
, cfg
);
333 err
= reftable_stack_add(st
, &write_test_ref
, &ref1
);
336 err
= reftable_stack_add(st
, &write_test_ref
, &ref2
);
337 EXPECT(err
== REFTABLE_API_ERROR
);
338 reftable_stack_destroy(st
);
342 static void test_reftable_stack_lock_failure(void)
344 char *dir
= get_tmp_dir(__LINE__
);
346 struct reftable_write_options cfg
= { 0 };
347 struct reftable_stack
*st
= NULL
;
350 err
= reftable_new_stack(&st
, dir
, cfg
);
352 for (i
= -1; i
!= REFTABLE_EMPTY_TABLE_ERROR
; i
--) {
353 err
= reftable_stack_add(st
, &write_error
, &i
);
357 reftable_stack_destroy(st
);
361 static void test_reftable_stack_add(void)
365 struct reftable_write_options cfg
= {
366 .exact_log_message
= 1,
368 struct reftable_stack
*st
= NULL
;
369 char *dir
= get_tmp_dir(__LINE__
);
371 struct reftable_ref_record refs
[2] = { { NULL
} };
372 struct reftable_log_record logs
[2] = { { NULL
} };
373 int N
= ARRAY_SIZE(refs
);
376 err
= reftable_new_stack(&st
, dir
, cfg
);
378 st
->disable_auto_compact
= 1;
380 for (i
= 0; i
< N
; i
++) {
382 snprintf(buf
, sizeof(buf
), "branch%02d", i
);
383 refs
[i
].refname
= xstrdup(buf
);
384 refs
[i
].update_index
= i
+ 1;
385 refs
[i
].value_type
= REFTABLE_REF_VAL1
;
386 refs
[i
].value
.val1
= reftable_malloc(GIT_SHA1_RAWSZ
);
387 set_test_hash(refs
[i
].value
.val1
, i
);
389 logs
[i
].refname
= xstrdup(buf
);
390 logs
[i
].update_index
= N
+ i
+ 1;
391 logs
[i
].value_type
= REFTABLE_LOG_UPDATE
;
393 logs
[i
].value
.update
.new_hash
= reftable_malloc(GIT_SHA1_RAWSZ
);
394 logs
[i
].value
.update
.email
= xstrdup("identity@invalid");
395 set_test_hash(logs
[i
].value
.update
.new_hash
, i
);
398 for (i
= 0; i
< N
; i
++) {
399 int err
= reftable_stack_add(st
, &write_test_ref
, &refs
[i
]);
403 for (i
= 0; i
< N
; i
++) {
404 struct write_log_arg arg
= {
406 .update_index
= reftable_stack_next_update_index(st
),
408 int err
= reftable_stack_add(st
, &write_test_log
, &arg
);
412 err
= reftable_stack_compact_all(st
, NULL
);
415 for (i
= 0; i
< N
; i
++) {
416 struct reftable_ref_record dest
= { NULL
};
418 int err
= reftable_stack_read_ref(st
, refs
[i
].refname
, &dest
);
420 EXPECT(reftable_ref_record_equal(&dest
, refs
+ i
,
422 reftable_ref_record_release(&dest
);
425 for (i
= 0; i
< N
; i
++) {
426 struct reftable_log_record dest
= { NULL
};
427 int err
= reftable_stack_read_log(st
, refs
[i
].refname
, &dest
);
429 EXPECT(reftable_log_record_equal(&dest
, logs
+ i
,
431 reftable_log_record_release(&dest
);
435 reftable_stack_destroy(st
);
436 for (i
= 0; i
< N
; i
++) {
437 reftable_ref_record_release(&refs
[i
]);
438 reftable_log_record_release(&logs
[i
]);
443 static void test_reftable_stack_log_normalize(void)
446 struct reftable_write_options cfg
= {
449 struct reftable_stack
*st
= NULL
;
450 char *dir
= get_tmp_dir(__LINE__
);
452 uint8_t h1
[GIT_SHA1_RAWSZ
] = { 0x01 }, h2
[GIT_SHA1_RAWSZ
] = { 0x02 };
454 struct reftable_log_record input
= { .refname
= "branch",
456 .value_type
= REFTABLE_LOG_UPDATE
,
457 .value
= { .update
= {
461 struct reftable_log_record dest
= {
464 struct write_log_arg arg
= {
469 err
= reftable_new_stack(&st
, dir
, cfg
);
472 input
.value
.update
.message
= "one\ntwo";
473 err
= reftable_stack_add(st
, &write_test_log
, &arg
);
474 EXPECT(err
== REFTABLE_API_ERROR
);
476 input
.value
.update
.message
= "one";
477 err
= reftable_stack_add(st
, &write_test_log
, &arg
);
480 err
= reftable_stack_read_log(st
, input
.refname
, &dest
);
482 EXPECT(0 == strcmp(dest
.value
.update
.message
, "one\n"));
484 input
.value
.update
.message
= "two\n";
485 arg
.update_index
= 2;
486 err
= reftable_stack_add(st
, &write_test_log
, &arg
);
488 err
= reftable_stack_read_log(st
, input
.refname
, &dest
);
490 EXPECT(0 == strcmp(dest
.value
.update
.message
, "two\n"));
493 reftable_stack_destroy(st
);
494 reftable_log_record_release(&dest
);
498 static void test_reftable_stack_tombstone(void)
501 char *dir
= get_tmp_dir(__LINE__
);
503 struct reftable_write_options cfg
= { 0 };
504 struct reftable_stack
*st
= NULL
;
506 struct reftable_ref_record refs
[2] = { { NULL
} };
507 struct reftable_log_record logs
[2] = { { NULL
} };
508 int N
= ARRAY_SIZE(refs
);
509 struct reftable_ref_record dest
= { NULL
};
510 struct reftable_log_record log_dest
= { NULL
};
513 err
= reftable_new_stack(&st
, dir
, cfg
);
516 /* even entries add the refs, odd entries delete them. */
517 for (i
= 0; i
< N
; i
++) {
518 const char *buf
= "branch";
519 refs
[i
].refname
= xstrdup(buf
);
520 refs
[i
].update_index
= i
+ 1;
522 refs
[i
].value_type
= REFTABLE_REF_VAL1
;
523 refs
[i
].value
.val1
= reftable_malloc(GIT_SHA1_RAWSZ
);
524 set_test_hash(refs
[i
].value
.val1
, i
);
527 logs
[i
].refname
= xstrdup(buf
);
528 /* update_index is part of the key. */
529 logs
[i
].update_index
= 42;
531 logs
[i
].value_type
= REFTABLE_LOG_UPDATE
;
532 logs
[i
].value
.update
.new_hash
=
533 reftable_malloc(GIT_SHA1_RAWSZ
);
534 set_test_hash(logs
[i
].value
.update
.new_hash
, i
);
535 logs
[i
].value
.update
.email
=
536 xstrdup("identity@invalid");
539 for (i
= 0; i
< N
; i
++) {
540 int err
= reftable_stack_add(st
, &write_test_ref
, &refs
[i
]);
544 for (i
= 0; i
< N
; i
++) {
545 struct write_log_arg arg
= {
547 .update_index
= reftable_stack_next_update_index(st
),
549 int err
= reftable_stack_add(st
, &write_test_log
, &arg
);
553 err
= reftable_stack_read_ref(st
, "branch", &dest
);
555 reftable_ref_record_release(&dest
);
557 err
= reftable_stack_read_log(st
, "branch", &log_dest
);
559 reftable_log_record_release(&log_dest
);
561 err
= reftable_stack_compact_all(st
, NULL
);
564 err
= reftable_stack_read_ref(st
, "branch", &dest
);
567 err
= reftable_stack_read_log(st
, "branch", &log_dest
);
569 reftable_ref_record_release(&dest
);
570 reftable_log_record_release(&log_dest
);
573 reftable_stack_destroy(st
);
574 for (i
= 0; i
< N
; i
++) {
575 reftable_ref_record_release(&refs
[i
]);
576 reftable_log_record_release(&logs
[i
]);
581 static void test_reftable_stack_hash_id(void)
583 char *dir
= get_tmp_dir(__LINE__
);
585 struct reftable_write_options cfg
= { 0 };
586 struct reftable_stack
*st
= NULL
;
589 struct reftable_ref_record ref
= {
591 .value_type
= REFTABLE_REF_SYMREF
,
592 .value
.symref
= "target",
595 struct reftable_write_options cfg32
= { .hash_id
= GIT_SHA256_FORMAT_ID
};
596 struct reftable_stack
*st32
= NULL
;
597 struct reftable_write_options cfg_default
= { 0 };
598 struct reftable_stack
*st_default
= NULL
;
599 struct reftable_ref_record dest
= { NULL
};
601 err
= reftable_new_stack(&st
, dir
, cfg
);
604 err
= reftable_stack_add(st
, &write_test_ref
, &ref
);
607 /* can't read it with the wrong hash ID. */
608 err
= reftable_new_stack(&st32
, dir
, cfg32
);
609 EXPECT(err
== REFTABLE_FORMAT_ERROR
);
611 /* check that we can read it back with default config too. */
612 err
= reftable_new_stack(&st_default
, dir
, cfg_default
);
615 err
= reftable_stack_read_ref(st_default
, "master", &dest
);
618 EXPECT(reftable_ref_record_equal(&ref
, &dest
, GIT_SHA1_RAWSZ
));
619 reftable_ref_record_release(&dest
);
620 reftable_stack_destroy(st
);
621 reftable_stack_destroy(st_default
);
625 static void test_log2(void)
627 EXPECT(1 == fastlog2(3));
628 EXPECT(2 == fastlog2(4));
629 EXPECT(2 == fastlog2(5));
632 static void test_sizes_to_segments(void)
634 uint64_t sizes
[] = { 2, 3, 4, 5, 7, 9 };
635 /* .................0 1 2 3 4 5 */
638 struct segment
*segs
=
639 sizes_to_segments(&seglen
, sizes
, ARRAY_SIZE(sizes
));
640 EXPECT(segs
[2].log
== 3);
641 EXPECT(segs
[2].start
== 5);
642 EXPECT(segs
[2].end
== 6);
644 EXPECT(segs
[1].log
== 2);
645 EXPECT(segs
[1].start
== 2);
646 EXPECT(segs
[1].end
== 5);
650 static void test_sizes_to_segments_empty(void)
653 struct segment
*segs
= sizes_to_segments(&seglen
, NULL
, 0);
658 static void test_sizes_to_segments_all_equal(void)
660 uint64_t sizes
[] = { 5, 5 };
663 struct segment
*segs
=
664 sizes_to_segments(&seglen
, sizes
, ARRAY_SIZE(sizes
));
666 EXPECT(segs
[0].start
== 0);
667 EXPECT(segs
[0].end
== 2);
671 static void test_suggest_compaction_segment(void)
673 uint64_t sizes
[] = { 128, 64, 17, 16, 9, 9, 9, 16, 16 };
674 /* .................0 1 2 3 4 5 6 */
676 suggest_compaction_segment(sizes
, ARRAY_SIZE(sizes
));
677 EXPECT(min
.start
== 2);
678 EXPECT(min
.end
== 7);
681 static void test_suggest_compaction_segment_nothing(void)
683 uint64_t sizes
[] = { 64, 32, 16, 8, 4, 2 };
684 struct segment result
=
685 suggest_compaction_segment(sizes
, ARRAY_SIZE(sizes
));
686 EXPECT(result
.start
== result
.end
);
689 static void test_reflog_expire(void)
691 char *dir
= get_tmp_dir(__LINE__
);
693 struct reftable_write_options cfg
= { 0 };
694 struct reftable_stack
*st
= NULL
;
695 struct reftable_log_record logs
[20] = { { NULL
} };
696 int N
= ARRAY_SIZE(logs
) - 1;
699 struct reftable_log_expiry_config expiry
= {
702 struct reftable_log_record log
= { NULL
};
705 err
= reftable_new_stack(&st
, dir
, cfg
);
708 for (i
= 1; i
<= N
; i
++) {
710 snprintf(buf
, sizeof(buf
), "branch%02d", i
);
712 logs
[i
].refname
= xstrdup(buf
);
713 logs
[i
].update_index
= i
;
714 logs
[i
].value_type
= REFTABLE_LOG_UPDATE
;
715 logs
[i
].value
.update
.time
= i
;
716 logs
[i
].value
.update
.new_hash
= reftable_malloc(GIT_SHA1_RAWSZ
);
717 logs
[i
].value
.update
.email
= xstrdup("identity@invalid");
718 set_test_hash(logs
[i
].value
.update
.new_hash
, i
);
721 for (i
= 1; i
<= N
; i
++) {
722 struct write_log_arg arg
= {
724 .update_index
= reftable_stack_next_update_index(st
),
726 int err
= reftable_stack_add(st
, &write_test_log
, &arg
);
730 err
= reftable_stack_compact_all(st
, NULL
);
733 err
= reftable_stack_compact_all(st
, &expiry
);
736 err
= reftable_stack_read_log(st
, logs
[9].refname
, &log
);
739 err
= reftable_stack_read_log(st
, logs
[11].refname
, &log
);
742 expiry
.min_update_index
= 15;
743 err
= reftable_stack_compact_all(st
, &expiry
);
746 err
= reftable_stack_read_log(st
, logs
[14].refname
, &log
);
749 err
= reftable_stack_read_log(st
, logs
[16].refname
, &log
);
753 reftable_stack_destroy(st
);
754 for (i
= 0; i
<= N
; i
++) {
755 reftable_log_record_release(&logs
[i
]);
758 reftable_log_record_release(&log
);
761 static int write_nothing(struct reftable_writer
*wr
, void *arg
)
763 reftable_writer_set_limits(wr
, 1, 1);
767 static void test_empty_add(void)
769 struct reftable_write_options cfg
= { 0 };
770 struct reftable_stack
*st
= NULL
;
772 char *dir
= get_tmp_dir(__LINE__
);
774 struct reftable_stack
*st2
= NULL
;
777 err
= reftable_new_stack(&st
, dir
, cfg
);
780 err
= reftable_stack_add(st
, &write_nothing
, NULL
);
783 err
= reftable_new_stack(&st2
, dir
, cfg
);
786 reftable_stack_destroy(st
);
787 reftable_stack_destroy(st2
);
790 static void test_reftable_stack_auto_compaction(void)
792 struct reftable_write_options cfg
= { 0 };
793 struct reftable_stack
*st
= NULL
;
794 char *dir
= get_tmp_dir(__LINE__
);
799 err
= reftable_new_stack(&st
, dir
, cfg
);
802 st
->disable_auto_compact
= 1; /* call manually below for coverage. */
803 for (i
= 0; i
< N
; i
++) {
805 struct reftable_ref_record ref
= {
807 .update_index
= reftable_stack_next_update_index(st
),
808 .value_type
= REFTABLE_REF_SYMREF
,
809 .value
.symref
= "master",
811 snprintf(name
, sizeof(name
), "branch%04d", i
);
813 err
= reftable_stack_add(st
, &write_test_ref
, &ref
);
816 err
= reftable_stack_auto_compact(st
);
817 EXPECT(i
< 3 || st
->merged
->stack_len
< 2 * fastlog2(i
));
820 EXPECT(reftable_stack_compaction_stats(st
)->entries_written
<
821 (uint64_t)(N
* fastlog2(N
)));
823 reftable_stack_destroy(st
);
827 static void test_reftable_stack_compaction_concurrent(void)
829 struct reftable_write_options cfg
= { 0 };
830 struct reftable_stack
*st1
= NULL
, *st2
= NULL
;
831 char *dir
= get_tmp_dir(__LINE__
);
836 err
= reftable_new_stack(&st1
, dir
, cfg
);
839 for (i
= 0; i
< N
; i
++) {
841 struct reftable_ref_record ref
= {
843 .update_index
= reftable_stack_next_update_index(st1
),
844 .value_type
= REFTABLE_REF_SYMREF
,
845 .value
.symref
= "master",
847 snprintf(name
, sizeof(name
), "branch%04d", i
);
849 err
= reftable_stack_add(st1
, &write_test_ref
, &ref
);
853 err
= reftable_new_stack(&st2
, dir
, cfg
);
856 err
= reftable_stack_compact_all(st1
, NULL
);
859 reftable_stack_destroy(st1
);
860 reftable_stack_destroy(st2
);
862 EXPECT(count_dir_entries(dir
) == 2);
866 static void unclean_stack_close(struct reftable_stack
*st
)
868 /* break abstraction boundary to simulate unclean shutdown. */
870 for (; i
< st
->readers_len
; i
++) {
871 reftable_reader_free(st
->readers
[i
]);
874 FREE_AND_NULL(st
->readers
);
877 static void test_reftable_stack_compaction_concurrent_clean(void)
879 struct reftable_write_options cfg
= { 0 };
880 struct reftable_stack
*st1
= NULL
, *st2
= NULL
, *st3
= NULL
;
881 char *dir
= get_tmp_dir(__LINE__
);
886 err
= reftable_new_stack(&st1
, dir
, cfg
);
889 for (i
= 0; i
< N
; i
++) {
891 struct reftable_ref_record ref
= {
893 .update_index
= reftable_stack_next_update_index(st1
),
894 .value_type
= REFTABLE_REF_SYMREF
,
895 .value
.symref
= "master",
897 snprintf(name
, sizeof(name
), "branch%04d", i
);
899 err
= reftable_stack_add(st1
, &write_test_ref
, &ref
);
903 err
= reftable_new_stack(&st2
, dir
, cfg
);
906 err
= reftable_stack_compact_all(st1
, NULL
);
909 unclean_stack_close(st1
);
910 unclean_stack_close(st2
);
912 err
= reftable_new_stack(&st3
, dir
, cfg
);
915 err
= reftable_stack_clean(st3
);
917 EXPECT(count_dir_entries(dir
) == 2);
919 reftable_stack_destroy(st1
);
920 reftable_stack_destroy(st2
);
921 reftable_stack_destroy(st3
);
926 int stack_test_main(int argc
, const char *argv
[])
928 RUN_TEST(test_empty_add
);
930 RUN_TEST(test_names_equal
);
931 RUN_TEST(test_parse_names
);
932 RUN_TEST(test_read_file
);
933 RUN_TEST(test_reflog_expire
);
934 RUN_TEST(test_reftable_stack_add
);
935 RUN_TEST(test_reftable_stack_add_one
);
936 RUN_TEST(test_reftable_stack_auto_compaction
);
937 RUN_TEST(test_reftable_stack_compaction_concurrent
);
938 RUN_TEST(test_reftable_stack_compaction_concurrent_clean
);
939 RUN_TEST(test_reftable_stack_hash_id
);
940 RUN_TEST(test_reftable_stack_lock_failure
);
941 RUN_TEST(test_reftable_stack_log_normalize
);
942 RUN_TEST(test_reftable_stack_tombstone
);
943 RUN_TEST(test_reftable_stack_transaction_api
);
944 RUN_TEST(test_reftable_stack_update_index_check
);
945 RUN_TEST(test_reftable_stack_uptodate
);
946 RUN_TEST(test_reftable_stack_validate_refname
);
947 RUN_TEST(test_sizes_to_segments
);
948 RUN_TEST(test_sizes_to_segments_all_equal
);
949 RUN_TEST(test_sizes_to_segments_empty
);
950 RUN_TEST(test_suggest_compaction_segment
);
951 RUN_TEST(test_suggest_compaction_segment_nothing
);