2 * Copyright (c) 2021 Stefan Sperling <stsp@openbsd.org>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 #include "got_error.h"
25 #include "got_opentemp.h"
27 #include "got_lib_deltify.h"
30 #define nitems(_a) (sizeof(_a) / sizeof((_a)[0]))
36 const struct got_error *err = NULL;
38 FILE *base_file, *derived_file, *result_file;
39 struct got_delta_table *dt;
40 struct got_delta_instruction *deltas;
47 base_file = got_opentemp();
48 if (base_file == NULL)
51 derived_file = got_opentemp();
52 if (derived_file == NULL)
55 result_file = got_opentemp();
56 if (result_file == NULL)
59 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
60 fputc('a', base_file);
61 fputc('a', derived_file);
63 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
64 fputc('b', base_file);
65 fputc('x', derived_file);
67 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
68 fputc('c', base_file);
69 fputc('c', derived_file);
75 err = got_deltify_init(&dt, base_file, 0, 3 * GOT_DELTIFY_MAXCHUNK,
80 for (i = 0; i < dt->nalloc; i++) {
81 if (dt->blocks[i].len > 0)
84 if (have_nblocks != dt->nblocks) {
85 err = got_error(GOT_ERR_BAD_DELTA);
89 err = got_deltify(&deltas, &ndeltas, derived_file, 0,
90 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_file, 0,
91 3 * GOT_DELTIFY_MAXCHUNK);
96 err = got_error(GOT_ERR_BAD_DELTA);
99 /* Copy 'aaaa...' from base file. */
100 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
101 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
102 err = got_error(GOT_ERR_BAD_DELTA);
105 /* Copy 'xxxx...' from derived file. */
106 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
107 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
108 err = got_error(GOT_ERR_BAD_DELTA);
111 /* Copy 'ccccc...' from base file. */
112 if (!(deltas[2].copy == 1 &&
113 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
114 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
115 err = got_error(GOT_ERR_BAD_DELTA);
120 got_deltify_free(dt);
122 fclose(derived_file);
124 return (err == NULL);
128 deltify_abc_axc_file_mem(void)
130 const struct got_error *err = NULL;
132 uint8_t base_data[3 * GOT_DELTIFY_MAXCHUNK];
133 FILE *derived_file, *result_file;
134 struct got_delta_table *dt;
135 struct got_delta_instruction *deltas;
137 int have_nblocks = 0;
142 derived_file = got_opentemp();
143 if (derived_file == NULL)
146 result_file = got_opentemp();
147 if (result_file == NULL)
150 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
152 fputc('a', derived_file);
154 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
155 base_data[GOT_DELTIFY_MAXCHUNK + i] = 'b';
156 fputc('x', derived_file);
158 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
159 base_data[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
160 fputc('c', derived_file);
163 rewind(derived_file);
165 err = got_deltify_init_mem(&dt, base_data, 0, 3 * GOT_DELTIFY_MAXCHUNK,
170 for (i = 0; i < dt->nalloc; i++) {
171 if (dt->blocks[i].len > 0)
174 if (have_nblocks != dt->nblocks) {
175 err = got_error(GOT_ERR_BAD_DELTA);
179 err = got_deltify_file_mem(&deltas, &ndeltas, derived_file, 0,
180 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_data, 0,
181 3 * GOT_DELTIFY_MAXCHUNK);
186 err = got_error(GOT_ERR_BAD_DELTA);
189 /* Copy 'aaaa...' from base file. */
190 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
191 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
192 err = got_error(GOT_ERR_BAD_DELTA);
195 /* Copy 'xxxx...' from derived file. */
196 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
197 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
198 err = got_error(GOT_ERR_BAD_DELTA);
201 /* Copy 'ccccc...' from base file. */
202 if (!(deltas[2].copy == 1 &&
203 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
204 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
205 err = got_error(GOT_ERR_BAD_DELTA);
210 got_deltify_free(dt);
211 fclose(derived_file);
213 return (err == NULL);
217 deltify_abc_axc_mem_file(void)
219 const struct got_error *err = NULL;
221 FILE *base_file, *result_file;
222 uint8_t derived_file[3 * GOT_DELTIFY_MAXCHUNK];
223 struct got_delta_table *dt;
224 struct got_delta_instruction *deltas;
226 int have_nblocks = 0;
231 base_file = got_opentemp();
232 if (base_file == NULL)
235 result_file = got_opentemp();
236 if (result_file == NULL)
239 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
240 fputc('a', base_file);
241 derived_file[i] = 'a';
243 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
244 fputc('b', base_file);
245 derived_file[GOT_DELTIFY_MAXCHUNK + i] = 'x';
247 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
248 fputc('c', base_file);
249 derived_file[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
254 err = got_deltify_init(&dt, base_file, 0, 3 * GOT_DELTIFY_MAXCHUNK,
259 for (i = 0; i < dt->nalloc; i++) {
260 if (dt->blocks[i].len > 0)
263 if (have_nblocks != dt->nblocks) {
264 err = got_error(GOT_ERR_BAD_DELTA);
268 err = got_deltify_mem_file(&deltas, &ndeltas, derived_file, 0,
269 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_file, 0,
270 3 * GOT_DELTIFY_MAXCHUNK);
275 err = got_error(GOT_ERR_BAD_DELTA);
278 /* Copy 'aaaa...' from base file. */
279 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
280 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
281 err = got_error(GOT_ERR_BAD_DELTA);
284 /* Copy 'xxxx...' from derived file. */
285 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
286 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
287 err = got_error(GOT_ERR_BAD_DELTA);
290 /* Copy 'ccccc...' from base file. */
291 if (!(deltas[2].copy == 1 &&
292 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
293 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
294 err = got_error(GOT_ERR_BAD_DELTA);
299 got_deltify_free(dt);
302 return (err == NULL);
306 deltify_abc_axc_mem_mem(void)
308 const struct got_error *err = NULL;
311 uint8_t base_file[3 * GOT_DELTIFY_MAXCHUNK];
312 uint8_t derived_file[3 * GOT_DELTIFY_MAXCHUNK];
313 struct got_delta_table *dt;
314 struct got_delta_instruction *deltas;
316 int have_nblocks = 0;
321 result_file = got_opentemp();
322 if (result_file == NULL)
325 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
327 derived_file[i] = 'a';
329 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
330 base_file[GOT_DELTIFY_MAXCHUNK + i] = 'b';
331 derived_file[GOT_DELTIFY_MAXCHUNK + i] = 'x';
333 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
334 base_file[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
335 derived_file[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
338 err = got_deltify_init_mem(&dt, base_file, 0, 3 * GOT_DELTIFY_MAXCHUNK,
343 for (i = 0; i < dt->nalloc; i++) {
344 if (dt->blocks[i].len > 0)
347 if (have_nblocks != dt->nblocks) {
348 err = got_error(GOT_ERR_BAD_DELTA);
352 err = got_deltify_mem_mem(&deltas, &ndeltas, derived_file, 0,
353 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_file, 0,
354 3 * GOT_DELTIFY_MAXCHUNK);
359 err = got_error(GOT_ERR_BAD_DELTA);
362 /* Copy 'aaaa...' from base file. */
363 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
364 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
365 err = got_error(GOT_ERR_BAD_DELTA);
368 /* Copy 'xxxx...' from derived file. */
369 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
370 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
371 err = got_error(GOT_ERR_BAD_DELTA);
374 /* Copy 'ccccc...' from base file. */
375 if (!(deltas[2].copy == 1 &&
376 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
377 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
378 err = got_error(GOT_ERR_BAD_DELTA);
383 got_deltify_free(dt);
385 return (err == NULL);
390 #define RUN_TEST(expr, name) \
391 { test_ok = (expr); \
392 if (!quiet) printf("test_%s %s\n", (name), test_ok ? "ok" : "failed"); \
393 failure = (failure || !test_ok); }
398 fprintf(stderr, "usage: delta_test [-q]\n");
402 main(int argc, char *argv[])
408 while ((ch = getopt(argc, argv, "q")) != -1) {
428 if (pledge("stdio rpath wpath cpath unveil", NULL) == -1)
431 if (unveil(GOT_TMPDIR_STR, "rwc") != 0)
434 if (unveil(NULL, NULL) != 0)
437 RUN_TEST(deltify_abc_axc(), "deltify_abc_axc");
438 RUN_TEST(deltify_abc_axc_file_mem(), "deltify_abc_axc_file_mem");
439 RUN_TEST(deltify_abc_axc_mem_file(), "deltify_abc_axc_mem_file");
440 RUN_TEST(deltify_abc_axc_mem_mem(), "deltify_abc_axc_mem_mem");
442 return failure ? 1 : 0;