]> git.proxmox.com Git - libgit2.git/blob - tests/core/env.c
7e7b3274dec8997c03c87272f9207a5806eb7c98
[libgit2.git] / tests / core / env.c
1 #include "clar_libgit2.h"
2 #include "fileops.h"
3 #include "sysdir.h"
4 #include "path.h"
5
6 #ifdef GIT_WIN32
7 #define NUM_VARS 5
8 static const char *env_vars[NUM_VARS] = {
9 "HOME", "HOMEDRIVE", "HOMEPATH", "USERPROFILE", "PROGRAMFILES"
10 };
11 #else
12 #define NUM_VARS 1
13 static const char *env_vars[NUM_VARS] = { "HOME" };
14 #endif
15
16 static char *env_save[NUM_VARS];
17
18 static char *home_values[] = {
19 "fake_home",
20 "f\xc3\xa1ke_h\xc3\xb5me", /* all in latin-1 supplement */
21 "f\xc4\x80ke_\xc4\xa4ome", /* latin extended */
22 "f\xce\xb1\xce\xba\xce\xb5_h\xce\xbfm\xce\xad", /* having fun with greek */
23 "fa\xe0" "\xb8" "\x87" "e_\xe0" "\xb8" "\x99" "ome", /* thai characters */
24 "f\xe1\x9c\x80ke_\xe1\x9c\x91ome", /* tagalog characters */
25 "\xe1\xb8\x9f\xe1\xba\xa2" "ke_ho" "\xe1" "\xb9" "\x81" "e", /* latin extended additional */
26 "\xf0\x9f\x98\x98\xf0\x9f\x98\x82", /* emoticons */
27 NULL
28 };
29
30 void test_core_env__initialize(void)
31 {
32 int i;
33 for (i = 0; i < NUM_VARS; ++i)
34 env_save[i] = cl_getenv(env_vars[i]);
35 }
36
37 static void set_global_search_path_from_env(void)
38 {
39 cl_git_pass(git_sysdir_set(GIT_SYSDIR_GLOBAL, NULL));
40 }
41
42 static void set_system_search_path_from_env(void)
43 {
44 cl_git_pass(git_sysdir_set(GIT_SYSDIR_SYSTEM, NULL));
45 }
46
47 void test_core_env__cleanup(void)
48 {
49 int i;
50 char **val;
51
52 for (i = 0; i < NUM_VARS; ++i) {
53 cl_setenv(env_vars[i], env_save[i]);
54 git__free(env_save[i]);
55 env_save[i] = NULL;
56 }
57
58 /* these will probably have already been cleaned up, but if a test
59 * fails, then it's probably good to try and clear out these dirs
60 */
61 for (val = home_values; *val != NULL; val++) {
62 if (**val != '\0')
63 (void)p_rmdir(*val);
64 }
65
66 cl_sandbox_set_search_path_defaults();
67 }
68
69 static void setenv_and_check(const char *name, const char *value)
70 {
71 char *check;
72
73 cl_git_pass(cl_setenv(name, value));
74 check = cl_getenv(name);
75
76 if (value)
77 cl_assert_equal_s(value, check);
78 else
79 cl_assert(check == NULL);
80
81 git__free(check);
82 }
83
84 void test_core_env__0(void)
85 {
86 git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT;
87 char testfile[16], tidx = '0';
88 char **val;
89 const char *testname = "testfile";
90 size_t testlen = strlen(testname);
91
92 strncpy(testfile, testname, sizeof(testfile));
93 cl_assert_equal_s(testname, testfile);
94
95 for (val = home_values; *val != NULL; val++) {
96
97 /* if we can't make the directory, let's just assume
98 * we are on a filesystem that doesn't support the
99 * characters in question and skip this test...
100 */
101 if (p_mkdir(*val, 0777) != 0) {
102 *val = ""; /* mark as not created */
103 continue;
104 }
105
106 cl_git_pass(git_path_prettify(&path, *val, NULL));
107
108 /* vary testfile name in each directory so accidentally leaving
109 * an environment variable set from a previous iteration won't
110 * accidentally make this test pass...
111 */
112 testfile[testlen] = tidx++;
113 cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile));
114 cl_git_mkfile(path.ptr, "find me");
115 git_buf_rtruncate_at_char(&path, '/');
116
117 cl_assert_equal_i(
118 GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
119
120 setenv_and_check("HOME", path.ptr);
121 set_global_search_path_from_env();
122
123 cl_git_pass(git_sysdir_find_global_file(&found, testfile));
124
125 cl_setenv("HOME", env_save[0]);
126 set_global_search_path_from_env();
127
128 cl_assert_equal_i(
129 GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
130
131 #ifdef GIT_WIN32
132 setenv_and_check("HOMEDRIVE", NULL);
133 setenv_and_check("HOMEPATH", NULL);
134 setenv_and_check("USERPROFILE", path.ptr);
135 set_global_search_path_from_env();
136
137 cl_git_pass(git_sysdir_find_global_file(&found, testfile));
138
139 {
140 int root = git_path_root(path.ptr);
141 char old;
142
143 if (root >= 0) {
144 setenv_and_check("USERPROFILE", NULL);
145 set_global_search_path_from_env();
146
147 cl_assert_equal_i(
148 GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
149
150 old = path.ptr[root];
151 path.ptr[root] = '\0';
152 setenv_and_check("HOMEDRIVE", path.ptr);
153 path.ptr[root] = old;
154 setenv_and_check("HOMEPATH", &path.ptr[root]);
155 set_global_search_path_from_env();
156
157 cl_git_pass(git_sysdir_find_global_file(&found, testfile));
158 }
159 }
160 #endif
161
162 (void)p_rmdir(*val);
163 }
164
165 git_buf_dispose(&path);
166 git_buf_dispose(&found);
167 }
168
169
170 void test_core_env__1(void)
171 {
172 git_buf path = GIT_BUF_INIT;
173
174 cl_assert_equal_i(
175 GIT_ENOTFOUND, git_sysdir_find_global_file(&path, "nonexistentfile"));
176
177 cl_git_pass(cl_setenv("HOME", "doesnotexist"));
178 #ifdef GIT_WIN32
179 cl_git_pass(cl_setenv("HOMEPATH", "doesnotexist"));
180 cl_git_pass(cl_setenv("USERPROFILE", "doesnotexist"));
181 #endif
182 set_global_search_path_from_env();
183
184 cl_assert_equal_i(
185 GIT_ENOTFOUND, git_sysdir_find_global_file(&path, "nonexistentfile"));
186
187 cl_git_pass(cl_setenv("HOME", NULL));
188 #ifdef GIT_WIN32
189 cl_git_pass(cl_setenv("HOMEPATH", NULL));
190 cl_git_pass(cl_setenv("USERPROFILE", NULL));
191 #endif
192 set_global_search_path_from_env();
193 set_system_search_path_from_env();
194
195 cl_assert_equal_i(
196 GIT_ENOTFOUND, git_sysdir_find_global_file(&path, "nonexistentfile"));
197
198 cl_assert_equal_i(
199 GIT_ENOTFOUND, git_sysdir_find_system_file(&path, "nonexistentfile"));
200
201 #ifdef GIT_WIN32
202 cl_git_pass(cl_setenv("PROGRAMFILES", NULL));
203 set_system_search_path_from_env();
204
205 cl_assert_equal_i(
206 GIT_ENOTFOUND, git_sysdir_find_system_file(&path, "nonexistentfile"));
207 #endif
208
209 git_buf_dispose(&path);
210 }
211
212 static void check_global_searchpath(
213 const char *path, int position, const char *file, git_buf *temp)
214 {
215 git_buf out = GIT_BUF_INIT;
216
217 /* build and set new path */
218 if (position < 0)
219 cl_git_pass(git_buf_join(temp, GIT_PATH_LIST_SEPARATOR, path, "$PATH"));
220 else if (position > 0)
221 cl_git_pass(git_buf_join(temp, GIT_PATH_LIST_SEPARATOR, "$PATH", path));
222 else
223 cl_git_pass(git_buf_sets(temp, path));
224
225 cl_git_pass(git_libgit2_opts(
226 GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, temp->ptr));
227
228 /* get path and make sure $PATH expansion worked */
229 cl_git_pass(git_libgit2_opts(
230 GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &out));
231
232 if (position < 0)
233 cl_assert(git__prefixcmp(out.ptr, path) == 0);
234 else if (position > 0)
235 cl_assert(git__suffixcmp(out.ptr, path) == 0);
236 else
237 cl_assert_equal_s(out.ptr, path);
238
239 /* find file using new path */
240 cl_git_pass(git_sysdir_find_global_file(temp, file));
241
242 /* reset path and confirm file not found */
243 cl_git_pass(git_libgit2_opts(
244 GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL));
245 cl_assert_equal_i(
246 GIT_ENOTFOUND, git_sysdir_find_global_file(temp, file));
247
248 git_buf_dispose(&out);
249 }
250
251 void test_core_env__2(void)
252 {
253 git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT;
254 char testfile[16], tidx = '0';
255 char **val;
256 const char *testname = "alternate";
257 size_t testlen = strlen(testname);
258
259 strncpy(testfile, testname, sizeof(testfile));
260 cl_assert_equal_s(testname, testfile);
261
262 for (val = home_values; *val != NULL; val++) {
263
264 /* if we can't make the directory, let's just assume
265 * we are on a filesystem that doesn't support the
266 * characters in question and skip this test...
267 */
268 if (p_mkdir(*val, 0777) != 0 && errno != EEXIST) {
269 *val = ""; /* mark as not created */
270 continue;
271 }
272
273 cl_git_pass(git_path_prettify(&path, *val, NULL));
274
275 /* vary testfile name so any sloppiness is resetting variables or
276 * deleting files won't accidentally make a test pass.
277 */
278 testfile[testlen] = tidx++;
279 cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile));
280 cl_git_mkfile(path.ptr, "find me");
281 git_buf_rtruncate_at_char(&path, '/');
282
283 /* default should be NOTFOUND */
284 cl_assert_equal_i(
285 GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
286
287 /* try plain, append $PATH, and prepend $PATH */
288 check_global_searchpath(path.ptr, 0, testfile, &found);
289 check_global_searchpath(path.ptr, -1, testfile, &found);
290 check_global_searchpath(path.ptr, 1, testfile, &found);
291
292 /* cleanup */
293 cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile));
294 (void)p_unlink(path.ptr);
295 (void)p_rmdir(*val);
296 }
297
298 git_buf_dispose(&path);
299 git_buf_dispose(&found);
300 }
301
302 void test_core_env__substitution(void)
303 {
304 git_buf buf = GIT_BUF_INIT, expected = GIT_BUF_INIT;
305
306 /* Set it to something non-default so we have controllable values */
307 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, "/tmp/a"));
308 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &buf));
309 cl_assert_equal_s("/tmp/a", buf.ptr);
310
311 git_buf_clear(&buf);
312 cl_git_pass(git_buf_join(&buf, GIT_PATH_LIST_SEPARATOR, "$PATH", "/tmp/b"));
313 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, buf.ptr));
314 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &buf));
315
316 cl_git_pass(git_buf_join(&expected, GIT_PATH_LIST_SEPARATOR, "/tmp/a", "/tmp/b"));
317 cl_assert_equal_s(expected.ptr, buf.ptr);
318
319 git_buf_dispose(&expected);
320 git_buf_dispose(&buf);
321 }