]> git.proxmox.com Git - libgit2.git/blob - tests/core/env.c
Merge pull request #2178 from libgit2/rb/fix-short-id
[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\x9cx80ke_\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 const char *original = cl_getenv(env_vars[i]);
35 #ifdef GIT_WIN32
36 env_save[i] = (char *)original;
37 #else
38 env_save[i] = original ? git__strdup(original) : NULL;
39 #endif
40 }
41 }
42
43 static void reset_global_search_path(void)
44 {
45 cl_git_pass(git_sysdir_set(GIT_SYSDIR_GLOBAL, NULL));
46 }
47
48 static void reset_system_search_path(void)
49 {
50 cl_git_pass(git_sysdir_set(GIT_SYSDIR_SYSTEM, NULL));
51 }
52
53 void test_core_env__cleanup(void)
54 {
55 int i;
56 char **val;
57
58 for (i = 0; i < NUM_VARS; ++i) {
59 cl_setenv(env_vars[i], env_save[i]);
60 git__free(env_save[i]);
61 env_save[i] = NULL;
62 }
63
64 /* these will probably have already been cleaned up, but if a test
65 * fails, then it's probably good to try and clear out these dirs
66 */
67 for (val = home_values; *val != NULL; val++) {
68 if (**val != '\0')
69 (void)p_rmdir(*val);
70 }
71
72 /* reset search paths to default */
73 reset_global_search_path();
74 reset_system_search_path();
75 }
76
77 static void setenv_and_check(const char *name, const char *value)
78 {
79 char *check;
80
81 cl_git_pass(cl_setenv(name, value));
82
83 check = cl_getenv(name);
84 cl_assert_equal_s(value, check);
85 #ifdef GIT_WIN32
86 git__free(check);
87 #endif
88 }
89
90 void test_core_env__0(void)
91 {
92 git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT;
93 char testfile[16], tidx = '0';
94 char **val;
95 const char *testname = "testfile";
96 size_t testlen = strlen(testname);
97
98 strncpy(testfile, testname, sizeof(testfile));
99 cl_assert_equal_s(testname, testfile);
100
101 for (val = home_values; *val != NULL; val++) {
102
103 /* if we can't make the directory, let's just assume
104 * we are on a filesystem that doesn't support the
105 * characters in question and skip this test...
106 */
107 if (p_mkdir(*val, 0777) != 0) {
108 *val = ""; /* mark as not created */
109 continue;
110 }
111
112 cl_git_pass(git_path_prettify(&path, *val, NULL));
113
114 /* vary testfile name in each directory so accidentally leaving
115 * an environment variable set from a previous iteration won't
116 * accidentally make this test pass...
117 */
118 testfile[testlen] = tidx++;
119 cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile));
120 cl_git_mkfile(path.ptr, "find me");
121 git_buf_rtruncate_at_char(&path, '/');
122
123 cl_assert_equal_i(
124 GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
125
126 setenv_and_check("HOME", path.ptr);
127 reset_global_search_path();
128
129 cl_git_pass(git_sysdir_find_global_file(&found, testfile));
130
131 cl_setenv("HOME", env_save[0]);
132 reset_global_search_path();
133
134 cl_assert_equal_i(
135 GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
136
137 #ifdef GIT_WIN32
138 setenv_and_check("HOMEDRIVE", NULL);
139 setenv_and_check("HOMEPATH", NULL);
140 setenv_and_check("USERPROFILE", path.ptr);
141 reset_global_search_path();
142
143 cl_git_pass(git_sysdir_find_global_file(&found, testfile));
144
145 {
146 int root = git_path_root(path.ptr);
147 char old;
148
149 if (root >= 0) {
150 setenv_and_check("USERPROFILE", NULL);
151 reset_global_search_path();
152
153 cl_assert_equal_i(
154 GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
155
156 old = path.ptr[root];
157 path.ptr[root] = '\0';
158 setenv_and_check("HOMEDRIVE", path.ptr);
159 path.ptr[root] = old;
160 setenv_and_check("HOMEPATH", &path.ptr[root]);
161 reset_global_search_path();
162
163 cl_git_pass(git_sysdir_find_global_file(&found, testfile));
164 }
165 }
166 #endif
167
168 (void)p_rmdir(*val);
169 }
170
171 git_buf_free(&path);
172 git_buf_free(&found);
173 }
174
175
176 void test_core_env__1(void)
177 {
178 git_buf path = GIT_BUF_INIT;
179
180 cl_assert_equal_i(
181 GIT_ENOTFOUND, git_sysdir_find_global_file(&path, "nonexistentfile"));
182
183 cl_git_pass(cl_setenv("HOME", "doesnotexist"));
184 #ifdef GIT_WIN32
185 cl_git_pass(cl_setenv("HOMEPATH", "doesnotexist"));
186 cl_git_pass(cl_setenv("USERPROFILE", "doesnotexist"));
187 #endif
188 reset_global_search_path();
189
190 cl_assert_equal_i(
191 GIT_ENOTFOUND, git_sysdir_find_global_file(&path, "nonexistentfile"));
192
193 cl_git_pass(cl_setenv("HOME", NULL));
194 #ifdef GIT_WIN32
195 cl_git_pass(cl_setenv("HOMEPATH", NULL));
196 cl_git_pass(cl_setenv("USERPROFILE", NULL));
197 #endif
198 reset_global_search_path();
199 reset_system_search_path();
200
201 cl_assert_equal_i(
202 GIT_ENOTFOUND, git_sysdir_find_global_file(&path, "nonexistentfile"));
203
204 cl_assert_equal_i(
205 GIT_ENOTFOUND, git_sysdir_find_system_file(&path, "nonexistentfile"));
206
207 #ifdef GIT_WIN32
208 cl_git_pass(cl_setenv("PROGRAMFILES", NULL));
209 reset_system_search_path();
210
211 cl_assert_equal_i(
212 GIT_ENOTFOUND, git_sysdir_find_system_file(&path, "nonexistentfile"));
213 #endif
214
215 git_buf_free(&path);
216 }
217
218 static void check_global_searchpath(
219 const char *path, int position, const char *file, git_buf *temp)
220 {
221 git_buf out = GIT_BUF_INIT;
222
223 /* build and set new path */
224 if (position < 0)
225 cl_git_pass(git_buf_join(temp, GIT_PATH_LIST_SEPARATOR, path, "$PATH"));
226 else if (position > 0)
227 cl_git_pass(git_buf_join(temp, GIT_PATH_LIST_SEPARATOR, "$PATH", path));
228 else
229 cl_git_pass(git_buf_sets(temp, path));
230
231 cl_git_pass(git_libgit2_opts(
232 GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, temp->ptr));
233
234 /* get path and make sure $PATH expansion worked */
235 cl_git_pass(git_libgit2_opts(
236 GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &out));
237
238 if (position < 0)
239 cl_assert(git__prefixcmp(out.ptr, path) == 0);
240 else if (position > 0)
241 cl_assert(git__suffixcmp(out.ptr, path) == 0);
242 else
243 cl_assert_equal_s(out.ptr, path);
244
245 /* find file using new path */
246 cl_git_pass(git_sysdir_find_global_file(temp, file));
247
248 /* reset path and confirm file not found */
249 cl_git_pass(git_libgit2_opts(
250 GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL));
251 cl_assert_equal_i(
252 GIT_ENOTFOUND, git_sysdir_find_global_file(temp, file));
253
254 git_buf_free(&out);
255 }
256
257 void test_core_env__2(void)
258 {
259 git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT;
260 char testfile[16], tidx = '0';
261 char **val;
262 const char *testname = "alternate";
263 size_t testlen = strlen(testname);
264
265 strncpy(testfile, testname, sizeof(testfile));
266 cl_assert_equal_s(testname, testfile);
267
268 for (val = home_values; *val != NULL; val++) {
269
270 /* if we can't make the directory, let's just assume
271 * we are on a filesystem that doesn't support the
272 * characters in question and skip this test...
273 */
274 if (p_mkdir(*val, 0777) != 0 && errno != EEXIST) {
275 *val = ""; /* mark as not created */
276 continue;
277 }
278
279 cl_git_pass(git_path_prettify(&path, *val, NULL));
280
281 /* vary testfile name so any sloppiness is resetting variables or
282 * deleting files won't accidentally make a test pass.
283 */
284 testfile[testlen] = tidx++;
285 cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile));
286 cl_git_mkfile(path.ptr, "find me");
287 git_buf_rtruncate_at_char(&path, '/');
288
289 /* default should be NOTFOUND */
290 cl_assert_equal_i(
291 GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
292
293 /* try plain, append $PATH, and prepend $PATH */
294 check_global_searchpath(path.ptr, 0, testfile, &found);
295 check_global_searchpath(path.ptr, -1, testfile, &found);
296 check_global_searchpath(path.ptr, 1, testfile, &found);
297
298 /* cleanup */
299 cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile));
300 (void)p_unlink(path.ptr);
301 (void)p_rmdir(*val);
302 }
303
304 git_buf_free(&path);
305 git_buf_free(&found);
306 }