]> git.proxmox.com Git - libgit2.git/blame - tests-clar/online/push.c
Fix gen_pktline format specifier for Win32
[libgit2.git] / tests-clar / online / push.c
CommitLineData
613d5eb9
PK
1#include "clar_libgit2.h"
2#include "buffer.h"
3#include "posix.h"
4#include "vector.h"
5#include "../submodule/submodule_helpers.h"
6#include "push_util.h"
7
613d5eb9
PK
8static git_repository *_repo;
9
10static char *_remote_url;
11static char *_remote_user;
12static char *_remote_pass;
13
14static git_remote *_remote;
15static record_callbacks_data _record_cbs_data = {{ 0 }};
16static git_remote_callbacks _record_cbs = RECORD_CALLBACKS_INIT(&_record_cbs_data);
17
18static git_oid _oid_b6;
19static git_oid _oid_b5;
20static git_oid _oid_b4;
21static git_oid _oid_b3;
22static git_oid _oid_b2;
23static git_oid _oid_b1;
24
abeefbbe
MS
25static git_oid _tag_commit;
26static git_oid _tag_tree;
27static git_oid _tag_blob;
28static git_oid _tag_lightweight;
29
59bccf33 30static int cred_acquire_cb(git_cred **cred, const char *url, unsigned int allowed_types, void *payload)
613d5eb9
PK
31{
32 GIT_UNUSED(url);
33
59bccf33
BS
34 *((bool*)payload) = true;
35
613d5eb9
PK
36 if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 ||
37 git_cred_userpass_plaintext_new(cred, _remote_user, _remote_pass) < 0)
38 return -1;
39
40 return 0;
41}
42
43typedef struct {
44 const char *ref;
45 const char *msg;
46} push_status;
47
48/**
49 * git_push_status_foreach callback that records status entries.
50 * @param data (git_vector *) of push_status instances
51 */
52static int record_push_status_cb(const char *ref, const char *msg, void *data)
53{
54 git_vector *statuses = (git_vector *)data;
55 push_status *s;
56
57 cl_assert(s = git__malloc(sizeof(*s)));
58 s->ref = ref;
59 s->msg = msg;
60
61 git_vector_insert(statuses, s);
62
63 return 0;
64}
65
66static void do_verify_push_status(git_push *push, const push_status expected[], const size_t expected_len)
67{
68 git_vector actual = GIT_VECTOR_INIT;
69 push_status *iter;
70 bool failed = false;
71 size_t i;
72
73 git_push_status_foreach(push, record_push_status_cb, &actual);
74
75 if (expected_len != actual.length)
76 failed = true;
77 else
78 git_vector_foreach(&actual, i, iter)
79 if (strcmp(expected[i].ref, iter->ref) ||
80 (expected[i].msg && strcmp(expected[i].msg, iter->msg))) {
81 failed = true;
82 break;
83 }
84
85 if (failed) {
86 git_buf msg = GIT_BUF_INIT;
87
88 git_buf_puts(&msg, "Expected and actual push statuses differ:\nEXPECTED:\n");
89
90 for(i = 0; i < expected_len; i++) {
91 git_buf_printf(&msg, "%s: %s\n",
92 expected[i].ref,
93 expected[i].msg ? expected[i].msg : "<NULL>");
94 }
95
96 git_buf_puts(&msg, "\nACTUAL:\n");
97
98 git_vector_foreach(&actual, i, iter)
99 git_buf_printf(&msg, "%s: %s\n", iter->ref, iter->msg);
100
101 cl_fail(git_buf_cstr(&msg));
102
103 git_buf_free(&msg);
104 }
105
106 git_vector_foreach(&actual, i, iter)
107 git__free(iter);
108
109 git_vector_free(&actual);
110}
111
112/**
113 * Verifies that after git_push_finish(), refs on a remote have the expected
114 * names, oids, and order.
156cfec0 115 *
613d5eb9
PK
116 * @param remote remote to verify
117 * @param expected_refs expected remote refs after push
118 * @param expected_refs_len length of expected_refs
119 */
120static void verify_refs(git_remote *remote, expected_ref expected_refs[], size_t expected_refs_len)
121{
122 git_vector actual_refs = GIT_VECTOR_INIT;
123
124 git_remote_ls(remote, record_ref_cb, &actual_refs);
125 verify_remote_refs(&actual_refs, expected_refs, expected_refs_len);
126
127 git_vector_free(&actual_refs);
128}
129
6443eaf2 130void test_online_push__initialize(void)
613d5eb9
PK
131{
132 git_vector delete_specs = GIT_VECTOR_INIT;
133 size_t i;
134 char *curr_del_spec;
59bccf33 135 bool cred_acquire_called = false;
613d5eb9
PK
136
137 _repo = cl_git_sandbox_init("push_src");
138
139 cl_fixture_sandbox("testrepo.git");
140 cl_rename("push_src/submodule/.gitted", "push_src/submodule/.git");
141
142 rewrite_gitmodules(git_repository_workdir(_repo));
143
144 /* git log --format=oneline --decorate --graph
145 * *-. 951bbbb90e2259a4c8950db78946784fb53fcbce (HEAD, b6) merge b3, b4, and b5 to b6
146 * |\ \
147 * | | * fa38b91f199934685819bea316186d8b008c52a2 (b5) added submodule named 'submodule' pointing to '../testrepo.git'
148 * | * | 27b7ce66243eb1403862d05f958c002312df173d (b4) edited fold\b.txt
149 * | |/
150 * * | d9b63a88223d8367516f50bd131a5f7349b7f3e4 (b3) edited a.txt
151 * |/
152 * * a78705c3b2725f931d3ee05348d83cc26700f247 (b2, b1) added fold and fold/b.txt
153 * * 5c0bb3d1b9449d1cc69d7519fd05166f01840915 added a.txt
154 */
155 git_oid_fromstr(&_oid_b6, "951bbbb90e2259a4c8950db78946784fb53fcbce");
156 git_oid_fromstr(&_oid_b5, "fa38b91f199934685819bea316186d8b008c52a2");
157 git_oid_fromstr(&_oid_b4, "27b7ce66243eb1403862d05f958c002312df173d");
158 git_oid_fromstr(&_oid_b3, "d9b63a88223d8367516f50bd131a5f7349b7f3e4");
159 git_oid_fromstr(&_oid_b2, "a78705c3b2725f931d3ee05348d83cc26700f247");
160 git_oid_fromstr(&_oid_b1, "a78705c3b2725f931d3ee05348d83cc26700f247");
161
abeefbbe
MS
162 git_oid_fromstr(&_tag_commit, "805c54522e614f29f70d2413a0470247d8b424ac");
163 git_oid_fromstr(&_tag_tree, "ff83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e");
164 git_oid_fromstr(&_tag_blob, "b483ae7ba66decee9aee971f501221dea84b1498");
165 git_oid_fromstr(&_tag_lightweight, "951bbbb90e2259a4c8950db78946784fb53fcbce");
166
613d5eb9
PK
167 /* Remote URL environment variable must be set. User and password are optional. */
168 _remote_url = cl_getenv("GITTEST_REMOTE_URL");
169 _remote_user = cl_getenv("GITTEST_REMOTE_USER");
170 _remote_pass = cl_getenv("GITTEST_REMOTE_PASS");
171 _remote = NULL;
172
173 if (_remote_url) {
29f27599 174 cl_git_pass(git_remote_create(&_remote, _repo, "test", _remote_url));
613d5eb9 175
59bccf33 176 git_remote_set_cred_acquire_cb(_remote, cred_acquire_cb, &cred_acquire_called);
613d5eb9
PK
177 record_callbacks_data_clear(&_record_cbs_data);
178 git_remote_set_callbacks(_remote, &_record_cbs);
179
180 cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH));
181
182 /* Clean up previously pushed branches. Fails if receive.denyDeletes is
183 * set on the remote. Also, on Git 1.7.0 and newer, you must run
184 * 'git config receive.denyDeleteCurrent ignore' in the remote repo in
185 * order to delete the remote branch pointed to by HEAD (usually master).
186 * See: https://raw.github.com/git/git/master/Documentation/RelNotes/1.7.0.txt
187 */
188 cl_git_pass(git_remote_ls(_remote, delete_ref_cb, &delete_specs));
189 if (delete_specs.length) {
190 git_push *push;
191
192 cl_git_pass(git_push_new(&push, _remote));
193
194 git_vector_foreach(&delete_specs, i, curr_del_spec) {
195 git_push_add_refspec(push, curr_del_spec);
196 git__free(curr_del_spec);
197 }
198
199 cl_git_pass(git_push_finish(push));
200 git_push_free(push);
201 }
202
203 git_remote_disconnect(_remote);
204 git_vector_free(&delete_specs);
205
206 /* Now that we've deleted everything, fetch from the remote */
207 cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_FETCH));
208 cl_git_pass(git_remote_download(_remote, NULL, NULL));
209 cl_git_pass(git_remote_update_tips(_remote));
210 git_remote_disconnect(_remote);
211 } else
212 printf("GITTEST_REMOTE_URL unset; skipping push test\n");
213}
214
6443eaf2 215void test_online_push__cleanup(void)
613d5eb9
PK
216{
217 if (_remote)
218 git_remote_free(_remote);
c4e3e797
BS
219 _remote = NULL;
220
221 /* Freed by cl_git_sandbox_cleanup */
222 _repo = NULL;
613d5eb9
PK
223
224 record_callbacks_data_clear(&_record_cbs_data);
225
226 cl_fixture_cleanup("testrepo.git");
227 cl_git_sandbox_cleanup();
228}
229
230/**
231 * Calls push and relists refs on remote to verify success.
156cfec0 232 *
613d5eb9
PK
233 * @param refspecs refspecs to push
234 * @param refspecs_len length of refspecs
235 * @param expected_refs expected remote refs after push
236 * @param expected_refs_len length of expected_refs
237 * @param expected_ret expected return value from git_push_finish()
238 */
239static void do_push(const char *refspecs[], size_t refspecs_len,
240 push_status expected_statuses[], size_t expected_statuses_len,
241 expected_ref expected_refs[], size_t expected_refs_len, int expected_ret)
242{
243 git_push *push;
244 size_t i;
245 int ret;
246
247 if (_remote) {
248 cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH));
249
250 cl_git_pass(git_push_new(&push, _remote));
251
252 for (i = 0; i < refspecs_len; i++)
253 cl_git_pass(git_push_add_refspec(push, refspecs[i]));
254
255 if (expected_ret < 0) {
256 cl_git_fail(ret = git_push_finish(push));
257 cl_assert_equal_i(0, git_push_unpack_ok(push));
258 }
259 else {
260 cl_git_pass(ret = git_push_finish(push));
261 cl_assert_equal_i(1, git_push_unpack_ok(push));
262 }
263
264 do_verify_push_status(push, expected_statuses, expected_statuses_len);
265
266 cl_assert_equal_i(expected_ret, ret);
267
268 git_push_free(push);
269
270 verify_refs(_remote, expected_refs, expected_refs_len);
271
272 cl_git_pass(git_remote_update_tips(_remote));
273
274 git_remote_disconnect(_remote);
275 }
276}
277
278/* Call push_finish() without ever calling git_push_add_refspec() */
6443eaf2 279void test_online_push__noop(void)
613d5eb9
PK
280{
281 do_push(NULL, 0, NULL, 0, NULL, 0, 0);
282}
283
6443eaf2 284void test_online_push__b1(void)
613d5eb9
PK
285{
286 const char *specs[] = { "refs/heads/b1:refs/heads/b1" };
287 push_status exp_stats[] = { { "refs/heads/b1", NULL } };
288 expected_ref exp_refs[] = { { "refs/heads/b1", &_oid_b1 } };
289 do_push(specs, ARRAY_SIZE(specs),
290 exp_stats, ARRAY_SIZE(exp_stats),
291 exp_refs, ARRAY_SIZE(exp_refs), 0);
292}
293
6443eaf2 294void test_online_push__b2(void)
613d5eb9
PK
295{
296 const char *specs[] = { "refs/heads/b2:refs/heads/b2" };
297 push_status exp_stats[] = { { "refs/heads/b2", NULL } };
298 expected_ref exp_refs[] = { { "refs/heads/b2", &_oid_b2 } };
299 do_push(specs, ARRAY_SIZE(specs),
300 exp_stats, ARRAY_SIZE(exp_stats),
301 exp_refs, ARRAY_SIZE(exp_refs), 0);
302}
303
6443eaf2 304void test_online_push__b3(void)
613d5eb9
PK
305{
306 const char *specs[] = { "refs/heads/b3:refs/heads/b3" };
307 push_status exp_stats[] = { { "refs/heads/b3", NULL } };
308 expected_ref exp_refs[] = { { "refs/heads/b3", &_oid_b3 } };
309 do_push(specs, ARRAY_SIZE(specs),
310 exp_stats, ARRAY_SIZE(exp_stats),
311 exp_refs, ARRAY_SIZE(exp_refs), 0);
312}
313
6443eaf2 314void test_online_push__b4(void)
613d5eb9
PK
315{
316 const char *specs[] = { "refs/heads/b4:refs/heads/b4" };
317 push_status exp_stats[] = { { "refs/heads/b4", NULL } };
318 expected_ref exp_refs[] = { { "refs/heads/b4", &_oid_b4 } };
319 do_push(specs, ARRAY_SIZE(specs),
320 exp_stats, ARRAY_SIZE(exp_stats),
321 exp_refs, ARRAY_SIZE(exp_refs), 0);
322}
323
6443eaf2 324void test_online_push__b5(void)
613d5eb9
PK
325{
326 const char *specs[] = { "refs/heads/b5:refs/heads/b5" };
327 push_status exp_stats[] = { { "refs/heads/b5", NULL } };
328 expected_ref exp_refs[] = { { "refs/heads/b5", &_oid_b5 } };
329 do_push(specs, ARRAY_SIZE(specs),
330 exp_stats, ARRAY_SIZE(exp_stats),
331 exp_refs, ARRAY_SIZE(exp_refs), 0);
332}
333
6443eaf2 334void test_online_push__multi(void)
613d5eb9
PK
335{
336 const char *specs[] = {
337 "refs/heads/b1:refs/heads/b1",
338 "refs/heads/b2:refs/heads/b2",
339 "refs/heads/b3:refs/heads/b3",
340 "refs/heads/b4:refs/heads/b4",
341 "refs/heads/b5:refs/heads/b5"
342 };
343 push_status exp_stats[] = {
344 { "refs/heads/b1", NULL },
345 { "refs/heads/b2", NULL },
346 { "refs/heads/b3", NULL },
347 { "refs/heads/b4", NULL },
348 { "refs/heads/b5", NULL }
349 };
350 expected_ref exp_refs[] = {
351 { "refs/heads/b1", &_oid_b1 },
352 { "refs/heads/b2", &_oid_b2 },
353 { "refs/heads/b3", &_oid_b3 },
354 { "refs/heads/b4", &_oid_b4 },
355 { "refs/heads/b5", &_oid_b5 }
356 };
357 do_push(specs, ARRAY_SIZE(specs),
358 exp_stats, ARRAY_SIZE(exp_stats),
359 exp_refs, ARRAY_SIZE(exp_refs), 0);
360}
361
6443eaf2 362void test_online_push__implicit_tgt(void)
613d5eb9
PK
363{
364 const char *specs1[] = { "refs/heads/b1:" };
365 push_status exp_stats1[] = { { "refs/heads/b1", NULL } };
366 expected_ref exp_refs1[] = { { "refs/heads/b1", &_oid_b1 } };
367
368 const char *specs2[] = { "refs/heads/b2:" };
369 push_status exp_stats2[] = { { "refs/heads/b2", NULL } };
370 expected_ref exp_refs2[] = {
371 { "refs/heads/b1", &_oid_b1 },
372 { "refs/heads/b2", &_oid_b2 }
373 };
374
375 do_push(specs1, ARRAY_SIZE(specs1),
376 exp_stats1, ARRAY_SIZE(exp_stats1),
377 exp_refs1, ARRAY_SIZE(exp_refs1), 0);
378 do_push(specs2, ARRAY_SIZE(specs2),
379 exp_stats2, ARRAY_SIZE(exp_stats2),
380 exp_refs2, ARRAY_SIZE(exp_refs2), 0);
381}
382
6443eaf2 383void test_online_push__fast_fwd(void)
613d5eb9
PK
384{
385 /* Fast forward b1 in tgt from _oid_b1 to _oid_b6. */
386
387 const char *specs_init[] = { "refs/heads/b1:refs/heads/b1" };
388 push_status exp_stats_init[] = { { "refs/heads/b1", NULL } };
389 expected_ref exp_refs_init[] = { { "refs/heads/b1", &_oid_b1 } };
390
391 const char *specs_ff[] = { "refs/heads/b6:refs/heads/b1" };
392 push_status exp_stats_ff[] = { { "refs/heads/b1", NULL } };
393 expected_ref exp_refs_ff[] = { { "refs/heads/b1", &_oid_b6 } };
394
395 /* Do a force push to reset b1 in target back to _oid_b1 */
396 const char *specs_reset[] = { "+refs/heads/b1:refs/heads/b1" };
397 /* Force should have no effect on a fast forward push */
398 const char *specs_ff_force[] = { "+refs/heads/b6:refs/heads/b1" };
399
400 do_push(specs_init, ARRAY_SIZE(specs_init),
401 exp_stats_init, ARRAY_SIZE(exp_stats_init),
402 exp_refs_init, ARRAY_SIZE(exp_refs_init), 0);
403
404 do_push(specs_ff, ARRAY_SIZE(specs_ff),
405 exp_stats_ff, ARRAY_SIZE(exp_stats_ff),
406 exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0);
407
408 do_push(specs_reset, ARRAY_SIZE(specs_reset),
409 exp_stats_init, ARRAY_SIZE(exp_stats_init),
410 exp_refs_init, ARRAY_SIZE(exp_refs_init), 0);
411
412 do_push(specs_ff_force, ARRAY_SIZE(specs_ff_force),
413 exp_stats_ff, ARRAY_SIZE(exp_stats_ff),
414 exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0);
415}
416
abeefbbe
MS
417void test_online_push__tag_commit(void)
418{
419 const char *specs[] = { "refs/tags/tag-commit:refs/tags/tag-commit" };
420 push_status exp_stats[] = { { "refs/tags/tag-commit", NULL } };
421 expected_ref exp_refs[] = { { "refs/tags/tag-commit", &_tag_commit } };
422 do_push(specs, ARRAY_SIZE(specs),
423 exp_stats, ARRAY_SIZE(exp_stats),
424 exp_refs, ARRAY_SIZE(exp_refs), 0);
425}
426
427void test_online_push__tag_tree(void)
428{
429 const char *specs[] = { "refs/tags/tag-tree:refs/tags/tag-tree" };
430 push_status exp_stats[] = { { "refs/tags/tag-tree", NULL } };
431 expected_ref exp_refs[] = { { "refs/tags/tag-tree", &_tag_tree } };
432 do_push(specs, ARRAY_SIZE(specs),
433 exp_stats, ARRAY_SIZE(exp_stats),
434 exp_refs, ARRAY_SIZE(exp_refs), 0);
435}
436
437void test_online_push__tag_blob(void)
438{
439 const char *specs[] = { "refs/tags/tag-blob:refs/tags/tag-blob" };
440 push_status exp_stats[] = { { "refs/tags/tag-blob", NULL } };
441 expected_ref exp_refs[] = { { "refs/tags/tag-blob", &_tag_blob } };
442 do_push(specs, ARRAY_SIZE(specs),
443 exp_stats, ARRAY_SIZE(exp_stats),
444 exp_refs, ARRAY_SIZE(exp_refs), 0);
445}
446
447void test_online_push__tag_lightweight(void)
448{
449 const char *specs[] = { "refs/tags/tag-lightweight:refs/tags/tag-lightweight" };
450 push_status exp_stats[] = { { "refs/tags/tag-lightweight", NULL } };
451 expected_ref exp_refs[] = { { "refs/tags/tag-lightweight", &_tag_lightweight } };
452 do_push(specs, ARRAY_SIZE(specs),
453 exp_stats, ARRAY_SIZE(exp_stats),
454 exp_refs, ARRAY_SIZE(exp_refs), 0);
455}
456
6443eaf2 457void test_online_push__force(void)
613d5eb9
PK
458{
459 const char *specs1[] = {"refs/heads/b3:refs/heads/tgt"};
460 push_status exp_stats1[] = { { "refs/heads/tgt", NULL } };
461 expected_ref exp_refs1[] = { { "refs/heads/tgt", &_oid_b3 } };
462
463 const char *specs2[] = {"refs/heads/b4:refs/heads/tgt"};
464
465 const char *specs2_force[] = {"+refs/heads/b4:refs/heads/tgt"};
466 push_status exp_stats2_force[] = { { "refs/heads/tgt", NULL } };
467 expected_ref exp_refs2_force[] = { { "refs/heads/tgt", &_oid_b4 } };
468
469 do_push(specs1, ARRAY_SIZE(specs1),
470 exp_stats1, ARRAY_SIZE(exp_stats1),
471 exp_refs1, ARRAY_SIZE(exp_refs1), 0);
472
473 do_push(specs2, ARRAY_SIZE(specs2),
474 NULL, 0,
475 exp_refs1, ARRAY_SIZE(exp_refs1), GIT_ENONFASTFORWARD);
476
477 /* Non-fast-forward update with force should pass. */
478 do_push(specs2_force, ARRAY_SIZE(specs2_force),
479 exp_stats2_force, ARRAY_SIZE(exp_stats2_force),
480 exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0);
481}
482
6443eaf2 483void test_online_push__delete(void)
613d5eb9
PK
484{
485 const char *specs1[] = {
486 "refs/heads/b1:refs/heads/tgt1",
487 "refs/heads/b1:refs/heads/tgt2"
488 };
489 push_status exp_stats1[] = {
490 { "refs/heads/tgt1", NULL },
491 { "refs/heads/tgt2", NULL }
492 };
493 expected_ref exp_refs1[] = {
494 { "refs/heads/tgt1", &_oid_b1 },
495 { "refs/heads/tgt2", &_oid_b1 }
496 };
497
498 const char *specs_del_fake[] = { ":refs/heads/fake" };
499 /* Force has no effect for delete. */
500 const char *specs_del_fake_force[] = { "+:refs/heads/fake" };
d73d52df 501 push_status exp_stats_fake[] = { { "refs/heads/fake", NULL } };
613d5eb9
PK
502
503 const char *specs_delete[] = { ":refs/heads/tgt1" };
504 push_status exp_stats_delete[] = { { "refs/heads/tgt1", NULL } };
505 expected_ref exp_refs_delete[] = { { "refs/heads/tgt2", &_oid_b1 } };
506 /* Force has no effect for delete. */
507 const char *specs_delete_force[] = { "+:refs/heads/tgt1" };
508
509 do_push(specs1, ARRAY_SIZE(specs1),
510 exp_stats1, ARRAY_SIZE(exp_stats1),
511 exp_refs1, ARRAY_SIZE(exp_refs1), 0);
512
d73d52df
CW
513 /* When deleting a non-existent branch, the git client sends zero for both
514 * the old and new commit id. This should succeed on the server with the
515 * same status report as if the branch were actually deleted. The server
516 * returns a warning on the side-band iff the side-band is supported.
517 * Since libgit2 doesn't support the side-band yet, there are no warnings.
613d5eb9
PK
518 */
519 do_push(specs_del_fake, ARRAY_SIZE(specs_del_fake),
d73d52df
CW
520 exp_stats_fake, 1,
521 exp_refs1, ARRAY_SIZE(exp_refs1), 0);
613d5eb9 522 do_push(specs_del_fake_force, ARRAY_SIZE(specs_del_fake_force),
d73d52df
CW
523 exp_stats_fake, 1,
524 exp_refs1, ARRAY_SIZE(exp_refs1), 0);
613d5eb9
PK
525
526 /* Delete one of the pushed branches. */
527 do_push(specs_delete, ARRAY_SIZE(specs_delete),
528 exp_stats_delete, ARRAY_SIZE(exp_stats_delete),
529 exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0);
530
531 /* Re-push branches and retry delete with force. */
532 do_push(specs1, ARRAY_SIZE(specs1),
533 exp_stats1, ARRAY_SIZE(exp_stats1),
534 exp_refs1, ARRAY_SIZE(exp_refs1), 0);
535 do_push(specs_delete_force, ARRAY_SIZE(specs_delete_force),
536 exp_stats_delete, ARRAY_SIZE(exp_stats_delete),
537 exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0);
538}
539
6443eaf2 540void test_online_push__bad_refspecs(void)
613d5eb9
PK
541{
542 /* All classes of refspecs that should be rejected by
543 * git_push_add_refspec() should go in this test.
544 */
545 git_push *push;
546
547 if (_remote) {
b412d563 548// cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH));
613d5eb9
PK
549 cl_git_pass(git_push_new(&push, _remote));
550
551 /* Unexpanded branch names not supported */
552 cl_git_fail(git_push_add_refspec(push, "b6:b6"));
553
554 git_push_free(push);
555 }
556}
557
6443eaf2 558void test_online_push__expressions(void)
613d5eb9
PK
559{
560 /* TODO: Expressions in refspecs doesn't actually work yet */
561 const char *specs_left_expr[] = { "refs/heads/b2~1:refs/heads/b2" };
562
563 const char *specs_right_expr[] = { "refs/heads/b2:refs/heads/b2~1" };
564 push_status exp_stats_right_expr[] = { { "refs/heads/b2~1", "funny refname" } };
565
566 /* TODO: Find a more precise way of checking errors than a exit code of -1. */
567 do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr),
568 NULL, 0,
569 NULL, 0, -1);
570
571 do_push(specs_right_expr, ARRAY_SIZE(specs_right_expr),
572 exp_stats_right_expr, ARRAY_SIZE(exp_stats_right_expr),
573 NULL, 0, 0);
574}
087f64d3 575
abeefbbe 576void test_online_push__notes(void)
087f64d3
JM
577{
578 git_oid note_oid, *target_oid, expected_oid;
579 git_signature *signature;
580 const char *specs[] = { "refs/notes/commits:refs/notes/commits" };
581 push_status exp_stats[] = { { "refs/notes/commits", NULL } };
582 expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } };
583 git_oid_fromstr(&expected_oid, "8461a99b27b7043e58ff6e1f5d2cf07d282534fb");
584
585 target_oid = &_oid_b6;
586
587 /* Create note to push */
588 cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
abeefbbe 589 cl_git_pass(git_note_create(&note_oid, _repo, signature, signature, NULL, target_oid, "hello world\n", 0));
087f64d3
JM
590
591 do_push(specs, ARRAY_SIZE(specs),
592 exp_stats, ARRAY_SIZE(exp_stats),
593 exp_refs, ARRAY_SIZE(exp_refs), 0);
594
595 git_signature_free(signature);
596}