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 "constants.h"
14 #include "test_framework.h"
15 #include "reftable-tests.h"
17 static void test_copy(struct reftable_record
*rec
)
19 struct reftable_record copy
= { 0 };
22 typ
= reftable_record_type(rec
);
23 copy
= reftable_new_record(typ
);
24 reftable_record_copy_from(©
, rec
, GIT_SHA1_RAWSZ
);
25 /* do it twice to catch memory leaks */
26 reftable_record_copy_from(©
, rec
, GIT_SHA1_RAWSZ
);
27 EXPECT(reftable_record_equal(rec
, ©
, GIT_SHA1_RAWSZ
));
29 puts("testing print coverage:\n");
30 reftable_record_print(©
, GIT_SHA1_RAWSZ
);
32 reftable_record_release(©
);
35 static void test_varint_roundtrip(void)
37 uint64_t inputs
[] = { 0,
45 ((uint64_t)1 << 63) + ((uint64_t)1 << 63) - 1 };
47 for (i
= 0; i
< ARRAY_SIZE(inputs
); i
++) {
50 struct string_view out
= {
54 uint64_t in
= inputs
[i
];
55 int n
= put_var_int(&out
, in
);
60 n
= get_var_int(&got
, &out
);
67 static void test_common_prefix(void)
80 for (i
= 0; i
< ARRAY_SIZE(cases
); i
++) {
81 struct strbuf a
= STRBUF_INIT
;
82 struct strbuf b
= STRBUF_INIT
;
83 strbuf_addstr(&a
, cases
[i
].a
);
84 strbuf_addstr(&b
, cases
[i
].b
);
85 EXPECT(common_prefix_size(&a
, &b
) == cases
[i
].want
);
92 static void set_hash(uint8_t *h
, int j
)
95 for (i
= 0; i
< hash_size(GIT_SHA1_FORMAT_ID
); i
++) {
96 h
[i
] = (j
>> i
) & 0xff;
100 static void test_reftable_ref_record_roundtrip(void)
104 for (i
= REFTABLE_REF_DELETION
; i
< REFTABLE_NR_REF_VALUETYPES
; i
++) {
105 struct reftable_record in
= {
106 .type
= BLOCK_TYPE_REF
,
108 struct reftable_record out
= { .type
= BLOCK_TYPE_REF
};
109 struct strbuf key
= STRBUF_INIT
;
110 uint8_t buffer
[1024] = { 0 };
111 struct string_view dest
= {
113 .len
= sizeof(buffer
),
117 in
.u
.ref
.value_type
= i
;
119 case REFTABLE_REF_DELETION
:
121 case REFTABLE_REF_VAL1
:
122 in
.u
.ref
.value
.val1
= reftable_malloc(GIT_SHA1_RAWSZ
);
123 set_hash(in
.u
.ref
.value
.val1
, 1);
125 case REFTABLE_REF_VAL2
:
126 in
.u
.ref
.value
.val2
.value
=
127 reftable_malloc(GIT_SHA1_RAWSZ
);
128 set_hash(in
.u
.ref
.value
.val2
.value
, 1);
129 in
.u
.ref
.value
.val2
.target_value
=
130 reftable_malloc(GIT_SHA1_RAWSZ
);
131 set_hash(in
.u
.ref
.value
.val2
.target_value
, 2);
133 case REFTABLE_REF_SYMREF
:
134 in
.u
.ref
.value
.symref
= xstrdup("target");
137 in
.u
.ref
.refname
= xstrdup("refs/heads/master");
141 EXPECT(reftable_record_val_type(&in
) == i
);
143 reftable_record_key(&in
, &key
);
144 n
= reftable_record_encode(&in
, dest
, GIT_SHA1_RAWSZ
);
147 /* decode into a non-zero reftable_record to test for leaks. */
148 m
= reftable_record_decode(&out
, key
, i
, dest
, GIT_SHA1_RAWSZ
);
151 EXPECT(reftable_ref_record_equal(&in
.u
.ref
, &out
.u
.ref
,
153 reftable_record_release(&in
);
155 strbuf_release(&key
);
156 reftable_record_release(&out
);
160 static void test_reftable_log_record_equal(void)
162 struct reftable_log_record in
[2] = {
164 .refname
= xstrdup("refs/heads/master"),
168 .refname
= xstrdup("refs/heads/master"),
173 EXPECT(!reftable_log_record_equal(&in
[0], &in
[1], GIT_SHA1_RAWSZ
));
174 in
[1].update_index
= in
[0].update_index
;
175 EXPECT(reftable_log_record_equal(&in
[0], &in
[1], GIT_SHA1_RAWSZ
));
176 reftable_log_record_release(&in
[0]);
177 reftable_log_record_release(&in
[1]);
180 static void test_reftable_log_record_roundtrip(void)
184 struct reftable_log_record in
[] = {
186 .refname
= xstrdup("refs/heads/master"),
188 .value_type
= REFTABLE_LOG_UPDATE
,
191 .old_hash
= reftable_malloc(GIT_SHA1_RAWSZ
),
192 .new_hash
= reftable_malloc(GIT_SHA1_RAWSZ
),
193 .name
= xstrdup("han-wen"),
194 .email
= xstrdup("hanwen@google.com"),
195 .message
= xstrdup("test"),
202 .refname
= xstrdup("refs/heads/master"),
204 .value_type
= REFTABLE_LOG_DELETION
,
207 .refname
= xstrdup("branch"),
209 .value_type
= REFTABLE_LOG_UPDATE
,
212 .old_hash
= reftable_malloc(GIT_SHA1_RAWSZ
),
213 .new_hash
= reftable_malloc(GIT_SHA1_RAWSZ
),
214 /* rest of fields left empty. */
219 set_test_hash(in
[0].value
.update
.new_hash
, 1);
220 set_test_hash(in
[0].value
.update
.old_hash
, 2);
221 set_test_hash(in
[2].value
.update
.new_hash
, 3);
222 set_test_hash(in
[2].value
.update
.old_hash
, 4);
223 for (i
= 0; i
< ARRAY_SIZE(in
); i
++) {
224 struct reftable_record rec
= { .type
= BLOCK_TYPE_LOG
};
225 struct strbuf key
= STRBUF_INIT
;
226 uint8_t buffer
[1024] = { 0 };
227 struct string_view dest
= {
229 .len
= sizeof(buffer
),
231 /* populate out, to check for leaks. */
232 struct reftable_record out
= {
233 .type
= BLOCK_TYPE_LOG
,
235 .refname
= xstrdup("old name"),
236 .value_type
= REFTABLE_LOG_UPDATE
,
239 .new_hash
= reftable_calloc(GIT_SHA1_RAWSZ
),
240 .old_hash
= reftable_calloc(GIT_SHA1_RAWSZ
),
241 .name
= xstrdup("old name"),
242 .email
= xstrdup("old@email"),
243 .message
= xstrdup("old message"),
254 reftable_record_key(&rec
, &key
);
256 n
= reftable_record_encode(&rec
, dest
, GIT_SHA1_RAWSZ
);
258 valtype
= reftable_record_val_type(&rec
);
259 m
= reftable_record_decode(&out
, key
, valtype
, dest
,
263 EXPECT(reftable_log_record_equal(&in
[i
], &out
.u
.log
,
265 reftable_log_record_release(&in
[i
]);
266 strbuf_release(&key
);
267 reftable_record_release(&out
);
271 static void test_u24_roundtrip(void)
273 uint32_t in
= 0x112233;
277 out
= get_be24(dest
);
281 static void test_key_roundtrip(void)
283 uint8_t buffer
[1024] = { 0 };
284 struct string_view dest
= {
286 .len
= sizeof(buffer
),
288 struct strbuf last_key
= STRBUF_INIT
;
289 struct strbuf key
= STRBUF_INIT
;
290 struct strbuf roundtrip
= STRBUF_INIT
;
296 strbuf_addstr(&last_key
, "refs/heads/master");
297 strbuf_addstr(&key
, "refs/tags/bla");
299 n
= reftable_encode_key(&restart
, dest
, last_key
, key
, extra
);
303 m
= reftable_decode_key(&roundtrip
, &rt_extra
, last_key
, dest
);
305 EXPECT(0 == strbuf_cmp(&key
, &roundtrip
));
306 EXPECT(rt_extra
== extra
);
308 strbuf_release(&last_key
);
309 strbuf_release(&key
);
310 strbuf_release(&roundtrip
);
313 static void test_reftable_obj_record_roundtrip(void)
315 uint8_t testHash1
[GIT_SHA1_RAWSZ
] = { 1, 2, 3, 4, 0 };
316 uint64_t till9
[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 };
317 struct reftable_obj_record recs
[3] = { {
318 .hash_prefix
= testHash1
,
319 .hash_prefix_len
= 5,
324 .hash_prefix
= testHash1
,
325 .hash_prefix_len
= 5,
330 .hash_prefix
= testHash1
,
331 .hash_prefix_len
= 5,
334 for (i
= 0; i
< ARRAY_SIZE(recs
); i
++) {
335 uint8_t buffer
[1024] = { 0 };
336 struct string_view dest
= {
338 .len
= sizeof(buffer
),
340 struct reftable_record in
= {
341 .type
= BLOCK_TYPE_OBJ
,
346 struct strbuf key
= STRBUF_INIT
;
347 struct reftable_record out
= { .type
= BLOCK_TYPE_OBJ
};
352 reftable_record_key(&in
, &key
);
353 n
= reftable_record_encode(&in
, dest
, GIT_SHA1_RAWSZ
);
355 extra
= reftable_record_val_type(&in
);
356 m
= reftable_record_decode(&out
, key
, extra
, dest
,
360 EXPECT(reftable_record_equal(&in
, &out
, GIT_SHA1_RAWSZ
));
361 strbuf_release(&key
);
362 reftable_record_release(&out
);
366 static void test_reftable_index_record_roundtrip(void)
368 struct reftable_record in
= {
369 .type
= BLOCK_TYPE_INDEX
,
372 .last_key
= STRBUF_INIT
,
375 uint8_t buffer
[1024] = { 0 };
376 struct string_view dest
= {
378 .len
= sizeof(buffer
),
380 struct strbuf key
= STRBUF_INIT
;
381 struct reftable_record out
= {
382 .type
= BLOCK_TYPE_INDEX
,
383 .u
.idx
= { .last_key
= STRBUF_INIT
},
388 strbuf_addstr(&in
.u
.idx
.last_key
, "refs/heads/master");
389 reftable_record_key(&in
, &key
);
392 EXPECT(0 == strbuf_cmp(&key
, &in
.u
.idx
.last_key
));
393 n
= reftable_record_encode(&in
, dest
, GIT_SHA1_RAWSZ
);
396 extra
= reftable_record_val_type(&in
);
397 m
= reftable_record_decode(&out
, key
, extra
, dest
, GIT_SHA1_RAWSZ
);
400 EXPECT(reftable_record_equal(&in
, &out
, GIT_SHA1_RAWSZ
));
402 reftable_record_release(&out
);
403 strbuf_release(&key
);
404 strbuf_release(&in
.u
.idx
.last_key
);
407 int record_test_main(int argc
, const char *argv
[])
409 RUN_TEST(test_reftable_log_record_equal
);
410 RUN_TEST(test_reftable_log_record_roundtrip
);
411 RUN_TEST(test_reftable_ref_record_roundtrip
);
412 RUN_TEST(test_varint_roundtrip
);
413 RUN_TEST(test_key_roundtrip
);
414 RUN_TEST(test_common_prefix
);
415 RUN_TEST(test_reftable_obj_record_roundtrip
);
416 RUN_TEST(test_reftable_index_record_roundtrip
);
417 RUN_TEST(test_u24_roundtrip
);