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
=
20 reftable_new_record(reftable_record_type(rec
));
21 reftable_record_copy_from(©
, rec
, GIT_SHA1_RAWSZ
);
22 /* do it twice to catch memory leaks */
23 reftable_record_copy_from(©
, rec
, GIT_SHA1_RAWSZ
);
24 EXPECT(reftable_record_equal(rec
, ©
, GIT_SHA1_RAWSZ
));
25 reftable_record_destroy(©
);
28 static void test_varint_roundtrip(void)
30 uint64_t inputs
[] = { 0,
38 ((uint64_t)1 << 63) + ((uint64_t)1 << 63) - 1 };
40 for (i
= 0; i
< ARRAY_SIZE(inputs
); i
++) {
43 struct string_view out
= {
47 uint64_t in
= inputs
[i
];
48 int n
= put_var_int(&out
, in
);
53 n
= get_var_int(&got
, &out
);
60 static void test_common_prefix(void)
73 for (i
= 0; i
< ARRAY_SIZE(cases
); i
++) {
74 struct strbuf a
= STRBUF_INIT
;
75 struct strbuf b
= STRBUF_INIT
;
76 strbuf_addstr(&a
, cases
[i
].a
);
77 strbuf_addstr(&b
, cases
[i
].b
);
78 EXPECT(common_prefix_size(&a
, &b
) == cases
[i
].want
);
85 static void set_hash(uint8_t *h
, int j
)
88 for (i
= 0; i
< hash_size(GIT_SHA1_FORMAT_ID
); i
++) {
89 h
[i
] = (j
>> i
) & 0xff;
93 static void test_reftable_ref_record_roundtrip(void)
97 for (i
= REFTABLE_REF_DELETION
; i
< REFTABLE_NR_REF_VALUETYPES
; i
++) {
98 struct reftable_ref_record in
= { NULL
};
99 struct reftable_ref_record out
= { NULL
};
100 struct reftable_record rec_out
= { NULL
};
101 struct strbuf key
= STRBUF_INIT
;
102 struct reftable_record rec
= { NULL
};
103 uint8_t buffer
[1024] = { 0 };
104 struct string_view dest
= {
106 .len
= sizeof(buffer
),
113 case REFTABLE_REF_DELETION
:
115 case REFTABLE_REF_VAL1
:
116 in
.value
.val1
= reftable_malloc(GIT_SHA1_RAWSZ
);
117 set_hash(in
.value
.val1
, 1);
119 case REFTABLE_REF_VAL2
:
120 in
.value
.val2
.value
= reftable_malloc(GIT_SHA1_RAWSZ
);
121 set_hash(in
.value
.val2
.value
, 1);
122 in
.value
.val2
.target_value
=
123 reftable_malloc(GIT_SHA1_RAWSZ
);
124 set_hash(in
.value
.val2
.target_value
, 2);
126 case REFTABLE_REF_SYMREF
:
127 in
.value
.symref
= xstrdup("target");
130 in
.refname
= xstrdup("refs/heads/master");
132 reftable_record_from_ref(&rec
, &in
);
135 EXPECT(reftable_record_val_type(&rec
) == i
);
137 reftable_record_key(&rec
, &key
);
138 n
= reftable_record_encode(&rec
, dest
, GIT_SHA1_RAWSZ
);
141 /* decode into a non-zero reftable_record to test for leaks. */
143 reftable_record_from_ref(&rec_out
, &out
);
144 m
= reftable_record_decode(&rec_out
, key
, i
, dest
,
148 EXPECT(reftable_ref_record_equal(&in
, &out
, GIT_SHA1_RAWSZ
));
149 reftable_record_release(&rec_out
);
151 strbuf_release(&key
);
152 reftable_ref_record_release(&in
);
156 static void test_reftable_log_record_equal(void)
158 struct reftable_log_record in
[2] = {
160 .refname
= xstrdup("refs/heads/master"),
164 .refname
= xstrdup("refs/heads/master"),
169 EXPECT(!reftable_log_record_equal(&in
[0], &in
[1], GIT_SHA1_RAWSZ
));
170 in
[1].update_index
= in
[0].update_index
;
171 EXPECT(reftable_log_record_equal(&in
[0], &in
[1], GIT_SHA1_RAWSZ
));
172 reftable_log_record_release(&in
[0]);
173 reftable_log_record_release(&in
[1]);
176 static void test_reftable_log_record_roundtrip(void)
179 struct reftable_log_record in
[2] = {
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 set_test_hash(in
[0].value
.update
.new_hash
, 1);
203 set_test_hash(in
[0].value
.update
.old_hash
, 2);
204 for (i
= 0; i
< ARRAY_SIZE(in
); i
++) {
205 struct reftable_record rec
= { NULL
};
206 struct strbuf key
= STRBUF_INIT
;
207 uint8_t buffer
[1024] = { 0 };
208 struct string_view dest
= {
210 .len
= sizeof(buffer
),
212 /* populate out, to check for leaks. */
213 struct reftable_log_record out
= {
214 .refname
= xstrdup("old name"),
215 .value_type
= REFTABLE_LOG_UPDATE
,
218 .new_hash
= reftable_calloc(GIT_SHA1_RAWSZ
),
219 .old_hash
= reftable_calloc(GIT_SHA1_RAWSZ
),
220 .name
= xstrdup("old name"),
221 .email
= xstrdup("old@email"),
222 .message
= xstrdup("old message"),
226 struct reftable_record rec_out
= { NULL
};
229 reftable_record_from_log(&rec
, &in
[i
]);
233 reftable_record_key(&rec
, &key
);
235 n
= reftable_record_encode(&rec
, dest
, GIT_SHA1_RAWSZ
);
237 reftable_record_from_log(&rec_out
, &out
);
238 valtype
= reftable_record_val_type(&rec
);
239 m
= reftable_record_decode(&rec_out
, key
, valtype
, dest
,
243 EXPECT(reftable_log_record_equal(&in
[i
], &out
, GIT_SHA1_RAWSZ
));
244 reftable_log_record_release(&in
[i
]);
245 strbuf_release(&key
);
246 reftable_record_release(&rec_out
);
250 static void test_u24_roundtrip(void)
252 uint32_t in
= 0x112233;
256 out
= get_be24(dest
);
260 static void test_key_roundtrip(void)
262 uint8_t buffer
[1024] = { 0 };
263 struct string_view dest
= {
265 .len
= sizeof(buffer
),
267 struct strbuf last_key
= STRBUF_INIT
;
268 struct strbuf key
= STRBUF_INIT
;
269 struct strbuf roundtrip
= STRBUF_INIT
;
275 strbuf_addstr(&last_key
, "refs/heads/master");
276 strbuf_addstr(&key
, "refs/tags/bla");
278 n
= reftable_encode_key(&restart
, dest
, last_key
, key
, extra
);
282 m
= reftable_decode_key(&roundtrip
, &rt_extra
, last_key
, dest
);
284 EXPECT(0 == strbuf_cmp(&key
, &roundtrip
));
285 EXPECT(rt_extra
== extra
);
287 strbuf_release(&last_key
);
288 strbuf_release(&key
);
289 strbuf_release(&roundtrip
);
292 static void test_reftable_obj_record_roundtrip(void)
294 uint8_t testHash1
[GIT_SHA1_RAWSZ
] = { 1, 2, 3, 4, 0 };
295 uint64_t till9
[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 };
296 struct reftable_obj_record recs
[3] = { {
297 .hash_prefix
= testHash1
,
298 .hash_prefix_len
= 5,
303 .hash_prefix
= testHash1
,
304 .hash_prefix_len
= 5,
309 .hash_prefix
= testHash1
,
310 .hash_prefix_len
= 5,
313 for (i
= 0; i
< ARRAY_SIZE(recs
); i
++) {
314 struct reftable_obj_record in
= recs
[i
];
315 uint8_t buffer
[1024] = { 0 };
316 struct string_view dest
= {
318 .len
= sizeof(buffer
),
320 struct reftable_record rec
= { NULL
};
321 struct strbuf key
= STRBUF_INIT
;
322 struct reftable_obj_record out
= { NULL
};
323 struct reftable_record rec_out
= { NULL
};
327 reftable_record_from_obj(&rec
, &in
);
329 reftable_record_key(&rec
, &key
);
330 n
= reftable_record_encode(&rec
, dest
, GIT_SHA1_RAWSZ
);
332 extra
= reftable_record_val_type(&rec
);
333 reftable_record_from_obj(&rec_out
, &out
);
334 m
= reftable_record_decode(&rec_out
, key
, extra
, dest
,
338 EXPECT(reftable_record_equal(&rec
, &rec_out
, GIT_SHA1_RAWSZ
));
339 strbuf_release(&key
);
340 reftable_record_release(&rec_out
);
344 static void test_reftable_index_record_roundtrip(void)
346 struct reftable_index_record in
= {
348 .last_key
= STRBUF_INIT
,
350 uint8_t buffer
[1024] = { 0 };
351 struct string_view dest
= {
353 .len
= sizeof(buffer
),
355 struct strbuf key
= STRBUF_INIT
;
356 struct reftable_record rec
= { NULL
};
357 struct reftable_index_record out
= { .last_key
= STRBUF_INIT
};
358 struct reftable_record out_rec
= { NULL
};
362 strbuf_addstr(&in
.last_key
, "refs/heads/master");
363 reftable_record_from_index(&rec
, &in
);
364 reftable_record_key(&rec
, &key
);
367 EXPECT(0 == strbuf_cmp(&key
, &in
.last_key
));
368 n
= reftable_record_encode(&rec
, dest
, GIT_SHA1_RAWSZ
);
371 extra
= reftable_record_val_type(&rec
);
372 reftable_record_from_index(&out_rec
, &out
);
373 m
= reftable_record_decode(&out_rec
, key
, extra
, dest
, GIT_SHA1_RAWSZ
);
376 EXPECT(reftable_record_equal(&rec
, &out_rec
, GIT_SHA1_RAWSZ
));
378 reftable_record_release(&out_rec
);
379 strbuf_release(&key
);
380 strbuf_release(&in
.last_key
);
383 int record_test_main(int argc
, const char *argv
[])
385 RUN_TEST(test_reftable_log_record_equal
);
386 RUN_TEST(test_reftable_log_record_roundtrip
);
387 RUN_TEST(test_reftable_ref_record_roundtrip
);
388 RUN_TEST(test_varint_roundtrip
);
389 RUN_TEST(test_key_roundtrip
);
390 RUN_TEST(test_common_prefix
);
391 RUN_TEST(test_reftable_obj_record_roundtrip
);
392 RUN_TEST(test_reftable_index_record_roundtrip
);
393 RUN_TEST(test_u24_roundtrip
);