]> git.proxmox.com Git - libgit2.git/blob - tests/config/read.c
Merge pull request #2974 from libgit2/cmn/clone-everything
[libgit2.git] / tests / config / read.c
1 #include "clar_libgit2.h"
2 #include "buffer.h"
3 #include "path.h"
4
5 static git_buf buf = GIT_BUF_INIT;
6
7 void test_config_read__cleanup(void)
8 {
9 git_buf_free(&buf);
10 }
11
12 void test_config_read__simple_read(void)
13 {
14 git_config *cfg;
15 int32_t i;
16
17 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config0")));
18
19 cl_git_pass(git_config_get_int32(&i, cfg, "core.repositoryformatversion"));
20 cl_assert(i == 0);
21 cl_git_pass(git_config_get_bool(&i, cfg, "core.filemode"));
22 cl_assert(i == 1);
23 cl_git_pass(git_config_get_bool(&i, cfg, "core.bare"));
24 cl_assert(i == 0);
25 cl_git_pass(git_config_get_bool(&i, cfg, "core.logallrefupdates"));
26 cl_assert(i == 1);
27
28 git_config_free(cfg);
29 }
30
31 void test_config_read__case_sensitive(void)
32 {
33 git_config *cfg;
34 int i;
35
36 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config1")));
37
38 cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.that.other"));
39 cl_assert_equal_s("true", git_buf_cstr(&buf));
40 git_buf_clear(&buf);
41
42 cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.That.other"));
43 cl_assert_equal_s("yes", git_buf_cstr(&buf));
44
45 cl_git_pass(git_config_get_bool(&i, cfg, "this.that.other"));
46 cl_assert(i == 1);
47 cl_git_pass(git_config_get_bool(&i, cfg, "this.That.other"));
48 cl_assert(i == 1);
49
50 /* This one doesn't exist */
51 cl_must_fail(git_config_get_bool(&i, cfg, "this.thaT.other"));
52
53 git_config_free(cfg);
54 }
55
56 /*
57 * If \ is the last non-space character on the line, we read the next
58 * one, separating each line with SP.
59 */
60 void test_config_read__multiline_value(void)
61 {
62 git_config *cfg;
63
64 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config2")));
65
66 cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.That.and"));
67 cl_assert_equal_s("one one one two two three three", git_buf_cstr(&buf));
68
69 git_config_free(cfg);
70 }
71
72 /*
73 * This kind of subsection declaration is case-insensitive
74 */
75 void test_config_read__subsection_header(void)
76 {
77 git_config *cfg;
78
79 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config3")));
80
81 cl_git_pass(git_config_get_string_buf(&buf, cfg, "section.subsection.var"));
82 cl_assert_equal_s("hello", git_buf_cstr(&buf));
83
84 /* The subsection is transformed to lower-case */
85 cl_must_fail(git_config_get_string_buf(&buf, cfg, "section.subSectIon.var"));
86
87 git_config_free(cfg);
88 }
89
90 void test_config_read__lone_variable(void)
91 {
92 git_config *cfg;
93 int i;
94
95 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config4")));
96
97 cl_git_fail(git_config_get_int32(&i, cfg, "some.section.variable"));
98
99 cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.section.variable"));
100 cl_assert_equal_s("", git_buf_cstr(&buf));
101 git_buf_clear(&buf);
102
103 cl_git_pass(git_config_get_bool(&i, cfg, "some.section.variable"));
104 cl_assert(i == 1);
105
106 cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.section.variableeq"));
107 cl_assert_equal_s("", git_buf_cstr(&buf));
108
109 cl_git_pass(git_config_get_bool(&i, cfg, "some.section.variableeq"));
110 cl_assert(i == 0);
111
112 git_config_free(cfg);
113 }
114
115 void test_config_read__number_suffixes(void)
116 {
117 git_config *cfg;
118 int64_t i;
119
120 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config5")));
121
122 cl_git_pass(git_config_get_int64(&i, cfg, "number.simple"));
123 cl_assert(i == 1);
124
125 cl_git_pass(git_config_get_int64(&i, cfg, "number.k"));
126 cl_assert(i == 1 * 1024);
127
128 cl_git_pass(git_config_get_int64(&i, cfg, "number.kk"));
129 cl_assert(i == 1 * 1024);
130
131 cl_git_pass(git_config_get_int64(&i, cfg, "number.m"));
132 cl_assert(i == 1 * 1024 * 1024);
133
134 cl_git_pass(git_config_get_int64(&i, cfg, "number.mm"));
135 cl_assert(i == 1 * 1024 * 1024);
136
137 cl_git_pass(git_config_get_int64(&i, cfg, "number.g"));
138 cl_assert(i == 1 * 1024 * 1024 * 1024);
139
140 cl_git_pass(git_config_get_int64(&i, cfg, "number.gg"));
141 cl_assert(i == 1 * 1024 * 1024 * 1024);
142
143 git_config_free(cfg);
144 }
145
146 void test_config_read__blank_lines(void)
147 {
148 git_config *cfg;
149 int i;
150
151 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config6")));
152
153 cl_git_pass(git_config_get_bool(&i, cfg, "valid.subsection.something"));
154 cl_assert(i == 1);
155
156 cl_git_pass(git_config_get_bool(&i, cfg, "something.else.something"));
157 cl_assert(i == 0);
158
159 git_config_free(cfg);
160 }
161
162 void test_config_read__invalid_ext_headers(void)
163 {
164 git_config *cfg;
165 cl_must_fail(git_config_open_ondisk(&cfg, cl_fixture("config/config7")));
166 }
167
168 void test_config_read__empty_files(void)
169 {
170 git_config *cfg;
171 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config8")));
172 git_config_free(cfg);
173 }
174
175 void test_config_read__symbol_headers(void)
176 {
177 git_config *cfg;
178 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config20")));
179 git_config_free(cfg);
180 }
181
182 void test_config_read__header_in_last_line(void)
183 {
184 git_config *cfg;
185
186 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config10")));
187 git_config_free(cfg);
188 }
189
190 void test_config_read__prefixes(void)
191 {
192 git_config *cfg;
193
194 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));
195 cl_git_pass(git_config_get_string_buf(&buf, cfg, "remote.ab.url"));
196 cl_assert_equal_s("http://example.com/git/ab", git_buf_cstr(&buf));
197 git_buf_clear(&buf);
198
199 cl_git_pass(git_config_get_string_buf(&buf, cfg, "remote.abba.url"));
200 cl_assert_equal_s("http://example.com/git/abba", git_buf_cstr(&buf));
201
202 git_config_free(cfg);
203 }
204
205 void test_config_read__escaping_quotes(void)
206 {
207 git_config *cfg;
208
209 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config13")));
210 cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.editor"));
211 cl_assert_equal_s("\"C:/Program Files/Nonsense/bah.exe\" \"--some option\"", git_buf_cstr(&buf));
212
213 git_config_free(cfg);
214 }
215
216 static int count_cfg_entries_and_compare_levels(
217 const git_config_entry *entry, void *payload)
218 {
219 int *count = payload;
220
221 if (!strcmp(entry->value, "7") || !strcmp(entry->value, "17"))
222 cl_assert(entry->level == GIT_CONFIG_LEVEL_GLOBAL);
223 else
224 cl_assert(entry->level == GIT_CONFIG_LEVEL_SYSTEM);
225
226 (*count)++;
227 return 0;
228 }
229
230 static int cfg_callback_countdown(const git_config_entry *entry, void *payload)
231 {
232 int *count = payload;
233 GIT_UNUSED(entry);
234 (*count)--;
235 if (*count == 0)
236 return -100;
237 return 0;
238 }
239
240 void test_config_read__foreach(void)
241 {
242 git_config *cfg;
243 int count, ret;
244
245 cl_git_pass(git_config_new(&cfg));
246 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
247 GIT_CONFIG_LEVEL_SYSTEM, 0));
248 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
249 GIT_CONFIG_LEVEL_GLOBAL, 0));
250
251 count = 0;
252 cl_git_pass(git_config_foreach(cfg, count_cfg_entries_and_compare_levels, &count));
253 cl_assert_equal_i(7, count);
254
255 count = 3;
256 cl_git_fail(ret = git_config_foreach(cfg, cfg_callback_countdown, &count));
257 cl_assert_equal_i(-100, ret);
258
259 git_config_free(cfg);
260 }
261
262 void test_config_read__iterator(void)
263 {
264 git_config *cfg;
265 git_config_iterator *iter;
266 git_config_entry *entry;
267 int count, ret;
268
269 cl_git_pass(git_config_new(&cfg));
270 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
271 GIT_CONFIG_LEVEL_SYSTEM, 0));
272 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
273 GIT_CONFIG_LEVEL_GLOBAL, 0));
274
275 count = 0;
276 cl_git_pass(git_config_iterator_new(&iter, cfg));
277
278 while ((ret = git_config_next(&entry, iter)) == 0) {
279 count++;
280 }
281
282 git_config_iterator_free(iter);
283 cl_assert_equal_i(GIT_ITEROVER, ret);
284 cl_assert_equal_i(7, count);
285
286 count = 3;
287 cl_git_pass(git_config_iterator_new(&iter, cfg));
288
289 git_config_iterator_free(iter);
290 git_config_free(cfg);
291 }
292
293 static int count_cfg_entries(const git_config_entry *entry, void *payload)
294 {
295 int *count = payload;
296 GIT_UNUSED(entry);
297 (*count)++;
298 return 0;
299 }
300
301 void test_config_read__foreach_match(void)
302 {
303 git_config *cfg;
304 int count;
305
306 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));
307
308 count = 0;
309 cl_git_pass(
310 git_config_foreach_match(cfg, "core.*", count_cfg_entries, &count));
311 cl_assert_equal_i(3, count);
312
313 count = 0;
314 cl_git_pass(
315 git_config_foreach_match(cfg, "remote\\.ab.*", count_cfg_entries, &count));
316 cl_assert_equal_i(2, count);
317
318 count = 0;
319 cl_git_pass(
320 git_config_foreach_match(cfg, ".*url$", count_cfg_entries, &count));
321 cl_assert_equal_i(2, count);
322
323 count = 0;
324 cl_git_pass(
325 git_config_foreach_match(cfg, ".*dummy.*", count_cfg_entries, &count));
326 cl_assert_equal_i(2, count);
327
328 count = 0;
329 cl_git_pass(
330 git_config_foreach_match(cfg, ".*nomatch.*", count_cfg_entries, &count));
331 cl_assert_equal_i(0, count);
332
333 git_config_free(cfg);
334 }
335
336 static void check_glob_iter(git_config *cfg, const char *regexp, int expected)
337 {
338 git_config_iterator *iter;
339 git_config_entry *entry;
340 int count, error;
341
342 cl_git_pass(git_config_iterator_glob_new(&iter, cfg, regexp));
343
344 count = 0;
345 while ((error = git_config_next(&entry, iter)) == 0)
346 count++;
347
348 cl_assert_equal_i(GIT_ITEROVER, error);
349 cl_assert_equal_i(expected, count);
350 git_config_iterator_free(iter);
351 }
352
353 void test_config_read__iterator_invalid_glob(void)
354 {
355 git_config *cfg;
356 git_config_iterator *iter;
357
358 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));
359
360 cl_git_fail(git_config_iterator_glob_new(&iter, cfg, "*"));
361
362 git_config_free(cfg);
363 }
364
365 void test_config_read__iterator_glob(void)
366 {
367 git_config *cfg;
368
369 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));
370
371 check_glob_iter(cfg, "core.*", 3);
372 check_glob_iter(cfg, "remote\\.ab.*", 2);
373 check_glob_iter(cfg, ".*url$", 2);
374 check_glob_iter(cfg, ".*dummy.*", 2);
375 check_glob_iter(cfg, ".*nomatch.*", 0);
376
377 git_config_free(cfg);
378 }
379
380 void test_config_read__whitespace_not_required_around_assignment(void)
381 {
382 git_config *cfg;
383
384 cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config14")));
385
386 cl_git_pass(git_config_get_string_buf(&buf, cfg, "a.b"));
387 cl_assert_equal_s("c", git_buf_cstr(&buf));
388 git_buf_clear(&buf);
389
390 cl_git_pass(git_config_get_string_buf(&buf, cfg, "d.e"));
391 cl_assert_equal_s("f", git_buf_cstr(&buf));
392
393 git_config_free(cfg);
394 }
395
396 void test_config_read__read_git_config_entry(void)
397 {
398 git_config *cfg;
399 git_config_entry *entry;
400
401 cl_git_pass(git_config_new(&cfg));
402 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
403 GIT_CONFIG_LEVEL_SYSTEM, 0));
404
405 cl_git_pass(git_config_get_entry(&entry, cfg, "core.dummy2"));
406 cl_assert_equal_s("core.dummy2", entry->name);
407 cl_assert_equal_s("42", entry->value);
408 cl_assert_equal_i(GIT_CONFIG_LEVEL_SYSTEM, entry->level);
409
410 git_config_entry_free(entry);
411 git_config_free(cfg);
412 }
413
414 /*
415 * At the beginning of the test:
416 * - config9 has: core.dummy2=42
417 * - config15 has: core.dummy2=7
418 * - config16 has: core.dummy2=28
419 */
420 void test_config_read__local_config_overrides_global_config_overrides_system_config(void)
421 {
422 git_config *cfg;
423 int32_t i;
424
425 cl_git_pass(git_config_new(&cfg));
426 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
427 GIT_CONFIG_LEVEL_SYSTEM, 0));
428 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
429 GIT_CONFIG_LEVEL_GLOBAL, 0));
430 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config16"),
431 GIT_CONFIG_LEVEL_LOCAL, 0));
432
433 cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2"));
434 cl_assert_equal_i(28, i);
435
436 git_config_free(cfg);
437
438 cl_git_pass(git_config_new(&cfg));
439 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
440 GIT_CONFIG_LEVEL_SYSTEM, 0));
441 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
442 GIT_CONFIG_LEVEL_GLOBAL, 0));
443
444 cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2"));
445 cl_assert_equal_i(7, i);
446
447 git_config_free(cfg);
448 }
449
450 /*
451 * At the beginning of the test:
452 * - config9 has: core.global does not exist
453 * - config15 has: core.global=17
454 * - config16 has: core.global=29
455 *
456 * And also:
457 * - config9 has: core.system does not exist
458 * - config15 has: core.system does not exist
459 * - config16 has: core.system=11
460 */
461 void test_config_read__fallback_from_local_to_global_and_from_global_to_system(void)
462 {
463 git_config *cfg;
464 int32_t i;
465
466 cl_git_pass(git_config_new(&cfg));
467 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
468 GIT_CONFIG_LEVEL_SYSTEM, 0));
469 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
470 GIT_CONFIG_LEVEL_GLOBAL, 0));
471 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config16"),
472 GIT_CONFIG_LEVEL_LOCAL, 0));
473
474 cl_git_pass(git_config_get_int32(&i, cfg, "core.global"));
475 cl_assert_equal_i(17, i);
476 cl_git_pass(git_config_get_int32(&i, cfg, "core.system"));
477 cl_assert_equal_i(11, i);
478
479 git_config_free(cfg);
480 }
481
482 /*
483 * At the beginning of the test, config18 has:
484 * int32global = 28
485 * int64global = 9223372036854775803
486 * boolglobal = true
487 * stringglobal = I'm a global config value!
488 *
489 * And config19 has:
490 * int32global = -1
491 * int64global = -2
492 * boolglobal = false
493 * stringglobal = don't find me!
494 *
495 */
496 void test_config_read__simple_read_from_specific_level(void)
497 {
498 git_config *cfg, *cfg_specific;
499 int i;
500 int64_t l, expected = +9223372036854775803;
501
502 cl_git_pass(git_config_new(&cfg));
503 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config18"),
504 GIT_CONFIG_LEVEL_GLOBAL, 0));
505 cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config19"),
506 GIT_CONFIG_LEVEL_SYSTEM, 0));
507
508 cl_git_pass(git_config_open_level(&cfg_specific, cfg, GIT_CONFIG_LEVEL_GLOBAL));
509
510 cl_git_pass(git_config_get_int32(&i, cfg_specific, "core.int32global"));
511 cl_assert_equal_i(28, i);
512 cl_git_pass(git_config_get_int64(&l, cfg_specific, "core.int64global"));
513 cl_assert(l == expected);
514 cl_git_pass(git_config_get_bool(&i, cfg_specific, "core.boolglobal"));
515 cl_assert_equal_b(true, i);
516 cl_git_pass(git_config_get_string_buf(&buf, cfg_specific, "core.stringglobal"));
517 cl_assert_equal_s("I'm a global config value!", git_buf_cstr(&buf));
518
519 git_config_free(cfg_specific);
520 git_config_free(cfg);
521 }
522
523 static void clean_test_config(void *unused)
524 {
525 GIT_UNUSED(unused);
526 cl_fixture_cleanup("./testconfig");
527 }
528
529 void test_config_read__can_load_and_parse_an_empty_config_file(void)
530 {
531 git_config *cfg;
532 int i;
533
534 cl_set_cleanup(&clean_test_config, NULL);
535 cl_git_mkfile("./testconfig", "");
536 cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
537 cl_assert_equal_i(GIT_ENOTFOUND, git_config_get_int32(&i, cfg, "nope.neither"));
538
539 git_config_free(cfg);
540 }
541
542 void test_config_read__corrupt_header(void)
543 {
544 git_config *cfg;
545
546 cl_set_cleanup(&clean_test_config, NULL);
547 cl_git_mkfile("./testconfig", "[sneaky ] \"quoted closing quote mark\\\"");
548 cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
549
550 git_config_free(cfg);
551 }
552
553 void test_config_read__corrupt_header2(void)
554 {
555 git_config *cfg;
556
557 cl_set_cleanup(&clean_test_config, NULL);
558 cl_git_mkfile("./testconfig", "[unclosed \"bracket\"\n lib = git2\n");
559 cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
560
561 git_config_free(cfg);
562 }
563
564 void test_config_read__corrupt_header3(void)
565 {
566 git_config *cfg;
567
568 cl_set_cleanup(&clean_test_config, NULL);
569 cl_git_mkfile("./testconfig", "[unclosed \"slash\\\"]\n lib = git2\n");
570 cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
571
572 git_config_free(cfg);
573 }
574
575 void test_config_read__override_variable(void)
576 {
577 git_config *cfg;
578
579 cl_set_cleanup(&clean_test_config, NULL);
580 cl_git_mkfile("./testconfig", "[some] var = one\nvar = two");
581 cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
582
583 cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.var"));
584 cl_assert_equal_s("two", git_buf_cstr(&buf));
585
586 git_config_free(cfg);
587 }
588
589 void test_config_read__path(void)
590 {
591 git_config *cfg;
592 git_buf path = GIT_BUF_INIT;
593 git_buf old_path = GIT_BUF_INIT;
594 git_buf home_path = GIT_BUF_INIT;
595 git_buf expected_path = GIT_BUF_INIT;
596
597 cl_git_pass(p_mkdir("fakehome", 0777));
598 cl_git_pass(git_path_prettify(&home_path, "fakehome", NULL));
599 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &old_path));
600 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, home_path.ptr));
601 cl_git_mkfile("./testconfig", "[some]\n path = ~/somefile");
602 cl_git_pass(git_path_join_unrooted(&expected_path, "somefile", home_path.ptr, NULL));
603
604 cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
605 cl_git_pass(git_config_get_path(&path, cfg, "some.path"));
606 cl_assert_equal_s(expected_path.ptr, path.ptr);
607 git_buf_free(&path);
608
609 cl_git_mkfile("./testconfig", "[some]\n path = ~/");
610 cl_git_pass(git_path_join_unrooted(&expected_path, "", home_path.ptr, NULL));
611
612 cl_git_pass(git_config_get_path(&path, cfg, "some.path"));
613 cl_assert_equal_s(expected_path.ptr, path.ptr);
614 git_buf_free(&path);
615
616 cl_git_mkfile("./testconfig", "[some]\n path = ~");
617 cl_git_pass(git_buf_sets(&expected_path, home_path.ptr));
618
619 cl_git_pass(git_config_get_path(&path, cfg, "some.path"));
620 cl_assert_equal_s(expected_path.ptr, path.ptr);
621 git_buf_free(&path);
622
623 cl_git_mkfile("./testconfig", "[some]\n path = ~user/foo");
624 cl_git_fail(git_config_get_path(&path, cfg, "some.path"));
625
626 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, old_path.ptr));
627 git_buf_free(&old_path);
628 git_buf_free(&home_path);
629 git_buf_free(&expected_path);
630 git_config_free(cfg);
631 }