summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-12-24 12:37:41 +0000
committerCarlos Martín Nieto <cmn@dwim.me>2016-11-14 11:25:58 +0100
commit7da4c429ea3d21e0fca0755e927f19b93e81a5c6 (patch)
tree21c8240ff24422a1f5cd9a8cafe3e8d607195652
parente1c14335d8c46fcc36e9fbe25c835455639fe339 (diff)
downloadlibgit2-7da4c429ea3d21e0fca0755e927f19b93e81a5c6.tar.gz
refdb: adjust the threading tests to what we promise
We say it's going to work if you use a different repository in each thread. Let's do precisely that in our code instead of hoping re-using the refdb is going to work. This test does fail currently, surfacing existing bugs.
-rw-r--r--tests/threads/refdb.c122
1 files changed, 44 insertions, 78 deletions
diff --git a/tests/threads/refdb.c b/tests/threads/refdb.c
index f869bcb44..9b1b37592 100644
--- a/tests/threads/refdb.c
+++ b/tests/threads/refdb.c
@@ -19,13 +19,21 @@ void test_threads_refdb__cleanup(void)
#define REPEAT 20
#define THREADS 20
+struct th_data {
+ int id;
+ const char *path;
+};
+
static void *iterate_refs(void *arg)
{
+ struct th_data *data = (struct th_data *) arg;
git_reference_iterator *i;
git_reference *ref;
int count = 0;
+ git_repository *repo;
- cl_git_pass(git_reference_iterator_new(&i, g_repo));
+ cl_git_pass(git_repository_open(&repo, data->path));
+ cl_git_pass(git_reference_iterator_new(&i, repo));
for (count = 0; !git_reference_next(&ref, i); ++count) {
cl_assert(ref != NULL);
@@ -37,77 +45,31 @@ static void *iterate_refs(void *arg)
git_reference_iterator_free(i);
+ git_repository_free(repo);
giterr_clear();
return arg;
}
-void test_threads_refdb__iterator(void)
-{
- int r, t;
- git_thread th[THREADS];
- int id[THREADS];
- git_oid head;
- git_reference *ref;
- char name[128];
- git_refdb *refdb;
-
- g_repo = cl_git_sandbox_init("testrepo2");
-
- cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD"));
-
- /* make a bunch of references */
-
- for (r = 0; r < 200; ++r) {
- p_snprintf(name, sizeof(name), "refs/heads/direct-%03d", r);
- cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL));
- git_reference_free(ref);
- }
-
- cl_git_pass(git_repository_refdb(&refdb, g_repo));
- cl_git_pass(git_refdb_compress(refdb));
- git_refdb_free(refdb);
-
- g_expected = 206;
-
- for (r = 0; r < REPEAT; ++r) {
- g_repo = cl_git_sandbox_reopen(); /* reopen to flush caches */
-
- for (t = 0; t < THREADS; ++t) {
- id[t] = t;
-#ifdef GIT_THREADS
- cl_git_pass(git_thread_create(&th[t], iterate_refs, &id[t]));
-#else
- th[t] = t;
- iterate_refs(&id[t]);
-#endif
- }
-
-#ifdef GIT_THREADS
- for (t = 0; t < THREADS; ++t) {
- cl_git_pass(git_thread_join(&th[t], NULL));
- }
-#endif
-
- memset(th, 0, sizeof(th));
- }
-}
-
static void *create_refs(void *arg)
{
- int *id = arg, i;
+ int i;
+ struct th_data *data = (struct th_data *) arg;
git_oid head;
char name[128];
git_reference *ref[10];
+ git_repository *repo;
- cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD"));
+ cl_git_pass(git_repository_open(&repo, data->path));
+
+ cl_git_pass(git_reference_name_to_id(&head, repo, "HEAD"));
for (i = 0; i < 10; ++i) {
- p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", *id, i);
- cl_git_pass(git_reference_create(&ref[i], g_repo, name, &head, 0, NULL));
+ p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", data->id, i);
+ cl_git_pass(git_reference_create(&ref[i], repo, name, &head, 0, NULL));
if (i == 5) {
git_refdb *refdb;
- cl_git_pass(git_repository_refdb(&refdb, g_repo));
+ cl_git_pass(git_repository_refdb(&refdb, repo));
cl_git_pass(git_refdb_compress(refdb));
git_refdb_free(refdb);
}
@@ -116,33 +78,40 @@ static void *create_refs(void *arg)
for (i = 0; i < 10; ++i)
git_reference_free(ref[i]);
+ git_repository_free(repo);
+
giterr_clear();
return arg;
}
static void *delete_refs(void *arg)
{
- int *id = arg, i;
+ int i;
+ struct th_data *data = (struct th_data *) arg;
git_reference *ref;
char name[128];
+ git_repository *repo;
+
+ cl_git_pass(git_repository_open(&repo, data->path));
for (i = 0; i < 10; ++i) {
p_snprintf(
- name, sizeof(name), "refs/heads/thread-%03d-%02d", (*id) & ~0x3, i);
+ name, sizeof(name), "refs/heads/thread-%03d-%02d", (data->id) & ~0x3, i);
- if (!git_reference_lookup(&ref, g_repo, name)) {
+ if (!git_reference_lookup(&ref, repo, name)) {
cl_git_pass(git_reference_delete(ref));
git_reference_free(ref);
}
if (i == 5) {
git_refdb *refdb;
- cl_git_pass(git_repository_refdb(&refdb, g_repo));
+ cl_git_pass(git_repository_refdb(&refdb, repo));
cl_git_pass(git_refdb_compress(refdb));
git_refdb_free(refdb);
}
}
+ git_repository_free(repo);
giterr_clear();
return arg;
}
@@ -150,7 +119,7 @@ static void *delete_refs(void *arg)
void test_threads_refdb__edit_while_iterate(void)
{
int r, t;
- int id[THREADS];
+ struct th_data th_data[THREADS];
git_oid head;
git_reference *ref;
char name[128];
@@ -189,29 +158,26 @@ void test_threads_refdb__edit_while_iterate(void)
default: fn = iterate_refs; break;
}
- id[t] = t;
-
- /* It appears with all reflog writing changes, etc., that this
- * test has started to fail quite frequently, so let's disable it
- * for now by just running on a single thread...
- */
-/* #ifdef GIT_THREADS */
-/* cl_git_pass(git_thread_create(&th[t], fn, &id[t])); */
-/* #else */
- fn(&id[t]);
-/* #endif */
+ th_data[t].id = t;
+ th_data[t].path = git_repository_path(g_repo);
+
+#ifdef GIT_THREADS
+ cl_git_pass(git_thread_create(&th[t], fn, &th_data[t]));
+#else
+ fn(&th_data[t]);
+#endif
}
#ifdef GIT_THREADS
-/* for (t = 0; t < THREADS; ++t) { */
-/* cl_git_pass(git_thread_join(th[t], NULL)); */
-/* } */
+ for (t = 0; t < THREADS; ++t) {
+ cl_git_pass(git_thread_join(&th[t], NULL));
+ }
memset(th, 0, sizeof(th));
for (t = 0; t < THREADS; ++t) {
- id[t] = t;
- cl_git_pass(git_thread_create(&th[t], iterate_refs, &id[t]));
+ th_data[t].id = t;
+ cl_git_pass(git_thread_create(&th[t], iterate_refs, &th_data[t]));
}
for (t = 0; t < THREADS; ++t) {