Commit 6e010bb126360d084b1c38056728c7fd3286a443

Patrick Steinhardt 2017-06-12T15:43:56

tests: odb: allow passing fake objects to the fake backend Right now, the fake backend is quite restrained in the way how it works: we pass it an OID which it is to return later as well as an error code we want it to return. While this is sufficient for existing tests, we can make the fake backend a little bit more generic in order to allow us testing for additional scenarios. To do so, we change the backend to not accept an error code and OID which it is to return for queries, but instead a simple array of OIDs with their respective blob contents. On each query, the fake backend simply iterates through this array and returns the first matching object.

diff --git a/tests/odb/backend/backend_helpers.c b/tests/odb/backend/backend_helpers.c
index 21b33b9..2653702 100644
--- a/tests/odb/backend/backend_helpers.c
+++ b/tests/odb/backend/backend_helpers.c
@@ -2,83 +2,99 @@
 #include "git2/sys/odb_backend.h"
 #include "backend_helpers.h"
 
+static int search_object(const fake_object **out, fake_backend *fake, const git_oid *oid, size_t len)
+{
+	const fake_object *obj = fake->objects;
+
+	while (obj && obj->oid) {
+		git_oid current_oid;
+
+		git_oid_fromstr(&current_oid, obj->oid);
+
+		if (git_oid_ncmp(&current_oid, oid, len) == 0) {
+			if (out)
+				*out = obj;
+			return 0;
+		}
+
+		obj++;
+	}
+
+	return GIT_ENOTFOUND;
+}
+
 static int fake_backend__exists(git_odb_backend *backend, const git_oid *oid)
 {
 	fake_backend *fake;
 
-	GIT_UNUSED(oid);
-
 	fake = (fake_backend *)backend;
 
 	fake->exists_calls++;
 
-	return (fake->error_code == GIT_OK);
+	return search_object(NULL, fake, oid, GIT_OID_RAWSZ) == GIT_OK;
 }
 
 static int fake_backend__read(
 	void **buffer_p, size_t *len_p, git_otype *type_p,
 	git_odb_backend *backend, const git_oid *oid)
 {
+	const fake_object *obj;
 	fake_backend *fake;
 
-	GIT_UNUSED(buffer_p);
-	GIT_UNUSED(len_p);
-	GIT_UNUSED(type_p);
-	GIT_UNUSED(oid);
-
 	fake = (fake_backend *)backend;
 
 	fake->read_calls++;
 
-	*len_p = 0;
-	*buffer_p = NULL;
-	*type_p = GIT_OBJ_BLOB;
+	if (search_object(&obj, fake, oid, GIT_OID_RAWSZ) == 0) {
+		*len_p = strlen(obj->content);
+		*buffer_p = git__strdup(obj->content);
+		*type_p = GIT_OBJ_BLOB;
+		return 0;
+	}
 
-	return fake->error_code;
+	return GIT_ENOTFOUND;
 }
 
 static int fake_backend__read_header(
 	size_t *len_p, git_otype *type_p,
 	git_odb_backend *backend, const git_oid *oid)
 {
+	const fake_object *obj;
 	fake_backend *fake;
 
-	GIT_UNUSED(len_p);
-	GIT_UNUSED(type_p);
-	GIT_UNUSED(oid);
-
 	fake = (fake_backend *)backend;
 
 	fake->read_header_calls++;
 
-	*len_p = 0;
-	*type_p = GIT_OBJ_BLOB;
+	if (search_object(&obj, fake, oid, GIT_OID_RAWSZ) == 0) {
+		*len_p = strlen(obj->content);
+		*type_p = GIT_OBJ_BLOB;
+		return 0;
+	}
 
-	return fake->error_code;
+	return GIT_ENOTFOUND;
 }
 
 static int fake_backend__read_prefix(
 	git_oid *out_oid, void **buffer_p, size_t *len_p, git_otype *type_p,
 	git_odb_backend *backend, const git_oid *short_oid, size_t len)
 {
+	const fake_object *obj;
 	fake_backend *fake;
 
-	GIT_UNUSED(buffer_p);
-	GIT_UNUSED(len_p);
-	GIT_UNUSED(type_p);
-	GIT_UNUSED(short_oid);
-	GIT_UNUSED(len);
-
 	fake = (fake_backend *)backend;
 
 	fake->read_prefix_calls++;
 
-	git_oid_cpy(out_oid, &fake->oid);
-	*len_p = 0;
-	*buffer_p = NULL;
-	*type_p = GIT_OBJ_BLOB;
+	if (search_object(&obj, fake, short_oid, len) == 0) {
+		git_oid_fromstr(out_oid, obj->oid);
+		*len_p = strlen(obj->content);
+		*buffer_p = git__strdup(obj->content);
+		*type_p = GIT_OBJ_BLOB;
+		return 0;
+	}
 
-	return fake->error_code;
+	return GIT_ENOTFOUND;
 }
 
 static void fake_backend__free(git_odb_backend *_backend)
@@ -92,8 +108,7 @@ static void fake_backend__free(git_odb_backend *_backend)
 
 int build_fake_backend(
 	git_odb_backend **out,
-	git_error_code error_code,
-	const git_oid *oid)
+	const fake_object *objects)
 {
 	fake_backend *backend;
 
@@ -103,7 +118,7 @@ int build_fake_backend(
 	backend->parent.version = GIT_ODB_BACKEND_VERSION;
 
 	backend->parent.refresh = NULL;
-	backend->error_code = error_code;
+	backend->objects = objects;
 
 	backend->parent.read = fake_backend__read;
 	backend->parent.read_prefix = fake_backend__read_prefix;
@@ -111,8 +126,6 @@ int build_fake_backend(
 	backend->parent.exists = fake_backend__exists;
 	backend->parent.free = &fake_backend__free;
 
-	git_oid_cpy(&backend->oid, oid);
-
 	*out = (git_odb_backend *)backend;
 
 	return 0;
diff --git a/tests/odb/backend/backend_helpers.h b/tests/odb/backend/backend_helpers.h
index 04bd844..6cc1ce9 100644
--- a/tests/odb/backend/backend_helpers.h
+++ b/tests/odb/backend/backend_helpers.h
@@ -1,18 +1,21 @@
 #include "git2/sys/odb_backend.h"
 
 typedef struct {
-	git_odb_backend parent;
+	const char *oid;
+	const char *content;
+} fake_object;
 
-	git_error_code error_code;
-	git_oid oid;
+typedef struct {
+	git_odb_backend parent;
 
 	int exists_calls;
 	int read_calls;
 	int read_header_calls;
 	int read_prefix_calls;
+
+	const fake_object *objects;
 } fake_backend;
 
 int build_fake_backend(
 	git_odb_backend **out,
-	git_error_code error_code,
-	const git_oid *oid);
+	const fake_object *objects);
diff --git a/tests/odb/backend/nonrefreshing.c b/tests/odb/backend/nonrefreshing.c
index 42da312..6abc0c6 100644
--- a/tests/odb/backend/nonrefreshing.c
+++ b/tests/odb/backend/nonrefreshing.c
@@ -5,22 +5,25 @@
 static git_repository *_repo;
 static fake_backend *_fake;
 
-#define HASH "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
-#define EMPTY_HASH "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
+#define NONEXISTING_HASH "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
+#define EXISTING_HASH "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
 
-static git_oid _oid;
-static git_oid _empty_oid;
+static const fake_object _objects[] = {
+	{ EXISTING_HASH, "" },
+	{ NULL, NULL }
+};
 
-static void setup_repository_and_backend(git_error_code error_code, const char *hash)
+static git_oid _nonexisting_oid;
+static git_oid _existing_oid;
+
+static void setup_repository_and_backend(void)
 {
 	git_odb *odb = NULL;
 	git_odb_backend *backend = NULL;
-	git_oid oid;
 
 	_repo = cl_git_sandbox_init("testrepo.git");
 
-	cl_git_pass(git_oid_fromstr(&oid, hash));
-	cl_git_pass(build_fake_backend(&backend, error_code, &oid));
+	cl_git_pass(build_fake_backend(&backend, _objects));
 
 	cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
 	cl_git_pass(git_odb_add_backend(odb, backend, 10));
@@ -30,8 +33,9 @@ static void setup_repository_and_backend(git_error_code error_code, const char *
 
 void test_odb_backend_nonrefreshing__initialize(void)
 {
-	git_oid_fromstr(&_oid, HASH);
-	git_oid_fromstr(&_empty_oid, EMPTY_HASH);
+	git_oid_fromstr(&_nonexisting_oid, NONEXISTING_HASH);
+	git_oid_fromstr(&_existing_oid, EXISTING_HASH);
+	setup_repository_and_backend();
 }
 
 void test_odb_backend_nonrefreshing__cleanup(void)
@@ -43,10 +47,8 @@ void test_odb_backend_nonrefreshing__exists_is_invoked_once_on_failure(void)
 {
 	git_odb *odb;
 
-	setup_repository_and_backend(GIT_ENOTFOUND, HASH);
-
 	cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
-	cl_assert_equal_b(false, git_odb_exists(odb, &_oid));
+	cl_assert_equal_b(false, git_odb_exists(odb, &_nonexisting_oid));
 
 	cl_assert_equal_i(1, _fake->exists_calls);
 }
@@ -55,10 +57,8 @@ void test_odb_backend_nonrefreshing__read_is_invoked_once_on_failure(void)
 {
 	git_object *obj;
 
-	setup_repository_and_backend(GIT_ENOTFOUND, HASH);
-
 	cl_git_fail_with(
-		git_object_lookup(&obj, _repo, &_oid, GIT_OBJ_ANY),
+		git_object_lookup(&obj, _repo, &_nonexisting_oid, GIT_OBJ_ANY),
 		GIT_ENOTFOUND);
 
 	cl_assert_equal_i(1, _fake->read_calls);
@@ -68,10 +68,8 @@ void test_odb_backend_nonrefreshing__readprefix_is_invoked_once_on_failure(void)
 {
 	git_object *obj;
 
-	setup_repository_and_backend(GIT_ENOTFOUND, HASH);
-
 	cl_git_fail_with(
-		git_object_lookup_prefix(&obj, _repo, &_oid, 7, GIT_OBJ_ANY),
+		git_object_lookup_prefix(&obj, _repo, &_nonexisting_oid, 7, GIT_OBJ_ANY),
 		GIT_ENOTFOUND);
 
 	cl_assert_equal_i(1, _fake->read_prefix_calls);
@@ -83,12 +81,10 @@ void test_odb_backend_nonrefreshing__readheader_is_invoked_once_on_failure(void)
 	size_t len;
 	git_otype type;
 
-	setup_repository_and_backend(GIT_ENOTFOUND, HASH);
-
 	cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
 
 	cl_git_fail_with(
-		git_odb_read_header(&len, &type, odb, &_oid),
+		git_odb_read_header(&len, &type, odb, &_nonexisting_oid),
 		GIT_ENOTFOUND);
 
 	cl_assert_equal_i(1, _fake->read_header_calls);
@@ -98,10 +94,8 @@ void test_odb_backend_nonrefreshing__exists_is_invoked_once_on_success(void)
 {
 	git_odb *odb;
 
-	setup_repository_and_backend(GIT_OK, HASH);
-
 	cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
-	cl_assert_equal_b(true, git_odb_exists(odb, &_oid));
+	cl_assert_equal_b(true, git_odb_exists(odb, &_existing_oid));
 
 	cl_assert_equal_i(1, _fake->exists_calls);
 }
@@ -110,9 +104,7 @@ void test_odb_backend_nonrefreshing__read_is_invoked_once_on_success(void)
 {
 	git_object *obj;
 
-	setup_repository_and_backend(GIT_OK, EMPTY_HASH);
-
-	cl_git_pass(git_object_lookup(&obj, _repo, &_empty_oid, GIT_OBJ_ANY));
+	cl_git_pass(git_object_lookup(&obj, _repo, &_existing_oid, GIT_OBJ_ANY));
 
 	cl_assert_equal_i(1, _fake->read_calls);
 
@@ -123,9 +115,7 @@ void test_odb_backend_nonrefreshing__readprefix_is_invoked_once_on_success(void)
 {
 	git_object *obj;
 
-	setup_repository_and_backend(GIT_OK, EMPTY_HASH);
-
-	cl_git_pass(git_object_lookup_prefix(&obj, _repo, &_empty_oid, 7, GIT_OBJ_ANY));
+	cl_git_pass(git_object_lookup_prefix(&obj, _repo, &_existing_oid, 7, GIT_OBJ_ANY));
 
 	cl_assert_equal_i(1, _fake->read_prefix_calls);
 
@@ -138,11 +128,9 @@ void test_odb_backend_nonrefreshing__readheader_is_invoked_once_on_success(void)
 	size_t len;
 	git_otype type;
 
-	setup_repository_and_backend(GIT_OK, HASH);
-
 	cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
 
-	cl_git_pass(git_odb_read_header(&len, &type, odb, &_oid));
+	cl_git_pass(git_odb_read_header(&len, &type, odb, &_existing_oid));
 
 	cl_assert_equal_i(1, _fake->read_header_calls);
 }
@@ -151,8 +139,6 @@ void test_odb_backend_nonrefreshing__read_is_invoked_once_when_revparsing_a_full
 {
 	git_object *obj;
 
-	setup_repository_and_backend(GIT_ENOTFOUND, HASH);
-
 	cl_git_fail_with(
 		git_revparse_single(&obj, _repo, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
 		GIT_ENOTFOUND);