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
;
22 typ
= reftable_record_type(rec
);
23 reftable_record_init(©
, 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 set_hash(in
.u
.ref
.value
.val1
, 1);
124 case REFTABLE_REF_VAL2
:
125 set_hash(in
.u
.ref
.value
.val2
.value
, 1);
126 set_hash(in
.u
.ref
.value
.val2
.target_value
, 2);
128 case REFTABLE_REF_SYMREF
:
129 in
.u
.ref
.value
.symref
= xstrdup("target");
132 in
.u
.ref
.refname
= xstrdup("refs/heads/master");
136 EXPECT(reftable_record_val_type(&in
) == i
);
138 reftable_record_key(&in
, &key
);
139 n
= reftable_record_encode(&in
, dest
, GIT_SHA1_RAWSZ
);
142 /* decode into a non-zero reftable_record to test for leaks. */
143 m
= reftable_record_decode(&out
, key
, i
, dest
, GIT_SHA1_RAWSZ
);
146 EXPECT(reftable_ref_record_equal(&in
.u
.ref
, &out
.u
.ref
,
148 reftable_record_release(&in
);
150 strbuf_release(&key
);
151 reftable_record_release(&out
);
155 static void test_reftable_log_record_equal(void)
157 struct reftable_log_record in
[2] = {
159 .refname
= xstrdup("refs/heads/master"),
163 .refname
= xstrdup("refs/heads/master"),
168 EXPECT(!reftable_log_record_equal(&in
[0], &in
[1], GIT_SHA1_RAWSZ
));
169 in
[1].update_index
= in
[0].update_index
;
170 EXPECT(reftable_log_record_equal(&in
[0], &in
[1], GIT_SHA1_RAWSZ
));
171 reftable_log_record_release(&in
[0]);
172 reftable_log_record_release(&in
[1]);
175 static void test_reftable_log_record_roundtrip(void)
179 struct reftable_log_record in
[] = {
181 .refname
= xstrdup("refs/heads/master"),
183 .value_type
= REFTABLE_LOG_UPDATE
,
186 .old_hash
= reftable_malloc(GIT_SHA1_RAWSZ
),
187 .new_hash
= reftable_malloc(GIT_SHA1_RAWSZ
),
188 .name
= xstrdup("han-wen"),
189 .email
= xstrdup("hanwen@google.com"),
190 .message
= xstrdup("test"),
197 .refname
= xstrdup("refs/heads/master"),
199 .value_type
= REFTABLE_LOG_DELETION
,
202 .refname
= xstrdup("branch"),
204 .value_type
= REFTABLE_LOG_UPDATE
,
207 .old_hash
= reftable_malloc(GIT_SHA1_RAWSZ
),
208 .new_hash
= reftable_malloc(GIT_SHA1_RAWSZ
),
209 /* rest of fields left empty. */
214 set_test_hash(in
[0].value
.update
.new_hash
, 1);
215 set_test_hash(in
[0].value
.update
.old_hash
, 2);
216 set_test_hash(in
[2].value
.update
.new_hash
, 3);
217 set_test_hash(in
[2].value
.update
.old_hash
, 4);
218 for (i
= 0; i
< ARRAY_SIZE(in
); i
++) {
219 struct reftable_record rec
= { .type
= BLOCK_TYPE_LOG
};
220 struct strbuf key
= STRBUF_INIT
;
221 uint8_t buffer
[1024] = { 0 };
222 struct string_view dest
= {
224 .len
= sizeof(buffer
),
226 /* populate out, to check for leaks. */
227 struct reftable_record out
= {
228 .type
= BLOCK_TYPE_LOG
,
230 .refname
= xstrdup("old name"),
231 .value_type
= REFTABLE_LOG_UPDATE
,
234 .new_hash
= reftable_calloc(GIT_SHA1_RAWSZ
, 1),
235 .old_hash
= reftable_calloc(GIT_SHA1_RAWSZ
, 1),
236 .name
= xstrdup("old name"),
237 .email
= xstrdup("old@email"),
238 .message
= xstrdup("old message"),
249 reftable_record_key(&rec
, &key
);
251 n
= reftable_record_encode(&rec
, dest
, GIT_SHA1_RAWSZ
);
253 valtype
= reftable_record_val_type(&rec
);
254 m
= reftable_record_decode(&out
, key
, valtype
, dest
,
258 EXPECT(reftable_log_record_equal(&in
[i
], &out
.u
.log
,
260 reftable_log_record_release(&in
[i
]);
261 strbuf_release(&key
);
262 reftable_record_release(&out
);
266 static void test_u24_roundtrip(void)
268 uint32_t in
= 0x112233;
272 out
= get_be24(dest
);
276 static void test_key_roundtrip(void)
278 uint8_t buffer
[1024] = { 0 };
279 struct string_view dest
= {
281 .len
= sizeof(buffer
),
283 struct strbuf last_key
= STRBUF_INIT
;
284 struct strbuf key
= STRBUF_INIT
;
285 struct strbuf roundtrip
= STRBUF_INIT
;
291 strbuf_addstr(&last_key
, "refs/heads/master");
292 strbuf_addstr(&key
, "refs/tags/bla");
294 n
= reftable_encode_key(&restart
, dest
, last_key
, key
, extra
);
298 m
= reftable_decode_key(&roundtrip
, &rt_extra
, last_key
, dest
);
300 EXPECT(0 == strbuf_cmp(&key
, &roundtrip
));
301 EXPECT(rt_extra
== extra
);
303 strbuf_release(&last_key
);
304 strbuf_release(&key
);
305 strbuf_release(&roundtrip
);
308 static void test_reftable_obj_record_roundtrip(void)
310 uint8_t testHash1
[GIT_SHA1_RAWSZ
] = { 1, 2, 3, 4, 0 };
311 uint64_t till9
[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 };
312 struct reftable_obj_record recs
[3] = { {
313 .hash_prefix
= testHash1
,
314 .hash_prefix_len
= 5,
319 .hash_prefix
= testHash1
,
320 .hash_prefix_len
= 5,
325 .hash_prefix
= testHash1
,
326 .hash_prefix_len
= 5,
329 for (i
= 0; i
< ARRAY_SIZE(recs
); i
++) {
330 uint8_t buffer
[1024] = { 0 };
331 struct string_view dest
= {
333 .len
= sizeof(buffer
),
335 struct reftable_record in
= {
336 .type
= BLOCK_TYPE_OBJ
,
341 struct strbuf key
= STRBUF_INIT
;
342 struct reftable_record out
= { .type
= BLOCK_TYPE_OBJ
};
347 reftable_record_key(&in
, &key
);
348 n
= reftable_record_encode(&in
, dest
, GIT_SHA1_RAWSZ
);
350 extra
= reftable_record_val_type(&in
);
351 m
= reftable_record_decode(&out
, key
, extra
, dest
,
355 EXPECT(reftable_record_equal(&in
, &out
, GIT_SHA1_RAWSZ
));
356 strbuf_release(&key
);
357 reftable_record_release(&out
);
361 static void test_reftable_index_record_roundtrip(void)
363 struct reftable_record in
= {
364 .type
= BLOCK_TYPE_INDEX
,
367 .last_key
= STRBUF_INIT
,
370 uint8_t buffer
[1024] = { 0 };
371 struct string_view dest
= {
373 .len
= sizeof(buffer
),
375 struct strbuf key
= STRBUF_INIT
;
376 struct reftable_record out
= {
377 .type
= BLOCK_TYPE_INDEX
,
378 .u
.idx
= { .last_key
= STRBUF_INIT
},
383 strbuf_addstr(&in
.u
.idx
.last_key
, "refs/heads/master");
384 reftable_record_key(&in
, &key
);
387 EXPECT(0 == strbuf_cmp(&key
, &in
.u
.idx
.last_key
));
388 n
= reftable_record_encode(&in
, dest
, GIT_SHA1_RAWSZ
);
391 extra
= reftable_record_val_type(&in
);
392 m
= reftable_record_decode(&out
, key
, extra
, dest
, GIT_SHA1_RAWSZ
);
395 EXPECT(reftable_record_equal(&in
, &out
, GIT_SHA1_RAWSZ
));
397 reftable_record_release(&out
);
398 strbuf_release(&key
);
399 strbuf_release(&in
.u
.idx
.last_key
);
402 int record_test_main(int argc
, const char *argv
[])
404 RUN_TEST(test_reftable_log_record_equal
);
405 RUN_TEST(test_reftable_log_record_roundtrip
);
406 RUN_TEST(test_reftable_ref_record_roundtrip
);
407 RUN_TEST(test_varint_roundtrip
);
408 RUN_TEST(test_key_roundtrip
);
409 RUN_TEST(test_common_prefix
);
410 RUN_TEST(test_reftable_obj_record_roundtrip
);
411 RUN_TEST(test_reftable_index_record_roundtrip
);
412 RUN_TEST(test_u24_roundtrip
);