mirror of
https://git.proxmox.com/git/libgit2
synced 2026-01-20 18:16:40 +00:00
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.
This commit is contained in:
parent
7e3ed41959
commit
11bd7a034b
@ -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);
|
||||
|
||||
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);
|
||||
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_vector_free(&output);
|
||||
git_reference_iterator_free(iter);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user