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(
const git_diff_line *line,
void *payload)
{
GIT_UNUSED(payload);
switch (line->origin) {
case GIT_DIFF_LINE_FILE_HDR:
cl_assert_equal_s(EXPECTED_HEADER, line->content);
......@@ -40,10 +38,12 @@ static int check_removal_cb(
case GIT_DIFF_LINE_HUNK_HDR:
cl_assert_equal_s(EXPECTED_HUNK, line->content);
/* Fall through */
goto check_hunk;
case GIT_DIFF_LINE_CONTEXT:
case GIT_DIFF_LINE_DELETION:
if (payload != NULL)
return *(int *)payload;
goto check_hunk;
default:
......@@ -101,6 +101,39 @@ void test_diff_patch__can_properly_display_the_removal_of_a_file(void)
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)
{
const char *one_sha = "26a125e";
......
......@@ -207,6 +207,7 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r
}
cl_assert_equal_i(error, GIT_ITEROVER);
git_branch_iterator_free(iter);
/* Loop through expected refs, make sure they exist */
for (i = 0; i < expected_refs_len; i++) {
......@@ -371,19 +372,25 @@ void test_online_push__cleanup(void)
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);
*was_called = 1;
if (*calls < 0)
return *calls;
(*calls)++;
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);
*was_called = 1;
if (*calls < 0)
return *calls;
(*calls)++;
return 0;
}
......@@ -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 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,
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_options opts = GIT_PUSH_OPTIONS_INIT;
size_t i;
int ret;
int pack_progress_called = 0, transfer_progress_called = 0;
int pack_progress_calls = 0, transfer_progress_calls = 0;
if (_remote) {
/* Auto-detect the number of threads to use */
......@@ -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_set_options(push, &opts));
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 (check_progress_cb) {
/* 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++)
cl_git_pass(git_push_add_refspec(push, refspecs[i]));
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));
}
else {
cl_git_pass(ret = git_push_finish(push));
} else {
cl_git_pass(git_push_finish(push));
cl_assert_equal_i(1, git_push_unpack_ok(push));
}
if (check_progress_cb) {
cl_assert_equal_i(1, pack_progress_called);
cl_assert_equal_i(1, transfer_progress_called);
if (check_progress_cb && !expected_ret) {
cl_assert(pack_progress_calls > 0);
cl_assert(transfer_progress_calls > 0);
}
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);
cl_git_pass(git_push_update_tips(push));
......@@ -507,6 +520,12 @@ void test_online_push__b5(void)
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)
{
const char *specs[] = {
......@@ -731,7 +750,7 @@ void test_online_push__bad_refspecs(void)
git_push *push;
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));
/* Unexpanded branch names not supported */
......
......@@ -46,36 +46,43 @@ static int refcmp_cb(const void *a, const void *b)
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)
{
git_reference_iterator *iter;
git_vector output;
git_reference *ref;
int error;
size_t i;
cl_git_pass(git_vector_init(&output, 32, &refcmp_cb));
cl_git_pass(git_reference_iterator_new(&iter, repo));
do {
error = git_reference_next(&ref, iter);
cl_assert(error == 0 || error == GIT_ITEROVER);
if (error != GIT_ITEROVER) {
cl_git_pass(git_vector_insert(&output, ref));
}
} while (!error);
while (1) {
int error = git_reference_next(&ref, iter);
if (error == GIT_ITEROVER)
break;
cl_git_pass(error);
cl_git_pass(git_vector_insert(&output, ref));
}
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)
......@@ -95,3 +102,87 @@ void test_refs_iterator__empty(void)
git_odb_free(odb);
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