]> git.proxmox.com Git - libgit2.git/blob - tests/online/fetch.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / tests / online / fetch.c
1 #include "clar_libgit2.h"
2 #include "futils.h"
3
4 static git_repository *_repo;
5 static int counter;
6
7 static char *_remote_proxy_scheme = NULL;
8 static char *_remote_proxy_host = NULL;
9 static char *_remote_proxy_user = NULL;
10 static char *_remote_proxy_pass = NULL;
11 static char *_remote_redirect_initial = NULL;
12 static char *_remote_redirect_subsequent = NULL;
13
14 void test_online_fetch__initialize(void)
15 {
16 cl_git_pass(git_repository_init(&_repo, "./fetch", 0));
17
18 _remote_proxy_scheme = cl_getenv("GITTEST_REMOTE_PROXY_SCHEME");
19 _remote_proxy_host = cl_getenv("GITTEST_REMOTE_PROXY_HOST");
20 _remote_proxy_user = cl_getenv("GITTEST_REMOTE_PROXY_USER");
21 _remote_proxy_pass = cl_getenv("GITTEST_REMOTE_PROXY_PASS");
22 _remote_redirect_initial = cl_getenv("GITTEST_REMOTE_REDIRECT_INITIAL");
23 _remote_redirect_subsequent = cl_getenv("GITTEST_REMOTE_REDIRECT_SUBSEQUENT");
24 }
25
26 void test_online_fetch__cleanup(void)
27 {
28 git_repository_free(_repo);
29 _repo = NULL;
30
31 cl_fixture_cleanup("./fetch");
32 cl_fixture_cleanup("./redirected");
33
34 git__free(_remote_proxy_scheme);
35 git__free(_remote_proxy_host);
36 git__free(_remote_proxy_user);
37 git__free(_remote_proxy_pass);
38 git__free(_remote_redirect_initial);
39 git__free(_remote_redirect_subsequent);
40 }
41
42 static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *data)
43 {
44 GIT_UNUSED(refname); GIT_UNUSED(a); GIT_UNUSED(b); GIT_UNUSED(data);
45
46 ++counter;
47
48 return 0;
49 }
50
51 static int progress(const git_indexer_progress *stats, void *payload)
52 {
53 size_t *bytes_received = (size_t *)payload;
54 *bytes_received = stats->received_bytes;
55 return 0;
56 }
57
58 static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n)
59 {
60 git_remote *remote;
61 git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
62 size_t bytes_received = 0;
63
64 options.callbacks.transfer_progress = progress;
65 options.callbacks.update_tips = update_tips;
66 options.callbacks.payload = &bytes_received;
67 options.download_tags = flag;
68 counter = 0;
69
70 cl_git_pass(git_remote_create(&remote, _repo, "test", url));
71 cl_git_pass(git_remote_fetch(remote, NULL, &options, NULL));
72 cl_assert_equal_i(counter, n);
73 cl_assert(bytes_received > 0);
74
75 git_remote_free(remote);
76 }
77
78 void test_online_fetch__default_http(void)
79 {
80 do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6);
81 }
82
83 void test_online_fetch__default_https(void)
84 {
85 do_fetch("https://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6);
86 }
87
88 void test_online_fetch__no_tags_git(void)
89 {
90 do_fetch("https://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_NONE, 3);
91 }
92
93 void test_online_fetch__no_tags_http(void)
94 {
95 do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_NONE, 3);
96 }
97
98 void test_online_fetch__fetch_twice(void)
99 {
100 git_remote *remote;
101 cl_git_pass(git_remote_create(&remote, _repo, "test", "https://github.com/libgit2/TestGitRepository.git"));
102 cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
103 cl_git_pass(git_remote_download(remote, NULL, NULL));
104 git_remote_disconnect(remote);
105
106 git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL);
107 cl_git_pass(git_remote_download(remote, NULL, NULL));
108 git_remote_disconnect(remote);
109
110 git_remote_free(remote);
111 }
112
113 static int transferProgressCallback(const git_indexer_progress *stats, void *payload)
114 {
115 bool *invoked = (bool *)payload;
116
117 GIT_UNUSED(stats);
118 *invoked = true;
119 return 0;
120 }
121
122 void test_online_fetch__doesnt_retrieve_a_pack_when_the_repository_is_up_to_date(void)
123 {
124 git_repository *_repository;
125 bool invoked = false;
126 git_remote *remote;
127 git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
128 git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
129 opts.bare = true;
130
131 cl_git_pass(git_clone(&_repository, "https://github.com/libgit2/TestGitRepository.git",
132 "./fetch/lg2", &opts));
133 git_repository_free(_repository);
134
135 cl_git_pass(git_repository_open(&_repository, "./fetch/lg2"));
136
137 cl_git_pass(git_remote_lookup(&remote, _repository, "origin"));
138 cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
139
140 cl_assert_equal_i(false, invoked);
141
142 options.callbacks.transfer_progress = &transferProgressCallback;
143 options.callbacks.payload = &invoked;
144 cl_git_pass(git_remote_download(remote, NULL, &options));
145
146 cl_assert_equal_i(false, invoked);
147
148 cl_git_pass(git_remote_update_tips(remote, &options.callbacks, 1, options.download_tags, NULL));
149 git_remote_disconnect(remote);
150
151 git_remote_free(remote);
152 git_repository_free(_repository);
153 }
154
155 static int cancel_at_half(const git_indexer_progress *stats, void *payload)
156 {
157 GIT_UNUSED(payload);
158
159 if (stats->received_objects > (stats->total_objects/2))
160 return -4321;
161 return 0;
162 }
163
164 void test_online_fetch__can_cancel(void)
165 {
166 git_remote *remote;
167 size_t bytes_received = 0;
168 git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
169
170 cl_git_pass(git_remote_create(&remote, _repo, "test",
171 "http://github.com/libgit2/TestGitRepository.git"));
172
173 options.callbacks.transfer_progress = cancel_at_half;
174 options.callbacks.payload = &bytes_received;
175
176 cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
177 cl_git_fail_with(git_remote_download(remote, NULL, &options), -4321);
178 git_remote_disconnect(remote);
179 git_remote_free(remote);
180 }
181
182 void test_online_fetch__ls_disconnected(void)
183 {
184 const git_remote_head **refs;
185 size_t refs_len_before, refs_len_after;
186 git_remote *remote;
187
188 cl_git_pass(git_remote_create(&remote, _repo, "test",
189 "http://github.com/libgit2/TestGitRepository.git"));
190 cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
191 cl_git_pass(git_remote_ls(&refs, &refs_len_before, remote));
192 git_remote_disconnect(remote);
193 cl_git_pass(git_remote_ls(&refs, &refs_len_after, remote));
194
195 cl_assert_equal_i(refs_len_before, refs_len_after);
196
197 git_remote_free(remote);
198 }
199
200 void test_online_fetch__remote_symrefs(void)
201 {
202 const git_remote_head **refs;
203 size_t refs_len;
204 git_remote *remote;
205
206 cl_git_pass(git_remote_create(&remote, _repo, "test",
207 "http://github.com/libgit2/TestGitRepository.git"));
208 cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
209 git_remote_disconnect(remote);
210 cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
211
212 cl_assert_equal_s("HEAD", refs[0]->name);
213 cl_assert_equal_s("refs/heads/master", refs[0]->symref_target);
214
215 git_remote_free(remote);
216 }
217
218 void test_online_fetch__twice(void)
219 {
220 git_remote *remote;
221
222 cl_git_pass(git_remote_create(&remote, _repo, "test", "http://github.com/libgit2/TestGitRepository.git"));
223 cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
224 cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
225
226 git_remote_free(remote);
227 }
228
229 void test_online_fetch__proxy(void)
230 {
231 git_remote *remote;
232 git_str url = GIT_STR_INIT;
233 git_fetch_options fetch_opts;
234
235 if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass)
236 cl_skip();
237
238 cl_git_pass(git_str_printf(&url, "%s://%s:%s@%s/",
239 _remote_proxy_scheme ? _remote_proxy_scheme : "http",
240 _remote_proxy_user, _remote_proxy_pass, _remote_proxy_host));
241
242 cl_git_pass(git_fetch_options_init(&fetch_opts, GIT_FETCH_OPTIONS_VERSION));
243 fetch_opts.proxy_opts.type = GIT_PROXY_SPECIFIED;
244 fetch_opts.proxy_opts.url = url.ptr;
245
246 cl_git_pass(git_remote_create(&remote, _repo, "test", "https://github.com/libgit2/TestGitRepository.git"));
247 cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, &fetch_opts.proxy_opts, NULL));
248 cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL));
249
250 git_remote_free(remote);
251 git_str_dispose(&url);
252 }
253
254 static int do_redirected_fetch(const char *url, const char *name, const char *config)
255 {
256 git_repository *repo;
257 git_remote *remote;
258 int error;
259
260 cl_git_pass(git_repository_init(&repo, "./redirected", 0));
261 cl_fixture_cleanup(name);
262
263 if (config)
264 cl_repo_set_string(repo, "http.followRedirects", config);
265
266 cl_git_pass(git_remote_create(&remote, repo, name, url));
267 error = git_remote_fetch(remote, NULL, NULL, NULL);
268
269 git_remote_free(remote);
270 git_repository_free(repo);
271
272 cl_fixture_cleanup("./redirected");
273
274 return error;
275 }
276
277 void test_online_fetch__redirect_config(void)
278 {
279 if (!_remote_redirect_initial || !_remote_redirect_subsequent)
280 cl_skip();
281
282 /* config defaults */
283 cl_git_pass(do_redirected_fetch(_remote_redirect_initial, "initial", NULL));
284 cl_git_fail(do_redirected_fetch(_remote_redirect_subsequent, "subsequent", NULL));
285
286 /* redirect=initial */
287 cl_git_pass(do_redirected_fetch(_remote_redirect_initial, "initial", "initial"));
288 cl_git_fail(do_redirected_fetch(_remote_redirect_subsequent, "subsequent", "initial"));
289
290 /* redirect=false */
291 cl_git_fail(do_redirected_fetch(_remote_redirect_initial, "initial", "false"));
292 cl_git_fail(do_redirected_fetch(_remote_redirect_subsequent, "subsequent", "false"));
293 }
294
295 void test_online_fetch__reachable_commit(void)
296 {
297 git_remote *remote;
298 git_strarray refspecs;
299 git_object *obj;
300 git_oid expected_id;
301 git_str fetchhead = GIT_STR_INIT;
302 char *refspec = "+2c349335b7f797072cf729c4f3bb0914ecb6dec9:refs/success";
303
304 refspecs.strings = &refspec;
305 refspecs.count = 1;
306
307 git_oid_fromstr(&expected_id, "2c349335b7f797072cf729c4f3bb0914ecb6dec9");
308
309 cl_git_pass(git_remote_create(&remote, _repo, "test",
310 "https://github.com/libgit2/TestGitRepository"));
311 cl_git_pass(git_remote_fetch(remote, &refspecs, NULL, NULL));
312
313 cl_git_pass(git_revparse_single(&obj, _repo, "refs/success"));
314 cl_assert_equal_oid(&expected_id, git_object_id(obj));
315
316 cl_git_pass(git_futils_readbuffer(&fetchhead, "./fetch/.git/FETCH_HEAD"));
317 cl_assert_equal_s(fetchhead.ptr,
318 "2c349335b7f797072cf729c4f3bb0914ecb6dec9\t\t'2c349335b7f797072cf729c4f3bb0914ecb6dec9' of https://github.com/libgit2/TestGitRepository\n");
319
320 git_str_dispose(&fetchhead);
321 git_object_free(obj);
322 git_remote_free(remote);
323 }
324
325 void test_online_fetch__reachable_commit_without_destination(void)
326 {
327 git_remote *remote;
328 git_strarray refspecs;
329 git_object *obj;
330 git_oid expected_id;
331 git_str fetchhead = GIT_STR_INIT;
332 char *refspec = "2c349335b7f797072cf729c4f3bb0914ecb6dec9";
333
334 refspecs.strings = &refspec;
335 refspecs.count = 1;
336
337 git_oid_fromstr(&expected_id, "2c349335b7f797072cf729c4f3bb0914ecb6dec9");
338
339 cl_git_pass(git_remote_create(&remote, _repo, "test",
340 "https://github.com/libgit2/TestGitRepository"));
341 cl_git_pass(git_remote_fetch(remote, &refspecs, NULL, NULL));
342
343 cl_git_fail_with(GIT_ENOTFOUND, git_revparse_single(&obj, _repo, "refs/success"));
344
345 cl_git_pass(git_futils_readbuffer(&fetchhead, "./fetch/.git/FETCH_HEAD"));
346 cl_assert_equal_s(fetchhead.ptr,
347 "2c349335b7f797072cf729c4f3bb0914ecb6dec9\t\t'2c349335b7f797072cf729c4f3bb0914ecb6dec9' of https://github.com/libgit2/TestGitRepository\n");
348
349 git_str_dispose(&fetchhead);
350 git_object_free(obj);
351 git_remote_free(remote);
352 }