forked from msysgit/git
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
t/: migrate helper/test-oidtree.c to unit-tests/t-oidtree.c
helper/test-oidtree.c along with t0069-oidtree.sh test the oidtree.h library, which is a wrapper around crit-bit tree. Migrate them to the unit testing framework for better debugging and runtime performance. Along with the migration, add an extra check for oidtree_each() test, which showcases how multiple expected matches can be given to check_each() helper. To achieve this, introduce a new library called 'lib-oid.h' exclusively for the unit tests to use. It currently mainly includes utility to generate object_id from an arbitrary hex string (i.e. '12a' -> '12a0000000000000000000000000000000000000'). This also handles the hash algo selection based on GIT_TEST_DEFAULT_HASH. This library will also be helpful when we port other unit tests such as oid-array, oidset etc. Helped-by: Junio C Hamano <[email protected]> Mentored-by: Christian Couder <[email protected]> Mentored-by: Kaartic Sivaraam <[email protected]> Signed-off-by: Ghanshyam Thakkar <[email protected]> [jc: small fixlets squashed in] Signed-off-by: Junio C Hamano <[email protected]>
- Loading branch information
Showing
8 changed files
with
197 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#include "test-lib.h" | ||
#include "lib-oid.h" | ||
#include "strbuf.h" | ||
#include "hex.h" | ||
|
||
static int init_hash_algo(void) | ||
{ | ||
static int algo = -1; | ||
|
||
if (algo < 0) { | ||
const char *algo_name = getenv("GIT_TEST_DEFAULT_HASH"); | ||
algo = algo_name ? hash_algo_by_name(algo_name) : GIT_HASH_SHA1; | ||
|
||
if (!check(algo != GIT_HASH_UNKNOWN)) | ||
test_msg("BUG: invalid GIT_TEST_DEFAULT_HASH value ('%s')", | ||
algo_name); | ||
} | ||
return algo; | ||
} | ||
|
||
static int get_oid_arbitrary_hex_algop(const char *hex, struct object_id *oid, | ||
const struct git_hash_algo *algop) | ||
{ | ||
int ret; | ||
size_t sz = strlen(hex); | ||
struct strbuf buf = STRBUF_INIT; | ||
|
||
if (!check(sz <= algop->hexsz)) { | ||
test_msg("BUG: hex string (%s) bigger than maximum allowed (%lu)", | ||
hex, (unsigned long)algop->hexsz); | ||
return -1; | ||
} | ||
|
||
strbuf_add(&buf, hex, sz); | ||
strbuf_addchars(&buf, '0', algop->hexsz - sz); | ||
|
||
ret = get_oid_hex_algop(buf.buf, oid, algop); | ||
if (!check_int(ret, ==, 0)) | ||
test_msg("BUG: invalid hex input (%s) provided", hex); | ||
|
||
strbuf_release(&buf); | ||
return ret; | ||
} | ||
|
||
int get_oid_arbitrary_hex(const char *hex, struct object_id *oid) | ||
{ | ||
int hash_algo = init_hash_algo(); | ||
|
||
if (!check_int(hash_algo, !=, GIT_HASH_UNKNOWN)) | ||
return -1; | ||
return get_oid_arbitrary_hex_algop(hex, oid, &hash_algos[hash_algo]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#ifndef LIB_OID_H | ||
#define LIB_OID_H | ||
|
||
#include "hash-ll.h" | ||
|
||
/* | ||
* Convert arbitrary hex string to object_id. | ||
* For example, passing "abc12" will generate | ||
* "abc1200000000000000000000000000000000000" hex of length 40 for SHA-1 and | ||
* create object_id with that. | ||
* WARNING: passing a string of length more than the hexsz of respective hash | ||
* algo is not allowed. The hash algo is decided based on GIT_TEST_DEFAULT_HASH | ||
* environment variable. | ||
*/ | ||
int get_oid_arbitrary_hex(const char *s, struct object_id *oid); | ||
|
||
#endif /* LIB_OID_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#include "test-lib.h" | ||
#include "lib-oid.h" | ||
#include "oidtree.h" | ||
#include "hash.h" | ||
#include "hex.h" | ||
#include "strvec.h" | ||
|
||
#define FILL_TREE(tree, ...) \ | ||
do { \ | ||
const char *hexes[] = { __VA_ARGS__ }; \ | ||
if (fill_tree_loc(tree, hexes, ARRAY_SIZE(hexes))) \ | ||
return; \ | ||
} while (0) | ||
|
||
static int fill_tree_loc(struct oidtree *ot, const char *hexes[], size_t n) | ||
{ | ||
for (size_t i = 0; i < n; i++) { | ||
struct object_id oid; | ||
if (!check_int(get_oid_arbitrary_hex(hexes[i], &oid), ==, 0)) | ||
return -1; | ||
oidtree_insert(ot, &oid); | ||
} | ||
return 0; | ||
} | ||
|
||
static void check_contains(struct oidtree *ot, const char *hex, int expected) | ||
{ | ||
struct object_id oid; | ||
|
||
if (!check_int(get_oid_arbitrary_hex(hex, &oid), ==, 0)) | ||
return; | ||
if (!check_int(oidtree_contains(ot, &oid), ==, expected)) | ||
test_msg("oid: %s", oid_to_hex(&oid)); | ||
} | ||
|
||
struct expected_hex_iter { | ||
size_t i; | ||
struct strvec expected_hexes; | ||
const char *query; | ||
}; | ||
|
||
static enum cb_next check_each_cb(const struct object_id *oid, void *data) | ||
{ | ||
struct expected_hex_iter *hex_iter = data; | ||
struct object_id expected; | ||
|
||
if (!check_int(hex_iter->i, <, hex_iter->expected_hexes.nr)) { | ||
test_msg("error: extraneous callback for query: ('%s'), object_id: ('%s')", | ||
hex_iter->query, oid_to_hex(oid)); | ||
return CB_BREAK; | ||
} | ||
|
||
if (!check_int(get_oid_arbitrary_hex(hex_iter->expected_hexes.v[hex_iter->i], | ||
&expected), ==, 0)) | ||
; /* the data is bogus and cannot be used */ | ||
else if (!check(oideq(oid, &expected))) | ||
test_msg("expected: %s\n got: %s\n query: %s", | ||
oid_to_hex(&expected), oid_to_hex(oid), hex_iter->query); | ||
|
||
hex_iter->i += 1; | ||
return CB_CONTINUE; | ||
} | ||
|
||
LAST_ARG_MUST_BE_NULL | ||
static void check_each(struct oidtree *ot, const char *query, ...) | ||
{ | ||
struct object_id oid; | ||
struct expected_hex_iter hex_iter = { .expected_hexes = STRVEC_INIT, | ||
.query = query }; | ||
const char *arg; | ||
va_list hex_args; | ||
|
||
va_start(hex_args, query); | ||
while ((arg = va_arg(hex_args, const char *))) | ||
strvec_push(&hex_iter.expected_hexes, arg); | ||
va_end(hex_args); | ||
|
||
if (!check_int(get_oid_arbitrary_hex(query, &oid), ==, 0)) | ||
return; | ||
oidtree_each(ot, &oid, strlen(query), check_each_cb, &hex_iter); | ||
|
||
if (!check_int(hex_iter.i, ==, hex_iter.expected_hexes.nr)) | ||
test_msg("error: could not find some 'object_id's for query ('%s')", query); | ||
strvec_clear(&hex_iter.expected_hexes); | ||
} | ||
|
||
static void setup(void (*f)(struct oidtree *ot)) | ||
{ | ||
struct oidtree ot; | ||
|
||
oidtree_init(&ot); | ||
f(&ot); | ||
oidtree_clear(&ot); | ||
} | ||
|
||
static void t_contains(struct oidtree *ot) | ||
{ | ||
FILL_TREE(ot, "444", "1", "2", "3", "4", "5", "a", "b", "c", "d", "e"); | ||
check_contains(ot, "44", 0); | ||
check_contains(ot, "441", 0); | ||
check_contains(ot, "440", 0); | ||
check_contains(ot, "444", 1); | ||
check_contains(ot, "4440", 1); | ||
check_contains(ot, "4444", 0); | ||
} | ||
|
||
static void t_each(struct oidtree *ot) | ||
{ | ||
FILL_TREE(ot, "f", "9", "8", "123", "321", "320", "a", "b", "c", "d", "e"); | ||
check_each(ot, "12300", "123", NULL); | ||
check_each(ot, "3211", NULL); /* should not reach callback */ | ||
check_each(ot, "3210", "321", NULL); | ||
check_each(ot, "32100", "321", NULL); | ||
check_each(ot, "32", "320", "321", NULL); | ||
} | ||
|
||
int cmd_main(int argc UNUSED, const char **argv UNUSED) | ||
{ | ||
TEST(setup(t_contains), "oidtree insert and contains works"); | ||
TEST(setup(t_each), "oidtree each works"); | ||
return test_done(); | ||
} |