summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/diff/iterator.c3
-rw-r--r--tests/threads/diff.c121
2 files changed, 91 insertions, 33 deletions
diff --git a/tests/diff/iterator.c b/tests/diff/iterator.c
index 19a9a0077..cdc64eb1d 100644
--- a/tests/diff/iterator.c
+++ b/tests/diff/iterator.c
@@ -363,9 +363,8 @@ static void index_iterator_test(
git_index *index;
git_iterator *i;
const git_index_entry *entry;
- int error, count = 0;
+ int error, count = 0, caps;
git_repository *repo = cl_git_sandbox_init(sandbox);
- unsigned int caps;
cl_git_pass(git_repository_index(&index, repo));
caps = git_index_caps(index);
diff --git a/tests/threads/diff.c b/tests/threads/diff.c
index 33afc58ac..7f10a699d 100644
--- a/tests/threads/diff.c
+++ b/tests/threads/diff.c
@@ -1,9 +1,10 @@
#include "clar_libgit2.h"
#include "thread-utils.h"
-static git_repository *g_repo;
-static git_tree *a, *b;
-static git_atomic counts[4];
+static git_repository *_repo;
+static git_tree *_a, *_b;
+static git_atomic _counts[4];
+static int _check_counts;
void test_threads_diff__cleanup(void)
{
@@ -24,7 +25,7 @@ static void run_in_parallel(
cl_assert(id != NULL && th != NULL);
for (r = 0; r < repeats; ++r) {
- g_repo = cl_git_sandbox_reopen(); /* reopen sandbox to flush caches */
+ _repo = cl_git_sandbox_reopen(); /* reopen sandbox to flush caches */
if (before_test) before_test();
@@ -53,24 +54,26 @@ static void run_in_parallel(
static void setup_trees(void)
{
cl_git_pass(git_revparse_single(
- (git_object **)&a, g_repo, "0017bd4ab1^{tree}"));
+ (git_object **)&_a, _repo, "0017bd4ab1^{tree}"));
cl_git_pass(git_revparse_single(
- (git_object **)&b, g_repo, "26a125ee1b^{tree}"));
+ (git_object **)&_b, _repo, "26a125ee1b^{tree}"));
- memset(counts, 0, sizeof(counts));
+ memset(_counts, 0, sizeof(_counts));
}
#define THREADS 20
static void free_trees(void)
{
- git_tree_free(a); a = NULL;
- git_tree_free(b); b = NULL;
-
- cl_assert_equal_i(288, git_atomic_get(&counts[0]));
- cl_assert_equal_i(112, git_atomic_get(&counts[1]));
- cl_assert_equal_i( 80, git_atomic_get(&counts[2]));
- cl_assert_equal_i( 96, git_atomic_get(&counts[3]));
+ git_tree_free(_a); _a = NULL;
+ git_tree_free(_b); _b = NULL;
+
+ if (_check_counts) {
+ cl_assert_equal_i(288, git_atomic_get(&_counts[0]));
+ cl_assert_equal_i(112, git_atomic_get(&_counts[1]));
+ cl_assert_equal_i( 80, git_atomic_get(&_counts[2]));
+ cl_assert_equal_i( 96, git_atomic_get(&_counts[3]));
+ }
}
static void *run_index_diffs(void *arg)
@@ -81,48 +84,41 @@ static void *run_index_diffs(void *arg)
size_t i;
int exp[4] = { 0, 0, 0, 0 };
-// fprintf(stderr, "%d >>>\n", thread);
-
switch (thread & 0x03) {
case 0: /* diff index to workdir */;
- cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+ cl_git_pass(git_diff_index_to_workdir(&diff, _repo, NULL, &opts));
break;
case 1: /* diff tree 'a' to index */;
- cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts));
+ cl_git_pass(git_diff_tree_to_index(&diff, _repo, _a, NULL, &opts));
break;
case 2: /* diff tree 'b' to index */;
- cl_git_pass(git_diff_tree_to_index(&diff, g_repo, b, NULL, &opts));
+ cl_git_pass(git_diff_tree_to_index(&diff, _repo, _b, NULL, &opts));
break;
case 3: /* diff index to workdir (explicit index) */;
{
git_index *idx;
- cl_git_pass(git_repository_index(&idx, g_repo));
- cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, idx, &opts));
+ cl_git_pass(git_repository_index(&idx, _repo));
+ cl_git_pass(git_diff_index_to_workdir(&diff, _repo, idx, &opts));
git_index_free(idx);
break;
}
}
-// fprintf(stderr, "%d <<<\n", thread);
-
/* keep some diff stats to make sure results are as expected */
i = git_diff_num_deltas(diff);
- git_atomic_add(&counts[0], (int32_t)i);
+ git_atomic_add(&_counts[0], (int32_t)i);
exp[0] = (int)i;
while (i > 0) {
switch (git_diff_get_delta(diff, --i)->status) {
- case GIT_DELTA_MODIFIED: exp[1]++; git_atomic_inc(&counts[1]); break;
- case GIT_DELTA_ADDED: exp[2]++; git_atomic_inc(&counts[2]); break;
- case GIT_DELTA_DELETED: exp[3]++; git_atomic_inc(&counts[3]); break;
+ case GIT_DELTA_MODIFIED: exp[1]++; git_atomic_inc(&_counts[1]); break;
+ case GIT_DELTA_ADDED: exp[2]++; git_atomic_inc(&_counts[2]); break;
+ case GIT_DELTA_DELETED: exp[3]++; git_atomic_inc(&_counts[3]); break;
default: break;
}
}
-// fprintf(stderr, "%2d: [%d] total %d (M %d A %d D %d)\n",
-// thread, (int)(thread & 0x03), exp[0], exp[1], exp[2], exp[3]);
-
switch (thread & 0x03) {
case 0: case 3:
cl_assert_equal_i(8, exp[0]); cl_assert_equal_i(4, exp[1]);
@@ -145,8 +141,71 @@ static void *run_index_diffs(void *arg)
void test_threads_diff__concurrent_diffs(void)
{
- g_repo = cl_git_sandbox_init("status");
+ _repo = cl_git_sandbox_init("status");
+ _check_counts = 1;
run_in_parallel(
20, 32, run_index_diffs, setup_trees, free_trees);
}
+
+static void *run_index_diffs_with_modifier(void *arg)
+{
+ int thread = *(int *)arg;
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff *diff = NULL;
+ git_index *idx = NULL;
+
+ cl_git_pass(git_repository_index(&idx, _repo));
+
+ /* have first thread altering the index as we go */
+ if (thread == 0) {
+ int i;
+
+ for (i = 0; i < 300; ++i) {
+ switch (i & 0x03) {
+ case 0: (void)git_index_add_bypath(idx, "new_file"); break;
+ case 1: (void)git_index_remove_bypath(idx, "modified_file"); break;
+ case 2: (void)git_index_remove_bypath(idx, "new_file"); break;
+ case 3: (void)git_index_add_bypath(idx, "modified_file"); break;
+ }
+ git_thread_yield();
+ }
+
+ git_index_free(idx);
+ return arg;
+ }
+
+ /* only use explicit index in this test to prevent reloading */
+
+ switch (thread & 0x03) {
+ case 0: /* diff index to workdir */;
+ cl_git_pass(git_diff_index_to_workdir(&diff, _repo, idx, &opts));
+ break;
+ case 1: /* diff tree 'a' to index */;
+ cl_git_pass(git_diff_tree_to_index(&diff, _repo, _a, idx, &opts));
+ break;
+ case 2: /* diff tree 'b' to index */;
+ cl_git_pass(git_diff_tree_to_index(&diff, _repo, _b, idx, &opts));
+ break;
+ case 3: /* diff index to workdir reversed */;
+ opts.flags |= GIT_DIFF_REVERSE;
+ cl_git_pass(git_diff_index_to_workdir(&diff, _repo, idx, &opts));
+ break;
+ }
+
+ /* results will be unpredictable with index modifier thread running */
+
+ git_diff_free(diff);
+ git_index_free(idx);
+
+ return arg;
+}
+
+void test_threads_diff__with_concurrent_index_modified(void)
+{
+ _repo = cl_git_sandbox_init("status");
+ _check_counts = 0;
+
+ run_in_parallel(
+ 20, 32, run_index_diffs_with_modifier, setup_trees, free_trees);
+}