summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/odb.c6
-rw-r--r--tests-clar/odb/backend/nonrefreshing.c261
2 files changed, 264 insertions, 3 deletions
diff --git a/src/odb.c b/src/odb.c
index 21b46bf56..9785c74da 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -622,7 +622,7 @@ attempt_lookup:
backend_internal *internal = git_vector_get(&db->backends, i);
git_odb_backend *b = internal->backend;
- if (b->exists != NULL)
+ if (b->exists != NULL && (!refreshed || b->refresh))
found = b->exists(b, id);
}
@@ -717,7 +717,7 @@ attempt_lookup:
backend_internal *internal = git_vector_get(&db->backends, i);
git_odb_backend *b = internal->backend;
- if (b->read != NULL) {
+ if (b->read != NULL && (!refreshed || b->refresh)) {
++reads;
error = b->read(&raw.data, &raw.len, &raw.type, b, id);
}
@@ -774,7 +774,7 @@ attempt_lookup:
backend_internal *internal = git_vector_get(&db->backends, i);
git_odb_backend *b = internal->backend;
- if (b->read_prefix != NULL) {
+ if (b->read_prefix != NULL && (!refreshed || b->refresh)) {
git_oid full_oid;
error = b->read_prefix(&full_oid, &raw.data, &raw.len, &raw.type, b, short_id, len);
if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
diff --git a/tests-clar/odb/backend/nonrefreshing.c b/tests-clar/odb/backend/nonrefreshing.c
new file mode 100644
index 000000000..abb824d4b
--- /dev/null
+++ b/tests-clar/odb/backend/nonrefreshing.c
@@ -0,0 +1,261 @@
+#include "clar_libgit2.h"
+#include "git2/sys/odb_backend.h"
+#include "repository.h"
+
+typedef struct fake_backend {
+ git_odb_backend parent;
+
+ git_error_code error_code;
+
+ int exists_calls;
+ int read_calls;
+ int read_header_calls;
+ int read_prefix_calls;
+} fake_backend;
+
+static git_repository *_repo;
+static fake_backend *_fake;
+static git_oid _oid;
+
+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);
+}
+
+static int fake_backend__read(
+ void **buffer_p, size_t *len_p, git_otype *type_p,
+ git_odb_backend *backend, const git_oid *oid)
+{
+ 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;
+
+ return fake->error_code;
+}
+
+static int fake_backend__read_header(
+ size_t *len_p, git_otype *type_p,
+ git_odb_backend *backend, const git_oid *oid)
+{
+ 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;
+
+ return fake->error_code;
+}
+
+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)
+{
+ fake_backend *fake;
+
+ GIT_UNUSED(out_oid);
+ 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++;
+
+ *len_p = 0;
+ *buffer_p = NULL;
+ *type_p = GIT_OBJ_BLOB;
+
+ return fake->error_code;
+}
+
+static void fake_backend__free(git_odb_backend *_backend)
+{
+ fake_backend *backend;
+
+ backend = (fake_backend *)_backend;
+
+ git__free(backend);
+}
+
+static int build_fake_backend(
+ git_odb_backend **out,
+ git_error_code error_code)
+{
+ fake_backend *backend;
+
+ backend = git__calloc(1, sizeof(fake_backend));
+ GITERR_CHECK_ALLOC(backend);
+
+ backend->parent.version = GIT_ODB_BACKEND_VERSION;
+
+ backend->parent.refresh = NULL;
+ backend->error_code = error_code;
+
+ backend->parent.read = fake_backend__read;
+ backend->parent.read_prefix = fake_backend__read_prefix;
+ backend->parent.read_header = fake_backend__read_header;
+ backend->parent.exists = fake_backend__exists;
+ backend->parent.free = &fake_backend__free;
+
+ *out = (git_odb_backend *)backend;
+
+ return 0;
+}
+
+static void setup_repository_and_backend(git_error_code error_code)
+{
+ git_odb *odb;
+ git_odb_backend *backend;
+
+ _repo = cl_git_sandbox_init("testrepo.git");
+
+ cl_git_pass(build_fake_backend(&backend, error_code));
+
+ cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
+ cl_git_pass(git_odb_add_backend(odb, backend, 10));
+
+ _fake = (fake_backend *)backend;
+
+ cl_git_pass(git_oid_fromstr(&_oid, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
+}
+
+void test_odb_backend_nonrefreshing__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+}
+
+void test_odb_backend_nonrefreshing__exists_is_invoked_once_on_failure(void)
+{
+ git_odb *odb;
+
+ setup_repository_and_backend(GIT_ENOTFOUND);
+
+ cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
+ cl_assert_equal_b(false, git_odb_exists(odb, &_oid));
+
+ cl_assert_equal_i(1, _fake->exists_calls);
+}
+
+void test_odb_backend_nonrefreshing__read_is_invoked_once_on_failure(void)
+{
+ git_object *obj;
+
+ setup_repository_and_backend(GIT_ENOTFOUND);
+
+ cl_git_fail_with(
+ git_object_lookup(&obj, _repo, &_oid, GIT_OBJ_ANY),
+ GIT_ENOTFOUND);
+
+ cl_assert_equal_i(1, _fake->read_calls);
+}
+
+void test_odb_backend_nonrefreshing__readprefix_is_invoked_once_on_failure(void)
+{
+ git_object *obj;
+
+ setup_repository_and_backend(GIT_ENOTFOUND);
+
+ cl_git_fail_with(
+ git_object_lookup_prefix(&obj, _repo, &_oid, 7, GIT_OBJ_ANY),
+ GIT_ENOTFOUND);
+
+ cl_assert_equal_i(1, _fake->read_prefix_calls);
+}
+
+void test_odb_backend_nonrefreshing__readheader_is_invoked_once_on_failure(void)
+{
+ git_odb *odb;
+ size_t len;
+ git_otype type;
+
+ setup_repository_and_backend(GIT_ENOTFOUND);
+
+ cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
+
+ cl_git_fail_with(
+ git_odb_read_header(&len, &type, odb, &_oid),
+ GIT_ENOTFOUND);
+
+ cl_assert_equal_i(1, _fake->read_header_calls);
+}
+
+void test_odb_backend_nonrefreshing__exists_is_invoked_once_on_success(void)
+{
+ git_odb *odb;
+
+ setup_repository_and_backend(GIT_OK);
+
+ cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
+ cl_assert_equal_b(true, git_odb_exists(odb, &_oid));
+
+ cl_assert_equal_i(1, _fake->exists_calls);
+}
+
+void test_odb_backend_nonrefreshing__read_is_invoked_once_on_success(void)
+{
+ git_object *obj;
+
+ setup_repository_and_backend(GIT_OK);
+
+ cl_git_pass(git_object_lookup(&obj, _repo, &_oid, GIT_OBJ_ANY));
+
+ cl_assert_equal_i(1, _fake->read_calls);
+
+ git_object_free(obj);
+}
+
+void test_odb_backend_nonrefreshing__readprefix_is_invoked_once_on_success(void)
+{
+ git_object *obj;
+
+ setup_repository_and_backend(GIT_OK);
+
+ cl_git_pass(git_object_lookup_prefix(&obj, _repo, &_oid, 7, GIT_OBJ_ANY));
+
+ cl_assert_equal_i(1, _fake->read_prefix_calls);
+
+ git_object_free(obj);
+}
+
+void test_odb_backend_nonrefreshing__readheader_is_invoked_once_on_success(void)
+{
+ git_odb *odb;
+ size_t len;
+ git_otype type;
+
+ setup_repository_and_backend(GIT_OK);
+
+ cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
+
+ cl_git_pass(git_odb_read_header(&len, &type, odb, &_oid));
+
+ cl_assert_equal_i(1, _fake->read_header_calls);
+}