]>
Commit | Line | Data |
---|---|---|
7c3a4a7f BS |
1 | #include "clar_libgit2.h" |
2 | ||
3 | #include "odb.h" | |
22a2d3d5 | 4 | #include "futils.h" |
7c3a4a7f BS |
5 | #include "repository.h" |
6 | ||
7c3a4a7f BS |
7 | #define TEMP_REPO_FOLDER "temprepo/" |
8 | #define DISCOVER_FOLDER TEMP_REPO_FOLDER "discover.git" | |
9 | ||
10 | #define SUB_REPOSITORY_FOLDER_NAME "sub_repo" | |
11 | #define SUB_REPOSITORY_FOLDER DISCOVER_FOLDER "/" SUB_REPOSITORY_FOLDER_NAME | |
07afeb23 | 12 | #define SUB_REPOSITORY_GITDIR SUB_REPOSITORY_FOLDER "/.git" |
7c3a4a7f BS |
13 | #define SUB_REPOSITORY_FOLDER_SUB SUB_REPOSITORY_FOLDER "/sub" |
14 | #define SUB_REPOSITORY_FOLDER_SUB_SUB SUB_REPOSITORY_FOLDER_SUB "/subsub" | |
15 | #define SUB_REPOSITORY_FOLDER_SUB_SUB_SUB SUB_REPOSITORY_FOLDER_SUB_SUB "/subsubsub" | |
16 | ||
17 | #define REPOSITORY_ALTERNATE_FOLDER DISCOVER_FOLDER "/alternate_sub_repo" | |
18 | #define REPOSITORY_ALTERNATE_FOLDER_SUB REPOSITORY_ALTERNATE_FOLDER "/sub" | |
19 | #define REPOSITORY_ALTERNATE_FOLDER_SUB_SUB REPOSITORY_ALTERNATE_FOLDER_SUB "/subsub" | |
20 | #define REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB REPOSITORY_ALTERNATE_FOLDER_SUB_SUB "/subsubsub" | |
21 | ||
22 | #define ALTERNATE_MALFORMED_FOLDER1 DISCOVER_FOLDER "/alternate_malformed_repo1" | |
23 | #define ALTERNATE_MALFORMED_FOLDER2 DISCOVER_FOLDER "/alternate_malformed_repo2" | |
24 | #define ALTERNATE_MALFORMED_FOLDER3 DISCOVER_FOLDER "/alternate_malformed_repo3" | |
25 | #define ALTERNATE_NOT_FOUND_FOLDER DISCOVER_FOLDER "/alternate_not_found_repo" | |
26 | ||
b1731215 | 27 | static void ensure_repository_discover(const char *start_path, |
07afeb23 PS |
28 | const char *ceiling_dirs, |
29 | const char *expected_path) | |
7c3a4a7f | 30 | { |
e579e0f7 MB |
31 | git_buf found_path = GIT_BUF_INIT; |
32 | git_str resolved = GIT_STR_INIT; | |
07afeb23 | 33 | |
e579e0f7 | 34 | git_str_attach(&resolved, p_realpath(expected_path, NULL), 0); |
07afeb23 | 35 | cl_assert(resolved.size > 0); |
e579e0f7 | 36 | cl_git_pass(git_fs_path_to_dir(&resolved)); |
ffd264d9 | 37 | cl_git_pass(git_repository_discover(&found_path, start_path, 1, ceiling_dirs)); |
07afeb23 PS |
38 | |
39 | cl_assert_equal_s(found_path.ptr, resolved.ptr); | |
40 | ||
e579e0f7 | 41 | git_str_dispose(&resolved); |
ac3d33df | 42 | git_buf_dispose(&found_path); |
7c3a4a7f BS |
43 | } |
44 | ||
270303ca | 45 | static void write_file(const char *path, const char *content) |
7c3a4a7f | 46 | { |
7c3a4a7f | 47 | git_file file; |
4dbaf3cd | 48 | int error; |
7c3a4a7f | 49 | |
e579e0f7 | 50 | if (git_fs_path_exists(path)) { |
270303ca | 51 | cl_git_pass(p_unlink(path)); |
7c3a4a7f BS |
52 | } |
53 | ||
54 | file = git_futils_creat_withpath(path, 0777, 0666); | |
270303ca | 55 | cl_assert(file >= 0); |
7c3a4a7f BS |
56 | |
57 | error = p_write(file, content, strlen(content) * sizeof(char)); | |
7c3a4a7f | 58 | p_close(file); |
270303ca | 59 | cl_git_pass(error); |
7c3a4a7f BS |
60 | } |
61 | ||
ac3d33df | 62 | /*no check is performed on ceiling_dirs length, so be sure it's long enough */ |
e579e0f7 | 63 | static void append_ceiling_dir(git_str *ceiling_dirs, const char *path) |
7c3a4a7f | 64 | { |
e579e0f7 | 65 | git_str pretty_path = GIT_STR_INIT; |
7c3a4a7f BS |
66 | char ceiling_separator[2] = { GIT_PATH_LIST_SEPARATOR, '\0' }; |
67 | ||
e579e0f7 | 68 | cl_git_pass(git_fs_path_prettify_dir(&pretty_path, path, NULL)); |
7c3a4a7f BS |
69 | |
70 | if (ceiling_dirs->size > 0) | |
e579e0f7 | 71 | git_str_puts(ceiling_dirs, ceiling_separator); |
946a6dc4 | 72 | |
e579e0f7 | 73 | git_str_puts(ceiling_dirs, pretty_path.ptr); |
946a6dc4 | 74 | |
e579e0f7 MB |
75 | git_str_dispose(&pretty_path); |
76 | cl_assert(git_str_oom(ceiling_dirs) == 0); | |
7c3a4a7f BS |
77 | } |
78 | ||
5242c424 | 79 | static git_buf discovered; |
e579e0f7 | 80 | static git_str ceiling_dirs; |
5242c424 | 81 | |
2382b0f8 | 82 | void test_repo_discover__initialize(void) |
7c3a4a7f | 83 | { |
7c3a4a7f | 84 | git_repository *repo; |
7c3a4a7f | 85 | const mode_t mode = 0777; |
ac2fba0e | 86 | git_futils_mkdir_r(DISCOVER_FOLDER, mode); |
7c3a4a7f | 87 | |
e579e0f7 | 88 | git_str_init(&ceiling_dirs, 0); |
5242c424 PS |
89 | append_ceiling_dir(&ceiling_dirs, TEMP_REPO_FOLDER); |
90 | ||
7c3a4a7f | 91 | cl_git_pass(git_repository_init(&repo, DISCOVER_FOLDER, 1)); |
7c3a4a7f BS |
92 | git_repository_free(repo); |
93 | ||
94 | cl_git_pass(git_repository_init(&repo, SUB_REPOSITORY_FOLDER, 0)); | |
ac2fba0e | 95 | cl_git_pass(git_futils_mkdir_r(SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, mode)); |
ac2fba0e | 96 | cl_git_pass(git_futils_mkdir_r(SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, mode)); |
7c3a4a7f | 97 | |
ac2fba0e | 98 | cl_git_pass(git_futils_mkdir_r(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB, mode)); |
270303ca BS |
99 | write_file(REPOSITORY_ALTERNATE_FOLDER "/" DOT_GIT, "gitdir: ../" SUB_REPOSITORY_FOLDER_NAME "/" DOT_GIT); |
100 | write_file(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB "/" DOT_GIT, "gitdir: ../../../" SUB_REPOSITORY_FOLDER_NAME "/" DOT_GIT); | |
101 | write_file(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB "/" DOT_GIT, "gitdir: ../../../../"); | |
7c3a4a7f | 102 | |
ac2fba0e | 103 | cl_git_pass(git_futils_mkdir_r(ALTERNATE_MALFORMED_FOLDER1, mode)); |
270303ca | 104 | write_file(ALTERNATE_MALFORMED_FOLDER1 "/" DOT_GIT, "Anything but not gitdir:"); |
ac2fba0e | 105 | cl_git_pass(git_futils_mkdir_r(ALTERNATE_MALFORMED_FOLDER2, mode)); |
270303ca | 106 | write_file(ALTERNATE_MALFORMED_FOLDER2 "/" DOT_GIT, "gitdir:"); |
ac2fba0e | 107 | cl_git_pass(git_futils_mkdir_r(ALTERNATE_MALFORMED_FOLDER3, mode)); |
270303ca | 108 | write_file(ALTERNATE_MALFORMED_FOLDER3 "/" DOT_GIT, "gitdir: \n\n\n"); |
ac2fba0e | 109 | cl_git_pass(git_futils_mkdir_r(ALTERNATE_NOT_FOUND_FOLDER, mode)); |
270303ca | 110 | write_file(ALTERNATE_NOT_FOUND_FOLDER "/" DOT_GIT, "gitdir: a_repository_that_surely_does_not_exist"); |
2382b0f8 PS |
111 | |
112 | git_repository_free(repo); | |
113 | } | |
114 | ||
115 | void test_repo_discover__cleanup(void) | |
116 | { | |
ac3d33df | 117 | git_buf_dispose(&discovered); |
e579e0f7 | 118 | git_str_dispose(&ceiling_dirs); |
2382b0f8 PS |
119 | cl_git_pass(git_futils_rmdir_r(TEMP_REPO_FOLDER, NULL, GIT_RMDIR_REMOVE_FILES)); |
120 | } | |
121 | ||
5242c424 | 122 | void test_repo_discover__discovering_repo_with_exact_path_succeeds(void) |
2382b0f8 | 123 | { |
5242c424 PS |
124 | cl_git_pass(git_repository_discover(&discovered, DISCOVER_FOLDER, 0, ceiling_dirs.ptr)); |
125 | cl_git_pass(git_repository_discover(&discovered, SUB_REPOSITORY_FOLDER, 0, ceiling_dirs.ptr)); | |
126 | } | |
2382b0f8 | 127 | |
5242c424 PS |
128 | void test_repo_discover__discovering_nonexistent_dir_fails(void) |
129 | { | |
130 | cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&discovered, DISCOVER_FOLDER "-nonexistent", 0, NULL)); | |
131 | } | |
2382b0f8 | 132 | |
5242c424 PS |
133 | void test_repo_discover__discovering_repo_with_subdirectory_succeeds(void) |
134 | { | |
135 | ensure_repository_discover(SUB_REPOSITORY_FOLDER_SUB, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
136 | ensure_repository_discover(SUB_REPOSITORY_FOLDER_SUB_SUB, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
137 | ensure_repository_discover(SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
138 | } | |
2382b0f8 | 139 | |
5242c424 PS |
140 | void test_repo_discover__discovering_repository_with_alternative_gitdir_succeeds(void) |
141 | { | |
142 | ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
143 | ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
144 | ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
145 | ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB, ceiling_dirs.ptr, DISCOVER_FOLDER); | |
146 | } | |
147 | ||
148 | void test_repo_discover__discovering_repository_with_malformed_alternative_gitdir_fails(void) | |
149 | { | |
150 | cl_git_fail(git_repository_discover(&discovered, ALTERNATE_MALFORMED_FOLDER1, 0, ceiling_dirs.ptr)); | |
151 | cl_git_fail(git_repository_discover(&discovered, ALTERNATE_MALFORMED_FOLDER2, 0, ceiling_dirs.ptr)); | |
152 | cl_git_fail(git_repository_discover(&discovered, ALTERNATE_MALFORMED_FOLDER3, 0, ceiling_dirs.ptr)); | |
153 | cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&discovered, ALTERNATE_NOT_FOUND_FOLDER, 0, ceiling_dirs.ptr)); | |
154 | } | |
2382b0f8 | 155 | |
5242c424 PS |
156 | void test_repo_discover__discovering_repository_with_ceiling(void) |
157 | { | |
158 | append_ceiling_dir(&ceiling_dirs, SUB_REPOSITORY_FOLDER_SUB); | |
2382b0f8 | 159 | |
5242c424 PS |
160 | /* this must pass as ceiling_directories cannot prevent the current |
161 | * working directory to be checked */ | |
162 | ensure_repository_discover(SUB_REPOSITORY_FOLDER, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
2382b0f8 | 163 | |
5242c424 PS |
164 | ensure_repository_discover(SUB_REPOSITORY_FOLDER_SUB, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); |
165 | cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&discovered, SUB_REPOSITORY_FOLDER_SUB_SUB, 0, ceiling_dirs.ptr)); | |
166 | cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&discovered, SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, 0, ceiling_dirs.ptr)); | |
167 | } | |
7c3a4a7f | 168 | |
5242c424 PS |
169 | void test_repo_discover__other_ceiling(void) |
170 | { | |
171 | append_ceiling_dir(&ceiling_dirs, SUB_REPOSITORY_FOLDER); | |
ed577134 | 172 | |
5242c424 | 173 | /* this must pass as ceiling_directories cannot predent the current |
ed577134 | 174 | * working directory to be checked */ |
5242c424 PS |
175 | ensure_repository_discover(SUB_REPOSITORY_FOLDER, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); |
176 | ||
177 | cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&discovered, SUB_REPOSITORY_FOLDER_SUB, 0, ceiling_dirs.ptr)); | |
178 | cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&discovered, SUB_REPOSITORY_FOLDER_SUB_SUB, 0, ceiling_dirs.ptr)); | |
179 | cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&discovered, SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, 0, ceiling_dirs.ptr)); | |
7c3a4a7f BS |
180 | } |
181 | ||
5242c424 PS |
182 | void test_repo_discover__ceiling_should_not_affect_gitdir_redirection(void) |
183 | { | |
184 | append_ceiling_dir(&ceiling_dirs, SUB_REPOSITORY_FOLDER); | |
185 | ||
186 | /* gitfile redirection should not be affected by ceiling directories */ | |
187 | ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
188 | ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
189 | ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB, ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
190 | ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB, ceiling_dirs.ptr, DISCOVER_FOLDER); | |
191 | } | |
0f316096 PS |
192 | |
193 | void test_repo_discover__discovery_starting_at_file_succeeds(void) | |
194 | { | |
195 | int fd; | |
196 | ||
197 | cl_assert((fd = p_creat(SUB_REPOSITORY_FOLDER "/file", 0600)) >= 0); | |
198 | cl_assert(p_close(fd) == 0); | |
199 | ||
200 | ensure_repository_discover(SUB_REPOSITORY_FOLDER "/file", ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); | |
201 | } | |
3428a523 PS |
202 | |
203 | void test_repo_discover__discovery_starting_at_system_root_causes_no_hang(void) | |
204 | { | |
205 | #ifdef GIT_WIN32 | |
206 | git_buf out = GIT_BUF_INIT; | |
207 | cl_git_fail(git_repository_discover(&out, "C:/", 0, NULL)); | |
208 | cl_git_fail(git_repository_discover(&out, "//localhost/", 0, NULL)); | |
209 | #endif | |
210 | } |