diff options
Diffstat (limited to 'tests/online/push.c')
-rw-r--r-- | tests/online/push.c | 260 |
1 files changed, 172 insertions, 88 deletions
diff --git a/tests/online/push.c b/tests/online/push.c index be505c3a1..6da27bb96 100644 --- a/tests/online/push.c +++ b/tests/online/push.c @@ -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++) { @@ -218,7 +219,7 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r if (!fetch_spec) continue; - cl_git_pass(git_refspec_transform_r(&ref_name, fetch_spec, expected_refs[i].name)); + cl_git_pass(git_refspec_transform(&ref_name, fetch_spec, expected_refs[i].name)); /* Find matching remote branch */ git_vector_foreach(&actual_refs, j, actual_ref) { @@ -253,8 +254,7 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r } failed: - - if(failed) + if (failed) cl_fail(git_buf_cstr(&msg)); git_vector_foreach(&actual_refs, i, actual_ref) @@ -263,7 +263,52 @@ failed: git_vector_free(&actual_refs); git_buf_free(&msg); git_buf_free(&ref_name); - return; +} + +static void verify_update_tips_callback(git_remote *remote, expected_ref expected_refs[], size_t expected_refs_len) +{ + git_refspec *fetch_spec; + git_buf msg = GIT_BUF_INIT; + git_buf ref_name = GIT_BUF_INIT; + updated_tip *tip = NULL; + size_t i, j; + int failed = 0; + + for (i = 0; i < expected_refs_len; ++i) { + /* Convert remote reference name into tracking branch name. + * If the spec is not under refs/heads/, then skip. + */ + fetch_spec = git_remote__matching_refspec(remote, expected_refs[i].name); + if (!fetch_spec) + continue; + + cl_git_pass(git_refspec_transform(&ref_name, fetch_spec, expected_refs[i].name)); + + /* Find matching update_tip entry */ + git_vector_foreach(&_record_cbs_data.updated_tips, j, tip) { + if (!strcmp(git_buf_cstr(&ref_name), tip->name)) + break; + } + + if (j == _record_cbs_data.updated_tips.length) { + git_buf_printf(&msg, "Did not find expected updated tip entry for branch '%s'.", git_buf_cstr(&ref_name)); + failed = 1; + goto failed; + } + + if (git_oid_cmp(expected_refs[i].oid, tip->new_oid) != 0) { + git_buf_printf(&msg, "Updated tip ID does not match expected ID"); + failed = 1; + goto failed; + } + } + +failed: + if (failed) + cl_fail(git_buf_cstr(&msg)); + + git_buf_free(&ref_name); + git_buf_free(&msg); } void test_online_push__initialize(void) @@ -314,46 +359,47 @@ void test_online_push__initialize(void) _remote_default = cl_getenv("GITTEST_REMOTE_DEFAULT"); _remote = NULL; - if (_remote_url) { - cl_git_pass(git_remote_create(&_remote, _repo, "test", _remote_url)); + /* Skip the test if we're missing the remote URL */ + if (!_remote_url) + cl_skip(); - record_callbacks_data_clear(&_record_cbs_data); - git_remote_set_callbacks(_remote, &_record_cbs); + cl_git_pass(git_remote_create(&_remote, _repo, "test", _remote_url)); - cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH)); + record_callbacks_data_clear(&_record_cbs_data); + git_remote_set_callbacks(_remote, &_record_cbs); - /* Clean up previously pushed branches. Fails if receive.denyDeletes is - * set on the remote. Also, on Git 1.7.0 and newer, you must run - * 'git config receive.denyDeleteCurrent ignore' in the remote repo in - * order to delete the remote branch pointed to by HEAD (usually master). - * See: https://raw.github.com/git/git/master/Documentation/RelNotes/1.7.0.txt - */ - cl_git_pass(git_remote_ls(&heads, &heads_len, _remote)); - cl_git_pass(create_deletion_refspecs(&delete_specs, heads, heads_len)); - if (delete_specs.length) { - git_push *push; + cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH)); - cl_git_pass(git_push_new(&push, _remote)); + /* Clean up previously pushed branches. Fails if receive.denyDeletes is + * set on the remote. Also, on Git 1.7.0 and newer, you must run + * 'git config receive.denyDeleteCurrent ignore' in the remote repo in + * order to delete the remote branch pointed to by HEAD (usually master). + * See: https://raw.github.com/git/git/master/Documentation/RelNotes/1.7.0.txt + */ + cl_git_pass(git_remote_ls(&heads, &heads_len, _remote)); + cl_git_pass(create_deletion_refspecs(&delete_specs, heads, heads_len)); + if (delete_specs.length) { + git_push *push; - git_vector_foreach(&delete_specs, i, curr_del_spec) { - git_push_add_refspec(push, curr_del_spec); - git__free(curr_del_spec); - } + cl_git_pass(git_push_new(&push, _remote)); - cl_git_pass(git_push_finish(push)); - git_push_free(push); + git_vector_foreach(&delete_specs, i, curr_del_spec) { + git_push_add_refspec(push, curr_del_spec); + git__free(curr_del_spec); } - git_remote_disconnect(_remote); - git_vector_free(&delete_specs); + cl_git_pass(git_push_finish(push)); + git_push_free(push); + } - /* Now that we've deleted everything, fetch from the remote */ - cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_FETCH)); - cl_git_pass(git_remote_download(_remote)); - cl_git_pass(git_remote_update_tips(_remote)); - git_remote_disconnect(_remote); - } else - printf("GITTEST_REMOTE_URL unset; skipping push test\n"); + git_remote_disconnect(_remote); + git_vector_free(&delete_specs); + + /* Now that we've deleted everything, fetch from the remote */ + cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_FETCH)); + cl_git_pass(git_remote_download(_remote)); + cl_git_pass(git_remote_update_tips(_remote, NULL, NULL)); + git_remote_disconnect(_remote); } void test_online_push__cleanup(void) @@ -371,19 +417,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,64 +449,77 @@ 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, int check_update_tips_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; + git_signature *pusher; if (_remote) { /* Auto-detect the number of threads to use */ opts.pb_parallelism = 0; + cl_git_pass(git_signature_now(&pusher, "Foo Bar", "foo@example.com")); cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH)); 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)); + cl_git_pass(git_push_update_tips(push, pusher, "test push")); verify_tracking_branches(_remote, expected_refs, expected_refs_len); + if (check_update_tips_cb) + verify_update_tips_callback(_remote, expected_refs, expected_refs_len); + git_push_free(push); git_remote_disconnect(_remote); + git_signature_free(pusher); } + } /* Call push_finish() without ever calling git_push_add_refspec() */ void test_online_push__noop(void) { - do_push(NULL, 0, NULL, 0, NULL, 0, 0, 0); + do_push(NULL, 0, NULL, 0, NULL, 0, 0, 0, 1); } void test_online_push__b1(void) @@ -464,7 +529,7 @@ void test_online_push__b1(void) expected_ref exp_refs[] = { { "refs/heads/b1", &_oid_b1 } }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); } void test_online_push__b2(void) @@ -474,7 +539,7 @@ void test_online_push__b2(void) expected_ref exp_refs[] = { { "refs/heads/b2", &_oid_b2 } }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); } void test_online_push__b3(void) @@ -484,7 +549,7 @@ void test_online_push__b3(void) expected_ref exp_refs[] = { { "refs/heads/b3", &_oid_b3 } }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); } void test_online_push__b4(void) @@ -494,7 +559,7 @@ void test_online_push__b4(void) expected_ref exp_refs[] = { { "refs/heads/b4", &_oid_b4 } }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); } void test_online_push__b5(void) @@ -504,11 +569,20 @@ void test_online_push__b5(void) expected_ref exp_refs[] = { { "refs/heads/b5", &_oid_b5 } }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 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, 1); } void test_online_push__multi(void) { + git_reflog *log; + const git_reflog_entry *entry; + const char *specs[] = { "refs/heads/b1:refs/heads/b1", "refs/heads/b2:refs/heads/b2", @@ -532,7 +606,16 @@ void test_online_push__multi(void) }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); + + cl_git_pass(git_reflog_read(&log, _repo, "refs/remotes/test/b1")); + entry = git_reflog_entry_byindex(log, 0); + if (entry) { + cl_assert_equal_s("test push", git_reflog_entry_message(entry)); + cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email); + } + + git_reflog_free(log); } void test_online_push__implicit_tgt(void) @@ -550,10 +633,10 @@ void test_online_push__implicit_tgt(void) do_push(specs1, ARRAY_SIZE(specs1), exp_stats1, ARRAY_SIZE(exp_stats1), - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1); do_push(specs2, ARRAY_SIZE(specs2), exp_stats2, ARRAY_SIZE(exp_stats2), - exp_refs2, ARRAY_SIZE(exp_refs2), 0, 0); + exp_refs2, ARRAY_SIZE(exp_refs2), 0, 0, 0); } void test_online_push__fast_fwd(void) @@ -575,19 +658,19 @@ void test_online_push__fast_fwd(void) do_push(specs_init, ARRAY_SIZE(specs_init), exp_stats_init, ARRAY_SIZE(exp_stats_init), - exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 1); + exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 1, 1); do_push(specs_ff, ARRAY_SIZE(specs_ff), exp_stats_ff, ARRAY_SIZE(exp_stats_ff), - exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0); + exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0); do_push(specs_reset, ARRAY_SIZE(specs_reset), exp_stats_init, ARRAY_SIZE(exp_stats_init), - exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 0); + exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 0, 0); do_push(specs_ff_force, ARRAY_SIZE(specs_ff_force), exp_stats_ff, ARRAY_SIZE(exp_stats_ff), - exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0); + exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0); } void test_online_push__tag_commit(void) @@ -597,7 +680,7 @@ void test_online_push__tag_commit(void) expected_ref exp_refs[] = { { "refs/tags/tag-commit", &_tag_commit } }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); } void test_online_push__tag_tree(void) @@ -607,7 +690,7 @@ void test_online_push__tag_tree(void) expected_ref exp_refs[] = { { "refs/tags/tag-tree", &_tag_tree } }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); } void test_online_push__tag_blob(void) @@ -617,7 +700,7 @@ void test_online_push__tag_blob(void) expected_ref exp_refs[] = { { "refs/tags/tag-blob", &_tag_blob } }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); } void test_online_push__tag_lightweight(void) @@ -627,7 +710,7 @@ void test_online_push__tag_lightweight(void) expected_ref exp_refs[] = { { "refs/tags/tag-lightweight", &_tag_lightweight } }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); } void test_online_push__tag_to_tag(void) @@ -637,7 +720,7 @@ void test_online_push__tag_to_tag(void) expected_ref exp_refs[] = { { "refs/tags/tag-tag", &_tag_tag } }; do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 0); + exp_refs, ARRAY_SIZE(exp_refs), 0, 0, 0); } void test_online_push__force(void) @@ -654,16 +737,17 @@ void test_online_push__force(void) do_push(specs1, ARRAY_SIZE(specs1), exp_stats1, ARRAY_SIZE(exp_stats1), - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1); do_push(specs2, ARRAY_SIZE(specs2), NULL, 0, - exp_refs1, ARRAY_SIZE(exp_refs1), GIT_ENONFASTFORWARD, 0); + exp_refs1, ARRAY_SIZE(exp_refs1), GIT_ENONFASTFORWARD, 0, 0); /* Non-fast-forward update with force should pass. */ + record_callbacks_data_clear(&_record_cbs_data); do_push(specs2_force, ARRAY_SIZE(specs2_force), exp_stats2_force, ARRAY_SIZE(exp_stats2_force), - exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0, 1); + exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0, 1, 1); } void test_online_push__delete(void) @@ -694,7 +778,7 @@ void test_online_push__delete(void) do_push(specs1, ARRAY_SIZE(specs1), exp_stats1, ARRAY_SIZE(exp_stats1), - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1); /* When deleting a non-existent branch, the git client sends zero for both * the old and new commit id. This should succeed on the server with the @@ -704,23 +788,23 @@ void test_online_push__delete(void) */ do_push(specs_del_fake, ARRAY_SIZE(specs_del_fake), exp_stats_fake, 1, - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0); do_push(specs_del_fake_force, ARRAY_SIZE(specs_del_fake_force), exp_stats_fake, 1, - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0); /* Delete one of the pushed branches. */ do_push(specs_delete, ARRAY_SIZE(specs_delete), exp_stats_delete, ARRAY_SIZE(exp_stats_delete), - exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0); + exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0); /* Re-push branches and retry delete with force. */ do_push(specs1, ARRAY_SIZE(specs1), exp_stats1, ARRAY_SIZE(exp_stats1), - exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0); + exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0); do_push(specs_delete_force, ARRAY_SIZE(specs_delete_force), exp_stats_delete, ARRAY_SIZE(exp_stats_delete), - exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0); + exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0); } void test_online_push__bad_refspecs(void) @@ -731,7 +815,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 */ @@ -754,11 +838,11 @@ void test_online_push__expressions(void) /* TODO: Find a more precise way of checking errors than a exit code of -1. */ do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr), NULL, 0, - NULL, 0, -1, 0); + NULL, 0, -1, 0, 0); do_push(specs_right_expr, ARRAY_SIZE(specs_right_expr), exp_stats_right_expr, ARRAY_SIZE(exp_stats_right_expr), - NULL, 0, 0, 1); + NULL, 0, 0, 1, 1); } void test_online_push__notes(void) @@ -778,7 +862,7 @@ void test_online_push__notes(void) do_push(specs, ARRAY_SIZE(specs), exp_stats, ARRAY_SIZE(exp_stats), - exp_refs, ARRAY_SIZE(exp_refs), 0, 1); + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); git_signature_free(signature); } |