mixed.c 7.63 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
#include "clar_libgit2.h"
#include "odb.h"

static git_odb *_odb;

void test_odb_mixed__initialize(void)
{
	cl_git_pass(git_odb_open(&_odb, cl_fixture("duplicate.git/objects")));
}

void test_odb_mixed__cleanup(void)
{
	git_odb_free(_odb);
14
	_odb = NULL;
15 16 17 18
}

void test_odb_mixed__dup_oid(void) {
	const char hex[] = "ce013625030ba8dba906f756967f9e9ca394464a";
19
	const char short_hex[] = "ce01362";
20 21
	git_oid oid;
	git_odb_object *obj;
22

23 24
	cl_git_pass(git_oid_fromstr(&oid, hex));
	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, GIT_OID_HEXSZ));
25
	git_odb_object_free(obj);
26 27 28

	cl_git_pass(git_odb_exists_prefix(NULL, _odb, &oid, GIT_OID_HEXSZ));

29 30
	cl_git_pass(git_oid_fromstrn(&oid, short_hex, sizeof(short_hex) - 1));
	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, sizeof(short_hex) - 1));
31
	git_odb_object_free(obj);
32 33

	cl_git_pass(git_odb_exists_prefix(NULL, _odb, &oid, sizeof(short_hex) - 1));
34 35
}

36 37 38 39 40 41 42 43 44
/* some known sha collisions of file content:
 *   'aabqhq' and 'aaazvc' with prefix 'dea509d0' (+ '9' and + 'b')
 *   'aaeufo' and 'aaaohs' with prefix '81b5bff5' (+ 'f' and + 'b')
 *   'aafewy' and 'aaepta' with prefix '739e3c4c'
 *   'aahsyn' and 'aadrjg' with prefix '0ddeaded' (+ '9' and + 'e')
 */

void test_odb_mixed__dup_oid_prefix_0(void) {
	char hex[10];
45
	git_oid oid, found;
46 47 48 49 50 51 52 53
	git_odb_object *obj;

	/* ambiguous in the same pack file */

	strncpy(hex, "dea509d0", sizeof(hex));
	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
	cl_assert_equal_i(
		GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
54 55
	cl_assert_equal_i(
		GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
56 57 58 59

	strncpy(hex, "dea509d09", sizeof(hex));
	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
60
	cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
61
	cl_assert_equal_oid(&found, git_odb_object_id(obj));
62 63 64 65 66 67 68 69 70 71 72 73 74
	git_odb_object_free(obj);

	strncpy(hex, "dea509d0b", sizeof(hex));
	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
	git_odb_object_free(obj);

	/* ambiguous in different pack files */

	strncpy(hex, "81b5bff5", sizeof(hex));
	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
	cl_assert_equal_i(
		GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
75 76
	cl_assert_equal_i(
		GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
77 78 79 80

	strncpy(hex, "81b5bff5b", sizeof(hex));
	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
81
	cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
82
	cl_assert_equal_oid(&found, git_odb_object_id(obj));
83 84 85 86 87 88 89 90 91 92 93 94 95
	git_odb_object_free(obj);

	strncpy(hex, "81b5bff5f", sizeof(hex));
	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
	git_odb_object_free(obj);

	/* ambiguous in pack file and loose */

	strncpy(hex, "0ddeaded", sizeof(hex));
	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
	cl_assert_equal_i(
		GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
96 97
	cl_assert_equal_i(
		GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
98 99 100 101

	strncpy(hex, "0ddeaded9", sizeof(hex));
	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
102
	cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
103
	cl_assert_equal_oid(&found, git_odb_object_id(obj));
104 105 106 107 108 109 110
	git_odb_object_free(obj);

	strncpy(hex, "0ddeadede", sizeof(hex));
	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
	git_odb_object_free(obj);
}
111

112
struct expand_id_test_data {
113 114 115 116 117
	char *lookup_id;
	char *expected_id;
	git_otype expected_type;
};

118
struct expand_id_test_data expand_id_test_data[] = {
119 120 121 122 123 124 125 126 127 128 129 130 131 132
	/* some prefixes and their expected values */
	{ "dea509d0",  NULL, GIT_OBJ_ANY },
	{ "00000000",  NULL, GIT_OBJ_ANY },
	{ "dea509d0",  NULL, GIT_OBJ_ANY },
	{ "dea509d09", "dea509d097ce692e167dfc6a48a7a280cc5e877e", GIT_OBJ_BLOB },
	{ "dea509d0b", "dea509d0b3cb8ee0650f6ca210bc83f4678851ba", GIT_OBJ_BLOB },
	{ "ce0136250", "ce013625030ba8dba906f756967f9e9ca394464a", GIT_OBJ_BLOB },
	{ "0ddeaded",  NULL, GIT_OBJ_ANY },
	{ "4d5979b",   "4d5979b468252190cb572ae758aca36928e8a91e", GIT_OBJ_TREE },
	{ "0ddeaded",  NULL, GIT_OBJ_ANY },
	{ "0ddeadede", "0ddeadede9e6d6ccddce0ee1e5749eed0485e5ea", GIT_OBJ_BLOB },
	{ "0ddeaded9", "0ddeaded9502971eefe1e41e34d0e536853ae20f", GIT_OBJ_BLOB },
	{ "f00b4e",    NULL, GIT_OBJ_ANY },

133 134 135
	/* this OID is too short and should be ambiguous! */
	{ "f00",    NULL, GIT_OBJ_ANY },

136 137 138 139 140 141 142 143 144 145 146 147 148
	/* some full-length object ids */
	{ "0000000000000000000000000000000000000000", NULL, GIT_OBJ_ANY },
	{
	  "dea509d097ce692e167dfc6a48a7a280cc5e877e",
	  "dea509d097ce692e167dfc6a48a7a280cc5e877e",
	  GIT_OBJ_BLOB
	},
	{ "f00f00f00f00f00f00f00f00f00f00f00f00f00f", NULL, GIT_OBJ_ANY },
	{
	  "4d5979b468252190cb572ae758aca36928e8a91e",
	  "4d5979b468252190cb572ae758aca36928e8a91e",
	  GIT_OBJ_TREE
	},
149 150 151 152 153 154

	 /*
	  * ensure we're not leaking the return error code for the
	  * last lookup if the last object is invalid
	  */
	{ "0ddeadedfff",  NULL, GIT_OBJ_ANY },
155 156 157
};

static void setup_prefix_query(
158
	git_odb_expand_id **out_ids,
159 160
	size_t *out_num)
{
161 162
	git_odb_expand_id *ids;
	size_t num, i;
163

164
	num = ARRAY_SIZE(expand_id_test_data);
165

166
	cl_assert((ids = git__calloc(num, sizeof(git_odb_expand_id))));
167 168

	for (i = 0; i < num; i++) {
169 170 171 172 173 174 175
		git_odb_expand_id *id = &ids[i];

		size_t len = strlen(expand_id_test_data[i].lookup_id);

		git_oid_fromstrn(&id->id, expand_id_test_data[i].lookup_id, len);
		id->length = (unsigned short)len;
		id->type = expand_id_test_data[i].expected_type;
176 177 178 179 180 181
	}

	*out_ids = ids;
	*out_num = num;
}

182
static void assert_found_objects(git_odb_expand_id *ids)
183 184 185
{
	size_t num, i;

186
	num = ARRAY_SIZE(expand_id_test_data);
187 188 189 190

	for (i = 0; i < num; i++) {
		git_oid expected_id = {{0}};
		size_t expected_len = 0;
191
		git_otype expected_type = 0;
192

193 194
		if (expand_id_test_data[i].expected_id) {
			git_oid_fromstr(&expected_id, expand_id_test_data[i].expected_id);
195
			expected_len = GIT_OID_HEXSZ;
196
			expected_type = expand_id_test_data[i].expected_type;
197 198
		}

199 200 201
		cl_assert_equal_oid(&expected_id, &ids[i].id);
		cl_assert_equal_i(expected_len, ids[i].length);
		cl_assert_equal_i(expected_type, ids[i].type);
202 203 204
	}
}

205
static void assert_notfound_objects(git_odb_expand_id *ids)
206 207 208 209
{
	git_oid expected_id = {{0}};
	size_t num, i;

210
	num = ARRAY_SIZE(expand_id_test_data);
211 212

	for (i = 0; i < num; i++) {
213 214 215
		cl_assert_equal_oid(&expected_id, &ids[i].id);
		cl_assert_equal_i(0, ids[i].length);
		cl_assert_equal_i(0, ids[i].type);
216 217 218
	}
}

219
void test_odb_mixed__expand_ids(void)
220
{
221 222
	git_odb_expand_id *ids;
	size_t i, num;
223 224 225

	/* test looking for the actual (correct) types */

226 227 228 229 230 231
	setup_prefix_query(&ids, &num);
	cl_git_pass(git_odb_expand_ids(_odb, ids, num));
	assert_found_objects(ids);
	git__free(ids);

	/* test looking for an explicit `type == 0` */
232

233 234 235 236
	setup_prefix_query(&ids, &num);

	for (i = 0; i < num; i++)
		ids[i].type = 0;
237

238 239 240
	cl_git_pass(git_odb_expand_ids(_odb, ids, num));
	assert_found_objects(ids);
	git__free(ids);
241 242 243

	/* test looking for an explicit GIT_OBJ_ANY */

244
	setup_prefix_query(&ids, &num);
245 246

	for (i = 0; i < num; i++)
247
		ids[i].type = GIT_OBJ_ANY;
248

249 250 251
	cl_git_pass(git_odb_expand_ids(_odb, ids, num));
	assert_found_objects(ids);
	git__free(ids);
252 253 254

	/* test looking for the completely wrong type */

255
	setup_prefix_query(&ids, &num);
256 257

	for (i = 0; i < num; i++)
258 259
		ids[i].type = (ids[i].type == GIT_OBJ_BLOB) ?
			GIT_OBJ_TREE : GIT_OBJ_BLOB;
260

261 262 263
	cl_git_pass(git_odb_expand_ids(_odb, ids, num));
	assert_notfound_objects(ids);
	git__free(ids);
264 265
}