]>
Commit | Line | Data |
---|---|---|
b47349b8 RB |
1 | #include "clar_libgit2.h" |
2 | #include "posix.h" | |
3 | #include "blob.h" | |
4 | #include "filter.h" | |
b47349b8 RB |
5 | #include "git2/sys/filter.h" |
6 | #include "git2/sys/repository.h" | |
63924435 | 7 | #include "custom_helpers.h" |
b47349b8 | 8 | |
eefc32d5 RB |
9 | /* going TO_WORKDIR, filters are executed low to high |
10 | * going TO_ODB, filters are executed high to low | |
11 | */ | |
12 | #define BITFLIP_FILTER_PRIORITY -1 | |
13 | #define REVERSE_FILTER_PRIORITY -2 | |
b47349b8 | 14 | |
b47349b8 RB |
15 | #ifdef GIT_WIN32 |
16 | # define NEWLINE "\r\n" | |
17 | #else | |
18 | # define NEWLINE "\n" | |
19 | #endif | |
20 | ||
21 | static char workdir_data[] = | |
22 | "some simple" NEWLINE | |
23 | "data" NEWLINE | |
24 | "that will be" NEWLINE | |
25 | "trivially" NEWLINE | |
26 | "scrambled." NEWLINE; | |
27 | ||
63924435 ET |
28 | #define REVERSED_DATA_LEN 51 |
29 | ||
b47349b8 RB |
30 | /* Represents the data above scrambled (bits flipped) after \r\n -> \n |
31 | * conversion, then bytewise reversed | |
32 | */ | |
33 | static unsigned char bitflipped_and_reversed_data[] = | |
34 | { 0xf5, 0xd1, 0x9b, 0x9a, 0x93, 0x9d, 0x92, 0x9e, 0x8d, 0x9c, 0x8c, | |
35 | 0xf5, 0x86, 0x93, 0x93, 0x9e, 0x96, 0x89, 0x96, 0x8d, 0x8b, 0xf5, | |
36 | 0x9a, 0x9d, 0xdf, 0x93, 0x93, 0x96, 0x88, 0xdf, 0x8b, 0x9e, 0x97, | |
37 | 0x8b, 0xf5, 0x9e, 0x8b, 0x9e, 0x9b, 0xf5, 0x9a, 0x93, 0x8f, 0x92, | |
38 | 0x96, 0x8c, 0xdf, 0x9a, 0x92, 0x90, 0x8c }; | |
39 | ||
40 | #define BITFLIPPED_AND_REVERSED_DATA_LEN 51 | |
41 | ||
42 | static git_repository *g_repo = NULL; | |
43 | ||
44 | static void register_custom_filters(void); | |
45 | ||
46 | void test_filter_custom__initialize(void) | |
47 | { | |
48 | register_custom_filters(); | |
49 | ||
50 | g_repo = cl_git_sandbox_init("empty_standard_repo"); | |
51 | ||
52 | cl_git_mkfile( | |
53 | "empty_standard_repo/.gitattributes", | |
54 | "hero* bitflip reverse\n" | |
55 | "herofile text\n" | |
ad7417d7 | 56 | "heroflip -reverse binary\n" |
cf07db2f | 57 | "villain erroneous\n" |
ad7417d7 | 58 | "*.bin binary\n"); |
b47349b8 RB |
59 | } |
60 | ||
61 | void test_filter_custom__cleanup(void) | |
62 | { | |
63 | cl_git_sandbox_cleanup(); | |
64 | g_repo = NULL; | |
65 | } | |
66 | ||
b47349b8 RB |
67 | static void register_custom_filters(void) |
68 | { | |
69 | static int filters_registered = 0; | |
70 | ||
71 | if (!filters_registered) { | |
72 | cl_git_pass(git_filter_register( | |
73 | "bitflip", create_bitflip_filter(), BITFLIP_FILTER_PRIORITY)); | |
74 | ||
75 | cl_git_pass(git_filter_register( | |
eefc32d5 RB |
76 | "reverse", create_reverse_filter("+reverse"), |
77 | REVERSE_FILTER_PRIORITY)); | |
78 | ||
79 | /* re-register reverse filter with standard filter=xyz priority */ | |
80 | cl_git_pass(git_filter_register( | |
81 | "pre-reverse", | |
82 | create_reverse_filter("+prereverse"), | |
83 | GIT_FILTER_DRIVER_PRIORITY)); | |
b47349b8 | 84 | |
cf07db2f PS |
85 | cl_git_pass(git_filter_register( |
86 | "erroneous", | |
87 | create_erroneous_filter("+erroneous"), | |
88 | GIT_FILTER_DRIVER_PRIORITY)); | |
89 | ||
b47349b8 RB |
90 | filters_registered = 1; |
91 | } | |
92 | } | |
93 | ||
b47349b8 RB |
94 | void test_filter_custom__to_odb(void) |
95 | { | |
96 | git_filter_list *fl; | |
c25aa7cd PP |
97 | git_buf out = GIT_BUF_INIT; |
98 | const char *in; | |
99 | size_t in_len; | |
b47349b8 RB |
100 | |
101 | cl_git_pass(git_filter_list_load( | |
5269008c | 102 | &fl, g_repo, NULL, "herofile", GIT_FILTER_TO_ODB, 0)); |
b47349b8 | 103 | |
c25aa7cd PP |
104 | in = workdir_data; |
105 | in_len = strlen(workdir_data); | |
106 | ||
107 | cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); | |
b47349b8 RB |
108 | |
109 | cl_assert_equal_i(BITFLIPPED_AND_REVERSED_DATA_LEN, out.size); | |
110 | ||
111 | cl_assert_equal_i( | |
112 | 0, memcmp(bitflipped_and_reversed_data, out.ptr, out.size)); | |
113 | ||
114 | git_filter_list_free(fl); | |
ac3d33df | 115 | git_buf_dispose(&out); |
b47349b8 RB |
116 | } |
117 | ||
118 | void test_filter_custom__to_workdir(void) | |
119 | { | |
120 | git_filter_list *fl; | |
c25aa7cd PP |
121 | git_buf out = GIT_BUF_INIT; |
122 | const char *in; | |
123 | size_t in_len; | |
b47349b8 RB |
124 | |
125 | cl_git_pass(git_filter_list_load( | |
5269008c | 126 | &fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE, 0)); |
b47349b8 | 127 | |
c25aa7cd PP |
128 | in = (char *)bitflipped_and_reversed_data; |
129 | in_len = BITFLIPPED_AND_REVERSED_DATA_LEN; | |
130 | ||
131 | cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); | |
b47349b8 RB |
132 | |
133 | cl_assert_equal_i(strlen(workdir_data), out.size); | |
134 | ||
135 | cl_assert_equal_i( | |
136 | 0, memcmp(workdir_data, out.ptr, out.size)); | |
137 | ||
138 | git_filter_list_free(fl); | |
ac3d33df | 139 | git_buf_dispose(&out); |
b47349b8 RB |
140 | } |
141 | ||
142 | void test_filter_custom__can_register_a_custom_filter_in_the_repository(void) | |
143 | { | |
144 | git_filter_list *fl; | |
145 | ||
146 | cl_git_pass(git_filter_list_load( | |
5269008c | 147 | &fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE, 0)); |
b47349b8 RB |
148 | /* expect: bitflip, reverse, crlf */ |
149 | cl_assert_equal_sz(3, git_filter_list_length(fl)); | |
150 | git_filter_list_free(fl); | |
151 | ||
152 | cl_git_pass(git_filter_list_load( | |
5269008c | 153 | &fl, g_repo, NULL, "herocorp", GIT_FILTER_TO_WORKTREE, 0)); |
ad7417d7 RB |
154 | /* expect: bitflip, reverse - possibly crlf depending on global config */ |
155 | { | |
156 | size_t flen = git_filter_list_length(fl); | |
157 | cl_assert(flen == 2 || flen == 3); | |
158 | } | |
159 | git_filter_list_free(fl); | |
160 | ||
161 | cl_git_pass(git_filter_list_load( | |
5269008c | 162 | &fl, g_repo, NULL, "hero.bin", GIT_FILTER_TO_WORKTREE, 0)); |
b47349b8 RB |
163 | /* expect: bitflip, reverse */ |
164 | cl_assert_equal_sz(2, git_filter_list_length(fl)); | |
165 | git_filter_list_free(fl); | |
166 | ||
167 | cl_git_pass(git_filter_list_load( | |
5269008c | 168 | &fl, g_repo, NULL, "heroflip", GIT_FILTER_TO_WORKTREE, 0)); |
b47349b8 RB |
169 | /* expect: bitflip (because of -reverse) */ |
170 | cl_assert_equal_sz(1, git_filter_list_length(fl)); | |
171 | git_filter_list_free(fl); | |
172 | ||
173 | cl_git_pass(git_filter_list_load( | |
5269008c RB |
174 | &fl, g_repo, NULL, "doesntapplytome.bin", |
175 | GIT_FILTER_TO_WORKTREE, 0)); | |
b47349b8 RB |
176 | /* expect: none */ |
177 | cl_assert_equal_sz(0, git_filter_list_length(fl)); | |
178 | git_filter_list_free(fl); | |
179 | } | |
eab3746b RB |
180 | |
181 | void test_filter_custom__order_dependency(void) | |
182 | { | |
183 | git_index *index; | |
184 | git_blob *blob; | |
185 | git_buf buf = { 0 }; | |
186 | ||
187 | /* so if ident and reverse are used together, an interesting thing | |
188 | * happens - a reversed "$Id$" string is no longer going to trigger | |
189 | * ident correctly. When checking out, the filters should be applied | |
190 | * in order CLRF, then ident, then reverse, so ident expansion should | |
191 | * work correctly. On check in, the content should be reversed, then | |
192 | * ident, then CRLF filtered. Let's make sure that works... | |
193 | */ | |
194 | ||
195 | cl_git_mkfile( | |
196 | "empty_standard_repo/.gitattributes", | |
eefc32d5 | 197 | "hero.*.rev-ident text ident prereverse eol=lf\n"); |
eab3746b RB |
198 | |
199 | cl_git_mkfile( | |
200 | "empty_standard_repo/hero.1.rev-ident", | |
201 | "This is a test\n$Id$\nHave fun!\n"); | |
202 | ||
203 | cl_git_mkfile( | |
204 | "empty_standard_repo/hero.2.rev-ident", | |
205 | "Another test\n$dI$\nCrazy!\n"); | |
206 | ||
207 | cl_git_pass(git_repository_index(&index, g_repo)); | |
208 | cl_git_pass(git_index_add_bypath(index, "hero.1.rev-ident")); | |
209 | cl_git_pass(git_index_add_bypath(index, "hero.2.rev-ident")); | |
210 | cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "Filter chains\n"); | |
211 | git_index_free(index); | |
212 | ||
213 | cl_git_pass(git_blob_lookup(&blob, g_repo, | |
d541170c | 214 | & git_index_get_bypath(index, "hero.1.rev-ident", 0)->id)); |
eab3746b RB |
215 | cl_assert_equal_s( |
216 | "\n!nuf evaH\n$dI$\ntset a si sihT", git_blob_rawcontent(blob)); | |
22a2d3d5 | 217 | cl_git_pass(git_blob_filter(&buf, blob, "hero.1.rev-ident", NULL)); |
eab3746b RB |
218 | /* no expansion because id was reversed at checkin and now at ident |
219 | * time, reverse is not applied yet */ | |
220 | cl_assert_equal_s( | |
221 | "This is a test\n$Id$\nHave fun!\n", buf.ptr); | |
222 | git_blob_free(blob); | |
223 | ||
224 | cl_git_pass(git_blob_lookup(&blob, g_repo, | |
d541170c | 225 | & git_index_get_bypath(index, "hero.2.rev-ident", 0)->id)); |
eab3746b RB |
226 | cl_assert_equal_s( |
227 | "\n!yzarC\n$Id$\ntset rehtonA", git_blob_rawcontent(blob)); | |
22a2d3d5 | 228 | cl_git_pass(git_blob_filter(&buf, blob, "hero.2.rev-ident", NULL)); |
eab3746b RB |
229 | /* expansion because reverse was applied at checkin and at ident time, |
230 | * reverse is not applied yet */ | |
231 | cl_assert_equal_s( | |
1ecbcd8e | 232 | "Another test\n$ 59001fe193103b1016b27027c0c827d036fd0ac8 :dI$\nCrazy!\n", buf.ptr); |
eab3746b RB |
233 | cl_assert_equal_i(0, git_oid_strcmp( |
234 | git_blob_id(blob), "8ca0df630d728c0c72072b6101b301391ef10095")); | |
235 | git_blob_free(blob); | |
236 | ||
ac3d33df | 237 | git_buf_dispose(&buf); |
eab3746b | 238 | } |
eefc32d5 RB |
239 | |
240 | void test_filter_custom__filter_registry_failure_cases(void) | |
241 | { | |
242 | git_filter fake = { GIT_FILTER_VERSION, 0 }; | |
243 | ||
244 | cl_assert_equal_i(GIT_EEXISTS, git_filter_register("bitflip", &fake, 0)); | |
245 | ||
246 | cl_git_fail(git_filter_unregister(GIT_FILTER_CRLF)); | |
247 | cl_git_fail(git_filter_unregister(GIT_FILTER_IDENT)); | |
248 | cl_assert_equal_i(GIT_ENOTFOUND, git_filter_unregister("not-a-filter")); | |
249 | } | |
cf07db2f PS |
250 | |
251 | void test_filter_custom__erroneous_filter_fails(void) | |
252 | { | |
253 | git_filter_list *filters; | |
254 | git_buf out = GIT_BUF_INIT; | |
c25aa7cd PP |
255 | const char *in; |
256 | size_t in_len; | |
cf07db2f PS |
257 | |
258 | cl_git_pass(git_filter_list_load( | |
259 | &filters, g_repo, NULL, "villain", GIT_FILTER_TO_WORKTREE, 0)); | |
260 | ||
c25aa7cd PP |
261 | in = workdir_data; |
262 | in_len = strlen(workdir_data); | |
263 | ||
264 | cl_git_fail(git_filter_list_apply_to_buffer(&out, filters, in, in_len)); | |
cf07db2f PS |
265 | |
266 | git_filter_list_free(filters); | |
ac3d33df | 267 | git_buf_dispose(&out); |
cf07db2f | 268 | } |