Skip to content

Commit 4c715eb

Browse files
tanayabhgitster
authored andcommitted
test-config: add tests for the config_set API
Expose the `config_set` C API as a set of simple commands in order to facilitate testing. Add tests for the `config_set` API as well as for `git_config_get_*()` family for the usual config files. Signed-off-by: Matthieu Moy <[email protected]> Signed-off-by: Tanay Abhra <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3c8687a commit 4c715eb

File tree

4 files changed

+344
-0
lines changed

4 files changed

+344
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@
178178
/gitweb/static/gitweb.min.*
179179
/test-chmtime
180180
/test-ctype
181+
/test-config
181182
/test-date
182183
/test-delta
183184
/test-dump-cache-tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
551551

552552
TEST_PROGRAMS_NEED_X += test-chmtime
553553
TEST_PROGRAMS_NEED_X += test-ctype
554+
TEST_PROGRAMS_NEED_X += test-config
554555
TEST_PROGRAMS_NEED_X += test-date
555556
TEST_PROGRAMS_NEED_X += test-delta
556557
TEST_PROGRAMS_NEED_X += test-dump-cache-tree

t/t1308-config-set.sh

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
#!/bin/sh
2+
3+
test_description='Test git config-set API in different settings'
4+
5+
. ./test-lib.sh
6+
7+
# 'check_config get_* section.key value' verifies that the entry for
8+
# section.key is 'value'
9+
check_config () {
10+
if test "$1" = expect_code
11+
then
12+
expect_code="$2" && shift && shift
13+
else
14+
expect_code=0
15+
fi &&
16+
op=$1 key=$2 && shift && shift &&
17+
if test $# != 0
18+
then
19+
printf "%s\n" "$@"
20+
fi >expect &&
21+
test_expect_code $expect_code test-config "$op" "$key" >actual &&
22+
test_cmp expect actual
23+
}
24+
25+
test_expect_success 'setup default config' '
26+
cat >.git/config <<\EOF
27+
[case]
28+
penguin = very blue
29+
Movie = BadPhysics
30+
UPPERCASE = true
31+
MixedCase = true
32+
my =
33+
foo
34+
baz = sam
35+
[Cores]
36+
WhatEver = Second
37+
baz = bar
38+
[cores]
39+
baz = bat
40+
[CORES]
41+
baz = ball
42+
[my "Foo bAr"]
43+
hi = mixed-case
44+
[my "FOO BAR"]
45+
hi = upper-case
46+
[my "foo bar"]
47+
hi = lower-case
48+
[case]
49+
baz = bat
50+
baz = hask
51+
[lamb]
52+
chop = 65
53+
head = none
54+
[goat]
55+
legs = 4
56+
head = true
57+
skin = false
58+
nose = 1
59+
horns
60+
EOF
61+
'
62+
63+
test_expect_success 'get value for a simple key' '
64+
check_config get_value case.penguin "very blue"
65+
'
66+
67+
test_expect_success 'get value for a key with value as an empty string' '
68+
check_config get_value case.my ""
69+
'
70+
71+
test_expect_success 'get value for a key with value as NULL' '
72+
check_config get_value case.foo "(NULL)"
73+
'
74+
75+
test_expect_success 'upper case key' '
76+
check_config get_value case.UPPERCASE "true" &&
77+
check_config get_value case.uppercase "true"
78+
'
79+
80+
test_expect_success 'mixed case key' '
81+
check_config get_value case.MixedCase "true" &&
82+
check_config get_value case.MIXEDCASE "true" &&
83+
check_config get_value case.mixedcase "true"
84+
'
85+
86+
test_expect_success 'key and value with mixed case' '
87+
check_config get_value case.Movie "BadPhysics"
88+
'
89+
90+
test_expect_success 'key with case sensitive subsection' '
91+
check_config get_value "my.Foo bAr.hi" "mixed-case" &&
92+
check_config get_value "my.FOO BAR.hi" "upper-case" &&
93+
check_config get_value "my.foo bar.hi" "lower-case"
94+
'
95+
96+
test_expect_success 'key with case insensitive section header' '
97+
check_config get_value cores.baz "ball" &&
98+
check_config get_value Cores.baz "ball" &&
99+
check_config get_value CORES.baz "ball" &&
100+
check_config get_value coreS.baz "ball"
101+
'
102+
103+
test_expect_success 'key with case insensitive section header & variable' '
104+
check_config get_value CORES.BAZ "ball" &&
105+
check_config get_value cores.baz "ball" &&
106+
check_config get_value cores.BaZ "ball" &&
107+
check_config get_value cOreS.bAz "ball"
108+
'
109+
110+
test_expect_success 'find value with misspelled key' '
111+
check_config expect_code 1 get_value "my.fOo Bar.hi" "Value not found for \"my.fOo Bar.hi\""
112+
'
113+
114+
test_expect_success 'find value with the highest priority' '
115+
check_config get_value case.baz "hask"
116+
'
117+
118+
test_expect_success 'find integer value for a key' '
119+
check_config get_int lamb.chop 65
120+
'
121+
122+
test_expect_success 'find integer if value is non parse-able' '
123+
check_config expect_code 128 get_int lamb.head
124+
'
125+
126+
test_expect_success 'find bool value for the entered key' '
127+
check_config get_bool goat.head 1 &&
128+
check_config get_bool goat.skin 0 &&
129+
check_config get_bool goat.nose 1 &&
130+
check_config get_bool goat.horns 1 &&
131+
check_config get_bool goat.legs 1
132+
'
133+
134+
test_expect_success 'find multiple values' '
135+
check_config get_value_multi case.baz sam bat hask
136+
'
137+
138+
test_expect_success 'find value from a configset' '
139+
cat >config2 <<-\EOF &&
140+
[case]
141+
baz = lama
142+
[my]
143+
new = silk
144+
[case]
145+
baz = ball
146+
EOF
147+
echo silk >expect &&
148+
test-config configset_get_value my.new config2 .git/config >actual &&
149+
test_cmp expect actual
150+
'
151+
152+
test_expect_success 'find value with highest priority from a configset' '
153+
echo hask >expect &&
154+
test-config configset_get_value case.baz config2 .git/config >actual &&
155+
test_cmp expect actual
156+
'
157+
158+
test_expect_success 'find value_list for a key from a configset' '
159+
cat >except <<-\EOF &&
160+
sam
161+
bat
162+
hask
163+
lama
164+
ball
165+
EOF
166+
test-config configset_get_value case.baz config2 .git/config >actual &&
167+
test_cmp expect actual
168+
'
169+
170+
test_expect_success 'proper error on non-existent files' '
171+
echo "Error (-1) reading configuration file non-existent-file." >expect &&
172+
test_expect_code 2 test-config configset_get_value foo.bar non-existent-file 2>actual &&
173+
test_cmp expect actual
174+
'
175+
176+
test_expect_success POSIXPERM,SANITY 'proper error on non-accessible files' '
177+
chmod -r .git/config &&
178+
test_when_finished "chmod +r .git/config" &&
179+
echo "Error (-1) reading configuration file .git/config." >expect &&
180+
test_expect_code 2 test-config configset_get_value foo.bar .git/config 2>actual &&
181+
test_cmp expect actual
182+
'
183+
184+
test_expect_success 'proper error on error in default config files' '
185+
cp .git/config .git/config.old &&
186+
test_when_finished "mv .git/config.old .git/config" &&
187+
echo "[" >>.git/config &&
188+
echo "fatal: bad config file line 35 in .git/config" >expect &&
189+
test_expect_code 128 test-config get_value foo.bar 2>actual &&
190+
test_cmp expect actual
191+
'
192+
193+
test_expect_success 'proper error on error in custom config files' '
194+
echo "[" >>syntax-error &&
195+
echo "fatal: bad config file line 1 in syntax-error" >expect &&
196+
test_expect_code 128 test-config configset_get_value foo.bar syntax-error 2>actual &&
197+
test_cmp expect actual
198+
'
199+
200+
test_done

test-config.c

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#include "cache.h"
2+
#include "string-list.h"
3+
4+
/*
5+
* This program exposes the C API of the configuration mechanism
6+
* as a set of simple commands in order to facilitate testing.
7+
*
8+
* Reads stdin and prints result of command to stdout:
9+
*
10+
* get_value -> prints the value with highest priority for the entered key
11+
*
12+
* get_value_multi -> prints all values for the entered key in increasing order
13+
* of priority
14+
*
15+
* get_int -> print integer value for the entered key or die
16+
*
17+
* get_bool -> print bool value for the entered key or die
18+
*
19+
* configset_get_value -> returns value with the highest priority for the entered key
20+
* from a config_set constructed from files entered as arguments.
21+
*
22+
* configset_get_value_multi -> returns value_list for the entered key sorted in
23+
* ascending order of priority from a config_set
24+
* constructed from files entered as arguments.
25+
*
26+
* Examples:
27+
*
28+
* To print the value with highest priority for key "foo.bAr Baz.rock":
29+
* test-config get_value "foo.bAr Baz.rock"
30+
*
31+
*/
32+
33+
34+
int main(int argc, char **argv)
35+
{
36+
int i, val;
37+
const char *v;
38+
const struct string_list *strptr;
39+
struct config_set cs;
40+
git_configset_init(&cs);
41+
42+
if (argc < 2) {
43+
fprintf(stderr, "Please, provide a command name on the command-line\n");
44+
goto exit1;
45+
} else if (argc == 3 && !strcmp(argv[1], "get_value")) {
46+
if (!git_config_get_value(argv[2], &v)) {
47+
if (!v)
48+
printf("(NULL)\n");
49+
else
50+
printf("%s\n", v);
51+
goto exit0;
52+
} else {
53+
printf("Value not found for \"%s\"\n", argv[2]);
54+
goto exit1;
55+
}
56+
} else if (argc == 3 && !strcmp(argv[1], "get_value_multi")) {
57+
strptr = git_config_get_value_multi(argv[2]);
58+
if (strptr) {
59+
for (i = 0; i < strptr->nr; i++) {
60+
v = strptr->items[i].string;
61+
if (!v)
62+
printf("(NULL)\n");
63+
else
64+
printf("%s\n", v);
65+
}
66+
goto exit0;
67+
} else {
68+
printf("Value not found for \"%s\"\n", argv[2]);
69+
goto exit1;
70+
}
71+
} else if (argc == 3 && !strcmp(argv[1], "get_int")) {
72+
if (!git_config_get_int(argv[2], &val)) {
73+
printf("%d\n", val);
74+
goto exit0;
75+
} else {
76+
printf("Value not found for \"%s\"\n", argv[2]);
77+
goto exit1;
78+
}
79+
} else if (argc == 3 && !strcmp(argv[1], "get_bool")) {
80+
if (!git_config_get_bool(argv[2], &val)) {
81+
printf("%d\n", val);
82+
goto exit0;
83+
} else {
84+
printf("Value not found for \"%s\"\n", argv[2]);
85+
goto exit1;
86+
}
87+
} else if (!strcmp(argv[1], "configset_get_value")) {
88+
for (i = 3; i < argc; i++) {
89+
int err;
90+
if ((err = git_configset_add_file(&cs, argv[i]))) {
91+
fprintf(stderr, "Error (%d) reading configuration file %s.\n", err, argv[i]);
92+
goto exit2;
93+
}
94+
}
95+
if (!git_configset_get_value(&cs, argv[2], &v)) {
96+
if (!v)
97+
printf("(NULL)\n");
98+
else
99+
printf("%s\n", v);
100+
goto exit0;
101+
} else {
102+
printf("Value not found for \"%s\"\n", argv[2]);
103+
goto exit1;
104+
}
105+
} else if (!strcmp(argv[1], "configset_get_value_multi")) {
106+
for (i = 3; i < argc; i++) {
107+
int err;
108+
if ((err = git_configset_add_file(&cs, argv[i]))) {
109+
fprintf(stderr, "Error (%d) reading configuration file %s.\n", err, argv[i]);
110+
goto exit2;
111+
}
112+
}
113+
strptr = git_configset_get_value_multi(&cs, argv[2]);
114+
if (strptr) {
115+
for (i = 0; i < strptr->nr; i++) {
116+
v = strptr->items[i].string;
117+
if (!v)
118+
printf("(NULL)\n");
119+
else
120+
printf("%s\n", v);
121+
}
122+
goto exit0;
123+
} else {
124+
printf("Value not found for \"%s\"\n", argv[2]);
125+
goto exit1;
126+
}
127+
}
128+
129+
die("%s: Please check the syntax and the function name", argv[0]);
130+
131+
exit0:
132+
git_configset_clear(&cs);
133+
return 0;
134+
135+
exit1:
136+
git_configset_clear(&cs);
137+
return 1;
138+
139+
exit2:
140+
git_configset_clear(&cs);
141+
return 2;
142+
}

0 commit comments

Comments
 (0)