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