]> git.proxmox.com Git - libgit2.git/blame - tests/filter/custom.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / tests / filter / custom.c
CommitLineData
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
21static 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 */
33static 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
42static git_repository *g_repo = NULL;
43
44static void register_custom_filters(void);
45
46void 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
61void test_filter_custom__cleanup(void)
62{
63 cl_git_sandbox_cleanup();
64 g_repo = NULL;
65}
66
b47349b8
RB
67static 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
94void 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
118void 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
142void 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
181void 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
240void 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
251void 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}