Commit 11bd7a03 by Russell Belfer

More tests of canceling from callbacks

This covers diff print, push, and ref foreach.  This also has a
fix for a small memory leak in the push tests.
parent 7e3ed419
...@@ -30,8 +30,6 @@ static int check_removal_cb( ...@@ -30,8 +30,6 @@ static int check_removal_cb(
const git_diff_line *line, const git_diff_line *line,
void *payload) void *payload)
{ {
GIT_UNUSED(payload);
switch (line->origin) { switch (line->origin) {
case GIT_DIFF_LINE_FILE_HDR: case GIT_DIFF_LINE_FILE_HDR:
cl_assert_equal_s(EXPECTED_HEADER, line->content); cl_assert_equal_s(EXPECTED_HEADER, line->content);
...@@ -40,10 +38,12 @@ static int check_removal_cb( ...@@ -40,10 +38,12 @@ static int check_removal_cb(
case GIT_DIFF_LINE_HUNK_HDR: case GIT_DIFF_LINE_HUNK_HDR:
cl_assert_equal_s(EXPECTED_HUNK, line->content); cl_assert_equal_s(EXPECTED_HUNK, line->content);
/* Fall through */ goto check_hunk;
case GIT_DIFF_LINE_CONTEXT: case GIT_DIFF_LINE_CONTEXT:
case GIT_DIFF_LINE_DELETION: case GIT_DIFF_LINE_DELETION:
if (payload != NULL)
return *(int *)payload;
goto check_hunk; goto check_hunk;
default: default:
...@@ -101,6 +101,39 @@ void test_diff_patch__can_properly_display_the_removal_of_a_file(void) ...@@ -101,6 +101,39 @@ void test_diff_patch__can_properly_display_the_removal_of_a_file(void)
git_tree_free(one); git_tree_free(one);
} }
void test_diff_patch__can_cancel_diff_print(void)
{
const char *one_sha = "26a125e";
const char *another_sha = "735b6a2";
git_tree *one, *another;
git_diff *diff;
int fail_with;
g_repo = cl_git_sandbox_init("status");
one = resolve_commit_oid_to_tree(g_repo, one_sha);
another = resolve_commit_oid_to_tree(g_repo, another_sha);
cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, one, another, NULL));
fail_with = -2323;
cl_git_fail_with(git_diff_print(
diff, GIT_DIFF_FORMAT_PATCH, check_removal_cb, &fail_with),
fail_with);
fail_with = 45;
cl_git_fail_with(git_diff_print(
diff, GIT_DIFF_FORMAT_PATCH, check_removal_cb, &fail_with),
fail_with);
git_diff_free(diff);
git_tree_free(another);
git_tree_free(one);
}
void test_diff_patch__to_string(void) void test_diff_patch__to_string(void)
{ {
const char *one_sha = "26a125e"; const char *one_sha = "26a125e";
......
...@@ -207,6 +207,7 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r ...@@ -207,6 +207,7 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r
} }
cl_assert_equal_i(error, GIT_ITEROVER); cl_assert_equal_i(error, GIT_ITEROVER);
git_branch_iterator_free(iter);
/* Loop through expected refs, make sure they exist */ /* Loop through expected refs, make sure they exist */
for (i = 0; i < expected_refs_len; i++) { for (i = 0; i < expected_refs_len; i++) {
...@@ -371,19 +372,25 @@ void test_online_push__cleanup(void) ...@@ -371,19 +372,25 @@ void test_online_push__cleanup(void)
cl_git_sandbox_cleanup(); cl_git_sandbox_cleanup();
} }
static int push_pack_progress_cb(int stage, unsigned int current, unsigned int total, void* payload) static int push_pack_progress_cb(
int stage, unsigned int current, unsigned int total, void* payload)
{ {
int *was_called = (int *) payload; int *calls = (int *)payload;
GIT_UNUSED(stage); GIT_UNUSED(current); GIT_UNUSED(total); GIT_UNUSED(stage); GIT_UNUSED(current); GIT_UNUSED(total);
*was_called = 1; if (*calls < 0)
return *calls;
(*calls)++;
return 0; return 0;
} }
static int push_transfer_progress_cb(unsigned int current, unsigned int total, size_t bytes, void* payload) static int push_transfer_progress_cb(
unsigned int current, unsigned int total, size_t bytes, void* payload)
{ {
int *was_called = (int *) payload; int *calls = (int *)payload;
GIT_UNUSED(current); GIT_UNUSED(total); GIT_UNUSED(bytes); GIT_UNUSED(current); GIT_UNUSED(total); GIT_UNUSED(bytes);
*was_called = 1; if (*calls < 0)
return *calls;
(*calls)++;
return 0; return 0;
} }
...@@ -397,15 +404,16 @@ static int push_transfer_progress_cb(unsigned int current, unsigned int total, s ...@@ -397,15 +404,16 @@ static int push_transfer_progress_cb(unsigned int current, unsigned int total, s
* @param expected_ret expected return value from git_push_finish() * @param expected_ret expected return value from git_push_finish()
* @param check_progress_cb Check that the push progress callbacks are called * @param check_progress_cb Check that the push progress callbacks are called
*/ */
static void do_push(const char *refspecs[], size_t refspecs_len, static void do_push(
const char *refspecs[], size_t refspecs_len,
push_status expected_statuses[], size_t expected_statuses_len, push_status expected_statuses[], size_t expected_statuses_len,
expected_ref expected_refs[], size_t expected_refs_len, int expected_ret, int check_progress_cb) expected_ref expected_refs[], size_t expected_refs_len,
int expected_ret, int check_progress_cb)
{ {
git_push *push; git_push *push;
git_push_options opts = GIT_PUSH_OPTIONS_INIT; git_push_options opts = GIT_PUSH_OPTIONS_INIT;
size_t i; size_t i;
int ret; int pack_progress_calls = 0, transfer_progress_calls = 0;
int pack_progress_called = 0, transfer_progress_called = 0;
if (_remote) { if (_remote) {
/* Auto-detect the number of threads to use */ /* Auto-detect the number of threads to use */
...@@ -416,30 +424,35 @@ static void do_push(const char *refspecs[], size_t refspecs_len, ...@@ -416,30 +424,35 @@ static void do_push(const char *refspecs[], size_t refspecs_len,
cl_git_pass(git_push_new(&push, _remote)); cl_git_pass(git_push_new(&push, _remote));
cl_git_pass(git_push_set_options(push, &opts)); cl_git_pass(git_push_set_options(push, &opts));
if (check_progress_cb) if (check_progress_cb) {
cl_git_pass(git_push_set_callbacks(push, push_pack_progress_cb, &pack_progress_called, push_transfer_progress_cb, &transfer_progress_called)); /* if EUSER, then abort in transfer */
if (expected_ret == GIT_EUSER)
transfer_progress_calls = GIT_EUSER;
cl_git_pass(
git_push_set_callbacks(
push, push_pack_progress_cb, &pack_progress_calls,
push_transfer_progress_cb, &transfer_progress_calls));
}
for (i = 0; i < refspecs_len; i++) for (i = 0; i < refspecs_len; i++)
cl_git_pass(git_push_add_refspec(push, refspecs[i])); cl_git_pass(git_push_add_refspec(push, refspecs[i]));
if (expected_ret < 0) { if (expected_ret < 0) {
cl_git_fail(ret = git_push_finish(push)); cl_git_fail_with(git_push_finish(push), expected_ret);
cl_assert_equal_i(0, git_push_unpack_ok(push)); cl_assert_equal_i(0, git_push_unpack_ok(push));
} } else {
else { cl_git_pass(git_push_finish(push));
cl_git_pass(ret = git_push_finish(push));
cl_assert_equal_i(1, git_push_unpack_ok(push)); cl_assert_equal_i(1, git_push_unpack_ok(push));
} }
if (check_progress_cb) { if (check_progress_cb && !expected_ret) {
cl_assert_equal_i(1, pack_progress_called); cl_assert(pack_progress_calls > 0);
cl_assert_equal_i(1, transfer_progress_called); cl_assert(transfer_progress_calls > 0);
} }
do_verify_push_status(push, expected_statuses, expected_statuses_len); do_verify_push_status(push, expected_statuses, expected_statuses_len);
cl_assert_equal_i(expected_ret, ret);
verify_refs(_remote, expected_refs, expected_refs_len); verify_refs(_remote, expected_refs, expected_refs_len);
cl_git_pass(git_push_update_tips(push)); cl_git_pass(git_push_update_tips(push));
...@@ -507,6 +520,12 @@ void test_online_push__b5(void) ...@@ -507,6 +520,12 @@ void test_online_push__b5(void)
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1);
} }
void test_online_push__b5_cancel(void)
{
const char *specs[] = { "refs/heads/b5:refs/heads/b5" };
do_push(specs, ARRAY_SIZE(specs), NULL, 0, NULL, 0, GIT_EUSER, 1);
}
void test_online_push__multi(void) void test_online_push__multi(void)
{ {
const char *specs[] = { const char *specs[] = {
...@@ -731,7 +750,7 @@ void test_online_push__bad_refspecs(void) ...@@ -731,7 +750,7 @@ void test_online_push__bad_refspecs(void)
git_push *push; git_push *push;
if (_remote) { if (_remote) {
// cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH)); /* cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH)); */
cl_git_pass(git_push_new(&push, _remote)); cl_git_pass(git_push_new(&push, _remote));
/* Unexpanded branch names not supported */ /* Unexpanded branch names not supported */
......
...@@ -46,36 +46,43 @@ static int refcmp_cb(const void *a, const void *b) ...@@ -46,36 +46,43 @@ static int refcmp_cb(const void *a, const void *b)
return strcmp(refa->name, refb->name); return strcmp(refa->name, refb->name);
} }
static void assert_all_refnames_match(git_vector *output)
{
size_t i;
git_reference *ref;
cl_assert_equal_sz(output->length, ARRAY_SIZE(refnames));
git_vector_sort(output);
git_vector_foreach(output, i, ref) {
cl_assert_equal_s(ref->name, refnames[i]);
git_reference_free(ref);
}
git_vector_free(output);
}
void test_refs_iterator__list(void) void test_refs_iterator__list(void)
{ {
git_reference_iterator *iter; git_reference_iterator *iter;
git_vector output; git_vector output;
git_reference *ref; git_reference *ref;
int error;
size_t i;
cl_git_pass(git_vector_init(&output, 32, &refcmp_cb)); cl_git_pass(git_vector_init(&output, 32, &refcmp_cb));
cl_git_pass(git_reference_iterator_new(&iter, repo)); cl_git_pass(git_reference_iterator_new(&iter, repo));
do { while (1) {
error = git_reference_next(&ref, iter); int error = git_reference_next(&ref, iter);
cl_assert(error == 0 || error == GIT_ITEROVER); if (error == GIT_ITEROVER)
if (error != GIT_ITEROVER) { break;
cl_git_pass(error);
cl_git_pass(git_vector_insert(&output, ref)); cl_git_pass(git_vector_insert(&output, ref));
} }
} while (!error);
git_reference_iterator_free(iter); git_reference_iterator_free(iter);
cl_assert_equal_sz(output.length, ARRAY_SIZE(refnames));
git_vector_sort(&output);
git_vector_foreach(&output, i, ref) {
cl_assert_equal_s(ref->name, refnames[i]);
git_reference_free(ref);
}
git_vector_free(&output); assert_all_refnames_match(&output);
} }
void test_refs_iterator__empty(void) void test_refs_iterator__empty(void)
...@@ -95,3 +102,87 @@ void test_refs_iterator__empty(void) ...@@ -95,3 +102,87 @@ void test_refs_iterator__empty(void)
git_odb_free(odb); git_odb_free(odb);
git_repository_free(empty); git_repository_free(empty);
} }
static int refs_foreach_cb(git_reference *reference, void *payload)
{
git_vector *output = payload;
cl_git_pass(git_vector_insert(output, reference));
return 0;
}
void test_refs_iterator__foreach(void)
{
git_vector output;
cl_git_pass(git_vector_init(&output, 32, &refcmp_cb));
cl_git_pass(git_reference_foreach(repo, refs_foreach_cb, &output));
assert_all_refnames_match(&output);
}
static int refs_foreach_cancel_cb(git_reference *reference, void *payload)
{
int *cancel_after = payload;
git_reference_free(reference);
if (!*cancel_after)
return -333;
(*cancel_after)--;
return 0;
}
void test_refs_iterator__foreach_can_cancel(void)
{
int cancel_after = 3;
cl_git_fail_with(
git_reference_foreach(repo, refs_foreach_cancel_cb, &cancel_after),
-333);
cl_assert_equal_i(0, cancel_after);
}
static int refs_foreach_name_cb(const char *name, void *payload)
{
git_vector *output = payload;
cl_git_pass(git_vector_insert(output, git__strdup(name)));
return 0;
}
void test_refs_iterator__foreach_name(void)
{
git_vector output;
size_t i;
char *name;
cl_git_pass(git_vector_init(&output, 32, &git__strcmp_cb));
cl_git_pass(
git_reference_foreach_name(repo, refs_foreach_name_cb, &output));
cl_assert_equal_sz(output.length, ARRAY_SIZE(refnames));
git_vector_sort(&output);
git_vector_foreach(&output, i, name) {
cl_assert_equal_s(name, refnames[i]);
git__free(name);
}
git_vector_free(&output);
}
static int refs_foreach_name_cancel_cb(const char *name, void *payload)
{
int *cancel_after = payload;
if (!*cancel_after)
return -333;
GIT_UNUSED(name);
(*cancel_after)--;
return 0;
}
void test_refs_iterator__foreach_name_can_cancel(void)
{
int cancel_after = 5;
cl_git_fail_with(
git_reference_foreach_name(
repo, refs_foreach_name_cancel_cb, &cancel_after),
-333);
cl_assert_equal_i(0, cancel_after);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment