Merge branch 'gt/unit-test-oidtree' into ps/use-the-repository
* gt/unit-test-oidtree: t/: migrate helper/test-oidtree.c to unit-tests/t-oidtree.c
This commit is contained in:
		
							
								
								
									
										8
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								Makefile
									
									
									
									
									
								
							@ -810,7 +810,6 @@ TEST_BUILTINS_OBJS += test-mergesort.o
 | 
			
		||||
TEST_BUILTINS_OBJS += test-mktemp.o
 | 
			
		||||
TEST_BUILTINS_OBJS += test-oid-array.o
 | 
			
		||||
TEST_BUILTINS_OBJS += test-oidmap.o
 | 
			
		||||
TEST_BUILTINS_OBJS += test-oidtree.o
 | 
			
		||||
TEST_BUILTINS_OBJS += test-online-cpus.o
 | 
			
		||||
TEST_BUILTINS_OBJS += test-pack-mtimes.o
 | 
			
		||||
TEST_BUILTINS_OBJS += test-parse-options.o
 | 
			
		||||
@ -1337,6 +1336,7 @@ UNIT_TEST_PROGRAMS += t-ctype
 | 
			
		||||
UNIT_TEST_PROGRAMS += t-example-decorate
 | 
			
		||||
UNIT_TEST_PROGRAMS += t-hash
 | 
			
		||||
UNIT_TEST_PROGRAMS += t-mem-pool
 | 
			
		||||
UNIT_TEST_PROGRAMS += t-oidtree
 | 
			
		||||
UNIT_TEST_PROGRAMS += t-prio-queue
 | 
			
		||||
UNIT_TEST_PROGRAMS += t-reftable-basics
 | 
			
		||||
UNIT_TEST_PROGRAMS += t-strbuf
 | 
			
		||||
@ -1346,6 +1346,7 @@ UNIT_TEST_PROGRAMS += t-trailer
 | 
			
		||||
UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS))
 | 
			
		||||
UNIT_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS))
 | 
			
		||||
UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o
 | 
			
		||||
UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/lib-oid.o
 | 
			
		||||
 | 
			
		||||
# xdiff and reftable libs may in turn depend on what is in libgit.a
 | 
			
		||||
GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(LIB_FILE)
 | 
			
		||||
@ -3885,7 +3886,10 @@ $(FUZZ_PROGRAMS): %: %.o oss-fuzz/dummy-cmd-main.o $(GITLIBS) GIT-LDFLAGS
 | 
			
		||||
		-Wl,--allow-multiple-definition \
 | 
			
		||||
		$(filter %.o,$^) $(filter %.a,$^) $(LIBS) $(LIB_FUZZING_ENGINE)
 | 
			
		||||
 | 
			
		||||
$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS
 | 
			
		||||
$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o \
 | 
			
		||||
	$(UNIT_TEST_DIR)/test-lib.o \
 | 
			
		||||
	$(UNIT_TEST_DIR)/lib-oid.o \
 | 
			
		||||
	$(GITLIBS) GIT-LDFLAGS
 | 
			
		||||
	$(call mkdir_p_parent_template)
 | 
			
		||||
	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
 | 
			
		||||
		$(filter %.o,$^) $(filter %.a,$^) $(LIBS)
 | 
			
		||||
 | 
			
		||||
@ -1,54 +0,0 @@
 | 
			
		||||
#include "test-tool.h"
 | 
			
		||||
#include "hex.h"
 | 
			
		||||
#include "oidtree.h"
 | 
			
		||||
#include "setup.h"
 | 
			
		||||
#include "strbuf.h"
 | 
			
		||||
 | 
			
		||||
static enum cb_next print_oid(const struct object_id *oid, void *data UNUSED)
 | 
			
		||||
{
 | 
			
		||||
	puts(oid_to_hex(oid));
 | 
			
		||||
	return CB_CONTINUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cmd__oidtree(int argc UNUSED, const char **argv UNUSED)
 | 
			
		||||
{
 | 
			
		||||
	struct oidtree ot;
 | 
			
		||||
	struct strbuf line = STRBUF_INIT;
 | 
			
		||||
	int nongit_ok;
 | 
			
		||||
	int algo = GIT_HASH_UNKNOWN;
 | 
			
		||||
 | 
			
		||||
	oidtree_init(&ot);
 | 
			
		||||
	setup_git_directory_gently(&nongit_ok);
 | 
			
		||||
 | 
			
		||||
	while (strbuf_getline(&line, stdin) != EOF) {
 | 
			
		||||
		const char *arg;
 | 
			
		||||
		struct object_id oid;
 | 
			
		||||
 | 
			
		||||
		if (skip_prefix(line.buf, "insert ", &arg)) {
 | 
			
		||||
			if (get_oid_hex_any(arg, &oid) == GIT_HASH_UNKNOWN)
 | 
			
		||||
				die("insert not a hexadecimal oid: %s", arg);
 | 
			
		||||
			algo = oid.algo;
 | 
			
		||||
			oidtree_insert(&ot, &oid);
 | 
			
		||||
		} else if (skip_prefix(line.buf, "contains ", &arg)) {
 | 
			
		||||
			if (get_oid_hex(arg, &oid))
 | 
			
		||||
				die("contains not a hexadecimal oid: %s", arg);
 | 
			
		||||
			printf("%d\n", oidtree_contains(&ot, &oid));
 | 
			
		||||
		} else if (skip_prefix(line.buf, "each ", &arg)) {
 | 
			
		||||
			char buf[GIT_MAX_HEXSZ + 1] = { '0' };
 | 
			
		||||
			memset(&oid, 0, sizeof(oid));
 | 
			
		||||
			memcpy(buf, arg, strlen(arg));
 | 
			
		||||
			buf[hash_algos[algo].hexsz] = '\0';
 | 
			
		||||
			get_oid_hex_any(buf, &oid);
 | 
			
		||||
			oid.algo = algo;
 | 
			
		||||
			oidtree_each(&ot, &oid, strlen(arg), print_oid, NULL);
 | 
			
		||||
		} else if (!strcmp(line.buf, "clear")) {
 | 
			
		||||
			oidtree_clear(&ot);
 | 
			
		||||
		} else {
 | 
			
		||||
			die("unknown command: %s", line.buf);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	strbuf_release(&line);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@ -45,7 +45,6 @@ static struct test_cmd cmds[] = {
 | 
			
		||||
	{ "mktemp", cmd__mktemp },
 | 
			
		||||
	{ "oid-array", cmd__oid_array },
 | 
			
		||||
	{ "oidmap", cmd__oidmap },
 | 
			
		||||
	{ "oidtree", cmd__oidtree },
 | 
			
		||||
	{ "online-cpus", cmd__online_cpus },
 | 
			
		||||
	{ "pack-mtimes", cmd__pack_mtimes },
 | 
			
		||||
	{ "parse-options", cmd__parse_options },
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,6 @@ int cmd__match_trees(int argc, const char **argv);
 | 
			
		||||
int cmd__mergesort(int argc, const char **argv);
 | 
			
		||||
int cmd__mktemp(int argc, const char **argv);
 | 
			
		||||
int cmd__oidmap(int argc, const char **argv);
 | 
			
		||||
int cmd__oidtree(int argc, const char **argv);
 | 
			
		||||
int cmd__online_cpus(int argc, const char **argv);
 | 
			
		||||
int cmd__pack_mtimes(int argc, const char **argv);
 | 
			
		||||
int cmd__parse_options(int argc, const char **argv);
 | 
			
		||||
 | 
			
		||||
@ -1,50 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
test_description='basic tests for the oidtree implementation'
 | 
			
		||||
TEST_PASSES_SANITIZE_LEAK=true
 | 
			
		||||
. ./test-lib.sh
 | 
			
		||||
 | 
			
		||||
maxhexsz=$(test_oid hexsz)
 | 
			
		||||
echoid () {
 | 
			
		||||
	prefix="${1:+$1 }"
 | 
			
		||||
	shift
 | 
			
		||||
	while test $# -gt 0
 | 
			
		||||
	do
 | 
			
		||||
		shortoid="$1"
 | 
			
		||||
		shift
 | 
			
		||||
		difference=$(($maxhexsz - ${#shortoid}))
 | 
			
		||||
		printf "%s%s%0${difference}d\\n" "$prefix" "$shortoid" "0"
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test_expect_success 'oidtree insert and contains' '
 | 
			
		||||
	cat >expect <<-\EOF &&
 | 
			
		||||
		0
 | 
			
		||||
		0
 | 
			
		||||
		0
 | 
			
		||||
		1
 | 
			
		||||
		1
 | 
			
		||||
		0
 | 
			
		||||
	EOF
 | 
			
		||||
	{
 | 
			
		||||
		echoid insert 444 1 2 3 4 5 a b c d e &&
 | 
			
		||||
		echoid contains 44 441 440 444 4440 4444 &&
 | 
			
		||||
		echo clear
 | 
			
		||||
	} | test-tool oidtree >actual &&
 | 
			
		||||
	test_cmp expect actual
 | 
			
		||||
'
 | 
			
		||||
 | 
			
		||||
test_expect_success 'oidtree each' '
 | 
			
		||||
	echoid "" 123 321 321 >expect &&
 | 
			
		||||
	{
 | 
			
		||||
		echoid insert f 9 8 123 321 a b c d e &&
 | 
			
		||||
		echo each 12300 &&
 | 
			
		||||
		echo each 3211 &&
 | 
			
		||||
		echo each 3210 &&
 | 
			
		||||
		echo each 32100 &&
 | 
			
		||||
		echo clear
 | 
			
		||||
	} | test-tool oidtree >actual &&
 | 
			
		||||
	test_cmp expect actual
 | 
			
		||||
'
 | 
			
		||||
 | 
			
		||||
test_done
 | 
			
		||||
							
								
								
									
										52
									
								
								t/unit-tests/lib-oid.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								t/unit-tests/lib-oid.c
									
									
									
									
									
										Normal file
									
								
							@ -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]);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								t/unit-tests/lib-oid.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								t/unit-tests/lib-oid.h
									
									
									
									
									
										Normal file
									
								
							@ -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 */
 | 
			
		||||
							
								
								
									
										122
									
								
								t/unit-tests/t-oidtree.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								t/unit-tests/t-oidtree.c
									
									
									
									
									
										Normal file
									
								
							@ -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();
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user