1 #include "clar_libgit2.h"
5 static git_buf buf
= GIT_BUF_INIT
;
7 void test_config_read__cleanup(void)
12 void test_config_read__simple_read(void)
17 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config0")));
19 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.repositoryformatversion"));
21 cl_git_pass(git_config_get_bool(&i
, cfg
, "core.filemode"));
23 cl_git_pass(git_config_get_bool(&i
, cfg
, "core.bare"));
25 cl_git_pass(git_config_get_bool(&i
, cfg
, "core.logallrefupdates"));
31 void test_config_read__case_sensitive(void)
36 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config1")));
38 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "this.that.other"));
39 cl_assert_equal_s("true", git_buf_cstr(&buf
));
42 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "this.That.other"));
43 cl_assert_equal_s("yes", git_buf_cstr(&buf
));
45 cl_git_pass(git_config_get_bool(&i
, cfg
, "this.that.other"));
47 cl_git_pass(git_config_get_bool(&i
, cfg
, "this.That.other"));
50 /* This one doesn't exist */
51 cl_must_fail(git_config_get_bool(&i
, cfg
, "this.thaT.other"));
57 * If \ is the last non-space character on the line, we read the next
58 * one, separating each line with SP.
60 void test_config_read__multiline_value(void)
64 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config2")));
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
));
72 static void clean_test_config(void *unused
)
75 cl_fixture_cleanup("./testconfig");
78 void test_config_read__multiline_value_and_eof(void)
82 cl_set_cleanup(&clean_test_config
, NULL
);
83 cl_git_mkfile("./testconfig", "[header]\n key1 = foo\\\n");
84 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
86 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "header.key1"));
87 cl_assert_equal_s("foo", git_buf_cstr(&buf
));
92 void test_config_read__multiline_eof(void)
96 cl_set_cleanup(&clean_test_config
, NULL
);
97 cl_git_mkfile("./testconfig", "[header]\n key1 = \\\n");
98 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
100 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "header.key1"));
101 cl_assert_equal_s("", git_buf_cstr(&buf
));
103 git_config_free(cfg
);
107 * This kind of subsection declaration is case-insensitive
109 void test_config_read__subsection_header(void)
113 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config3")));
115 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "section.subsection.var"));
116 cl_assert_equal_s("hello", git_buf_cstr(&buf
));
118 /* The subsection is transformed to lower-case */
119 cl_must_fail(git_config_get_string_buf(&buf
, cfg
, "section.subSectIon.var"));
121 git_config_free(cfg
);
124 void test_config_read__lone_variable(void)
129 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config4")));
131 cl_git_fail(git_config_get_int32(&i
, cfg
, "some.section.variable"));
133 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.section.variable"));
134 cl_assert_equal_s("", git_buf_cstr(&buf
));
137 cl_git_pass(git_config_get_bool(&i
, cfg
, "some.section.variable"));
140 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.section.variableeq"));
141 cl_assert_equal_s("", git_buf_cstr(&buf
));
143 cl_git_pass(git_config_get_bool(&i
, cfg
, "some.section.variableeq"));
146 git_config_free(cfg
);
149 void test_config_read__number_suffixes(void)
154 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config5")));
156 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.simple"));
159 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.k"));
160 cl_assert(i
== 1 * 1024);
162 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.kk"));
163 cl_assert(i
== 1 * 1024);
165 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.m"));
166 cl_assert(i
== 1 * 1024 * 1024);
168 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.mm"));
169 cl_assert(i
== 1 * 1024 * 1024);
171 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.g"));
172 cl_assert(i
== 1 * 1024 * 1024 * 1024);
174 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.gg"));
175 cl_assert(i
== 1 * 1024 * 1024 * 1024);
177 git_config_free(cfg
);
180 void test_config_read__blank_lines(void)
185 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config6")));
187 cl_git_pass(git_config_get_bool(&i
, cfg
, "valid.subsection.something"));
190 cl_git_pass(git_config_get_bool(&i
, cfg
, "something.else.something"));
193 git_config_free(cfg
);
196 void test_config_read__invalid_ext_headers(void)
199 cl_must_fail(git_config_open_ondisk(&cfg
, cl_fixture("config/config7")));
202 void test_config_read__empty_files(void)
205 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config8")));
206 git_config_free(cfg
);
209 void test_config_read__symbol_headers(void)
212 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config20")));
213 git_config_free(cfg
);
216 void test_config_read__header_in_last_line(void)
220 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config10")));
221 git_config_free(cfg
);
224 void test_config_read__prefixes(void)
228 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
229 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "remote.ab.url"));
230 cl_assert_equal_s("http://example.com/git/ab", git_buf_cstr(&buf
));
233 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "remote.abba.url"));
234 cl_assert_equal_s("http://example.com/git/abba", git_buf_cstr(&buf
));
236 git_config_free(cfg
);
239 void test_config_read__escaping_quotes(void)
243 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config13")));
244 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "core.editor"));
245 cl_assert_equal_s("\"C:/Program Files/Nonsense/bah.exe\" \"--some option\"", git_buf_cstr(&buf
));
247 git_config_free(cfg
);
250 void test_config_read__invalid_escape_sequence(void)
254 cl_set_cleanup(&clean_test_config
, NULL
);
255 cl_git_mkfile("./testconfig", "[header]\n key1 = \\\\\\;\n key2 = value2\n");
256 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
258 git_config_free(cfg
);
261 static int count_cfg_entries_and_compare_levels(
262 const git_config_entry
*entry
, void *payload
)
264 int *count
= payload
;
266 if (!strcmp(entry
->value
, "7") || !strcmp(entry
->value
, "17"))
267 cl_assert(entry
->level
== GIT_CONFIG_LEVEL_GLOBAL
);
269 cl_assert(entry
->level
== GIT_CONFIG_LEVEL_SYSTEM
);
275 static int cfg_callback_countdown(const git_config_entry
*entry
, void *payload
)
277 int *count
= payload
;
285 void test_config_read__foreach(void)
290 cl_git_pass(git_config_new(&cfg
));
291 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
292 GIT_CONFIG_LEVEL_SYSTEM
, 0));
293 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
294 GIT_CONFIG_LEVEL_GLOBAL
, 0));
297 cl_git_pass(git_config_foreach(cfg
, count_cfg_entries_and_compare_levels
, &count
));
298 cl_assert_equal_i(7, count
);
301 cl_git_fail(ret
= git_config_foreach(cfg
, cfg_callback_countdown
, &count
));
302 cl_assert_equal_i(-100, ret
);
304 git_config_free(cfg
);
307 void test_config_read__iterator(void)
310 git_config_iterator
*iter
;
311 git_config_entry
*entry
;
314 cl_git_pass(git_config_new(&cfg
));
315 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
316 GIT_CONFIG_LEVEL_SYSTEM
, 0));
317 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
318 GIT_CONFIG_LEVEL_GLOBAL
, 0));
321 cl_git_pass(git_config_iterator_new(&iter
, cfg
));
323 while ((ret
= git_config_next(&entry
, iter
)) == 0) {
327 git_config_iterator_free(iter
);
328 cl_assert_equal_i(GIT_ITEROVER
, ret
);
329 cl_assert_equal_i(7, count
);
332 cl_git_pass(git_config_iterator_new(&iter
, cfg
));
334 git_config_iterator_free(iter
);
335 git_config_free(cfg
);
338 static int count_cfg_entries(const git_config_entry
*entry
, void *payload
)
340 int *count
= payload
;
346 void test_config_read__foreach_match(void)
351 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
355 git_config_foreach_match(cfg
, "core.*", count_cfg_entries
, &count
));
356 cl_assert_equal_i(3, count
);
360 git_config_foreach_match(cfg
, "remote\\.ab.*", count_cfg_entries
, &count
));
361 cl_assert_equal_i(2, count
);
365 git_config_foreach_match(cfg
, ".*url$", count_cfg_entries
, &count
));
366 cl_assert_equal_i(2, count
);
370 git_config_foreach_match(cfg
, ".*dummy.*", count_cfg_entries
, &count
));
371 cl_assert_equal_i(2, count
);
375 git_config_foreach_match(cfg
, ".*nomatch.*", count_cfg_entries
, &count
));
376 cl_assert_equal_i(0, count
);
378 git_config_free(cfg
);
381 static void check_glob_iter(git_config
*cfg
, const char *regexp
, int expected
)
383 git_config_iterator
*iter
;
384 git_config_entry
*entry
;
387 cl_git_pass(git_config_iterator_glob_new(&iter
, cfg
, regexp
));
390 while ((error
= git_config_next(&entry
, iter
)) == 0)
393 cl_assert_equal_i(GIT_ITEROVER
, error
);
394 cl_assert_equal_i(expected
, count
);
395 git_config_iterator_free(iter
);
398 void test_config_read__iterator_invalid_glob(void)
401 git_config_iterator
*iter
;
403 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
405 cl_git_fail(git_config_iterator_glob_new(&iter
, cfg
, "*"));
407 git_config_free(cfg
);
410 void test_config_read__iterator_glob(void)
414 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
416 check_glob_iter(cfg
, "core.*", 3);
417 check_glob_iter(cfg
, "remote\\.ab.*", 2);
418 check_glob_iter(cfg
, ".*url$", 2);
419 check_glob_iter(cfg
, ".*dummy.*", 2);
420 check_glob_iter(cfg
, ".*nomatch.*", 0);
422 git_config_free(cfg
);
425 void test_config_read__whitespace_not_required_around_assignment(void)
429 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config14")));
431 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "a.b"));
432 cl_assert_equal_s("c", git_buf_cstr(&buf
));
435 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "d.e"));
436 cl_assert_equal_s("f", git_buf_cstr(&buf
));
438 git_config_free(cfg
);
441 void test_config_read__read_git_config_entry(void)
444 git_config_entry
*entry
;
446 cl_git_pass(git_config_new(&cfg
));
447 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
448 GIT_CONFIG_LEVEL_SYSTEM
, 0));
450 cl_git_pass(git_config_get_entry(&entry
, cfg
, "core.dummy2"));
451 cl_assert_equal_s("core.dummy2", entry
->name
);
452 cl_assert_equal_s("42", entry
->value
);
453 cl_assert_equal_i(GIT_CONFIG_LEVEL_SYSTEM
, entry
->level
);
455 git_config_entry_free(entry
);
456 git_config_free(cfg
);
460 * At the beginning of the test:
461 * - config9 has: core.dummy2=42
462 * - config15 has: core.dummy2=7
463 * - config16 has: core.dummy2=28
465 void test_config_read__local_config_overrides_global_config_overrides_system_config(void)
470 cl_git_pass(git_config_new(&cfg
));
471 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
472 GIT_CONFIG_LEVEL_SYSTEM
, 0));
473 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
474 GIT_CONFIG_LEVEL_GLOBAL
, 0));
475 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config16"),
476 GIT_CONFIG_LEVEL_LOCAL
, 0));
478 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.dummy2"));
479 cl_assert_equal_i(28, i
);
481 git_config_free(cfg
);
483 cl_git_pass(git_config_new(&cfg
));
484 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
485 GIT_CONFIG_LEVEL_SYSTEM
, 0));
486 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
487 GIT_CONFIG_LEVEL_GLOBAL
, 0));
489 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.dummy2"));
490 cl_assert_equal_i(7, i
);
492 git_config_free(cfg
);
496 * At the beginning of the test:
497 * - config9 has: core.global does not exist
498 * - config15 has: core.global=17
499 * - config16 has: core.global=29
502 * - config9 has: core.system does not exist
503 * - config15 has: core.system does not exist
504 * - config16 has: core.system=11
506 void test_config_read__fallback_from_local_to_global_and_from_global_to_system(void)
511 cl_git_pass(git_config_new(&cfg
));
512 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
513 GIT_CONFIG_LEVEL_SYSTEM
, 0));
514 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
515 GIT_CONFIG_LEVEL_GLOBAL
, 0));
516 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config16"),
517 GIT_CONFIG_LEVEL_LOCAL
, 0));
519 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.global"));
520 cl_assert_equal_i(17, i
);
521 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.system"));
522 cl_assert_equal_i(11, i
);
524 git_config_free(cfg
);
528 * At the beginning of the test, config18 has:
530 * int64global = 9223372036854775803
532 * stringglobal = I'm a global config value!
538 * stringglobal = don't find me!
541 void test_config_read__simple_read_from_specific_level(void)
543 git_config
*cfg
, *cfg_specific
;
545 int64_t l
, expected
= +9223372036854775803;
547 cl_git_pass(git_config_new(&cfg
));
548 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config18"),
549 GIT_CONFIG_LEVEL_GLOBAL
, 0));
550 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config19"),
551 GIT_CONFIG_LEVEL_SYSTEM
, 0));
553 cl_git_pass(git_config_open_level(&cfg_specific
, cfg
, GIT_CONFIG_LEVEL_GLOBAL
));
555 cl_git_pass(git_config_get_int32(&i
, cfg_specific
, "core.int32global"));
556 cl_assert_equal_i(28, i
);
557 cl_git_pass(git_config_get_int64(&l
, cfg_specific
, "core.int64global"));
558 cl_assert(l
== expected
);
559 cl_git_pass(git_config_get_bool(&i
, cfg_specific
, "core.boolglobal"));
560 cl_assert_equal_b(true, i
);
561 cl_git_pass(git_config_get_string_buf(&buf
, cfg_specific
, "core.stringglobal"));
562 cl_assert_equal_s("I'm a global config value!", git_buf_cstr(&buf
));
564 git_config_free(cfg_specific
);
565 git_config_free(cfg
);
568 void test_config_read__can_load_and_parse_an_empty_config_file(void)
573 cl_set_cleanup(&clean_test_config
, NULL
);
574 cl_git_mkfile("./testconfig", "");
575 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
576 cl_assert_equal_i(GIT_ENOTFOUND
, git_config_get_int32(&i
, cfg
, "nope.neither"));
578 git_config_free(cfg
);
581 void test_config_read__corrupt_header(void)
585 cl_set_cleanup(&clean_test_config
, NULL
);
586 cl_git_mkfile("./testconfig", "[sneaky ] \"quoted closing quote mark\\\"");
587 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
589 git_config_free(cfg
);
592 void test_config_read__corrupt_header2(void)
596 cl_set_cleanup(&clean_test_config
, NULL
);
597 cl_git_mkfile("./testconfig", "[unclosed \"bracket\"\n lib = git2\n");
598 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
600 git_config_free(cfg
);
603 void test_config_read__corrupt_header3(void)
607 cl_set_cleanup(&clean_test_config
, NULL
);
608 cl_git_mkfile("./testconfig", "[unclosed \"slash\\\"]\n lib = git2\n");
609 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
611 git_config_free(cfg
);
614 void test_config_read__override_variable(void)
618 cl_set_cleanup(&clean_test_config
, NULL
);
619 cl_git_mkfile("./testconfig", "[some] var = one\nvar = two");
620 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
622 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
623 cl_assert_equal_s("two", git_buf_cstr(&buf
));
625 git_config_free(cfg
);
628 void test_config_read__path(void)
631 git_buf path
= GIT_BUF_INIT
;
632 git_buf old_path
= GIT_BUF_INIT
;
633 git_buf home_path
= GIT_BUF_INIT
;
634 git_buf expected_path
= GIT_BUF_INIT
;
636 cl_git_pass(p_mkdir("fakehome", 0777));
637 cl_git_pass(git_path_prettify(&home_path
, "fakehome", NULL
));
638 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, &old_path
));
639 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, home_path
.ptr
));
640 cl_git_mkfile("./testconfig", "[some]\n path = ~/somefile");
641 cl_git_pass(git_path_join_unrooted(&expected_path
, "somefile", home_path
.ptr
, NULL
));
643 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
644 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
645 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
648 cl_git_mkfile("./testconfig", "[some]\n path = ~/");
649 cl_git_pass(git_path_join_unrooted(&expected_path
, "", home_path
.ptr
, NULL
));
651 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
652 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
655 cl_git_mkfile("./testconfig", "[some]\n path = ~");
656 cl_git_pass(git_buf_sets(&expected_path
, home_path
.ptr
));
658 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
659 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
662 cl_git_mkfile("./testconfig", "[some]\n path = ~user/foo");
663 cl_git_fail(git_config_get_path(&path
, cfg
, "some.path"));
665 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, old_path
.ptr
));
666 git_buf_free(&old_path
);
667 git_buf_free(&home_path
);
668 git_buf_free(&expected_path
);
669 git_config_free(cfg
);