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.
17 #include <sys/queue.h>
25 #include "got_error.h"
26 #include "got_opentemp.h"
28 #include "got_lib_deltify.h"
31 #define nitems(_a) (sizeof(_a) / sizeof((_a)[0]))
37 const struct got_error *err = NULL;
39 FILE *base_file, *derived_file, *result_file;
40 struct got_delta_table *dt;
41 struct got_delta_instruction *deltas;
48 base_file = got_opentemp();
49 if (base_file == NULL)
52 derived_file = got_opentemp();
53 if (derived_file == NULL)
56 result_file = got_opentemp();
57 if (result_file == NULL)
60 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
61 fputc('a', base_file);
62 fputc('a', derived_file);
64 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
65 fputc('b', base_file);
66 fputc('x', derived_file);
68 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
69 fputc('c', base_file);
70 fputc('c', derived_file);
76 err = got_deltify_init(&dt, base_file, 0, 3 * GOT_DELTIFY_MAXCHUNK,
81 for (i = 0; i < dt->nalloc; i++) {
82 if (dt->blocks[i].len > 0)
85 if (have_nblocks != dt->nblocks) {
86 err = got_error(GOT_ERR_BAD_DELTA);
90 err = got_deltify(&deltas, &ndeltas, derived_file, 0,
91 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_file, 0,
92 3 * GOT_DELTIFY_MAXCHUNK);
97 err = got_error(GOT_ERR_BAD_DELTA);
100 /* Copy 'aaaa...' from base file. */
101 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
102 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
103 err = got_error(GOT_ERR_BAD_DELTA);
106 /* Copy 'xxxx...' from derived file. */
107 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
108 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
109 err = got_error(GOT_ERR_BAD_DELTA);
112 /* Copy 'ccccc...' from base file. */
113 if (!(deltas[2].copy == 1 &&
114 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
115 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
116 err = got_error(GOT_ERR_BAD_DELTA);
121 got_deltify_free(dt);
123 fclose(derived_file);
125 return (err == NULL);
129 deltify_abc_axc_file_mem(void)
131 const struct got_error *err = NULL;
133 uint8_t base_data[3 * GOT_DELTIFY_MAXCHUNK];
134 FILE *derived_file, *result_file;
135 struct got_delta_table *dt;
136 struct got_delta_instruction *deltas;
138 int have_nblocks = 0;
143 derived_file = got_opentemp();
144 if (derived_file == NULL)
147 result_file = got_opentemp();
148 if (result_file == NULL)
151 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
153 fputc('a', derived_file);
155 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
156 base_data[GOT_DELTIFY_MAXCHUNK + i] = 'b';
157 fputc('x', derived_file);
159 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
160 base_data[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
161 fputc('c', derived_file);
164 rewind(derived_file);
166 err = got_deltify_init_mem(&dt, base_data, 0, 3 * GOT_DELTIFY_MAXCHUNK,
171 for (i = 0; i < dt->nalloc; i++) {
172 if (dt->blocks[i].len > 0)
175 if (have_nblocks != dt->nblocks) {
176 err = got_error(GOT_ERR_BAD_DELTA);
180 err = got_deltify_file_mem(&deltas, &ndeltas, derived_file, 0,
181 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_data, 0,
182 3 * GOT_DELTIFY_MAXCHUNK);
187 err = got_error(GOT_ERR_BAD_DELTA);
190 /* Copy 'aaaa...' from base file. */
191 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
192 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
193 err = got_error(GOT_ERR_BAD_DELTA);
196 /* Copy 'xxxx...' from derived file. */
197 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
198 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
199 err = got_error(GOT_ERR_BAD_DELTA);
202 /* Copy 'ccccc...' from base file. */
203 if (!(deltas[2].copy == 1 &&
204 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
205 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
206 err = got_error(GOT_ERR_BAD_DELTA);
211 got_deltify_free(dt);
212 fclose(derived_file);
214 return (err == NULL);
218 deltify_abc_axc_mem_file(void)
220 const struct got_error *err = NULL;
222 FILE *base_file, *result_file;
223 uint8_t derived_file[3 * GOT_DELTIFY_MAXCHUNK];
224 struct got_delta_table *dt;
225 struct got_delta_instruction *deltas;
227 int have_nblocks = 0;
232 base_file = got_opentemp();
233 if (base_file == NULL)
236 result_file = got_opentemp();
237 if (result_file == NULL)
240 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
241 fputc('a', base_file);
242 derived_file[i] = 'a';
244 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
245 fputc('b', base_file);
246 derived_file[GOT_DELTIFY_MAXCHUNK + i] = 'x';
248 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
249 fputc('c', base_file);
250 derived_file[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
255 err = got_deltify_init(&dt, base_file, 0, 3 * GOT_DELTIFY_MAXCHUNK,
260 for (i = 0; i < dt->nalloc; i++) {
261 if (dt->blocks[i].len > 0)
264 if (have_nblocks != dt->nblocks) {
265 err = got_error(GOT_ERR_BAD_DELTA);
269 err = got_deltify_mem_file(&deltas, &ndeltas, derived_file, 0,
270 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_file, 0,
271 3 * GOT_DELTIFY_MAXCHUNK);
276 err = got_error(GOT_ERR_BAD_DELTA);
279 /* Copy 'aaaa...' from base file. */
280 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
281 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
282 err = got_error(GOT_ERR_BAD_DELTA);
285 /* Copy 'xxxx...' from derived file. */
286 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
287 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
288 err = got_error(GOT_ERR_BAD_DELTA);
291 /* Copy 'ccccc...' from base file. */
292 if (!(deltas[2].copy == 1 &&
293 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
294 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
295 err = got_error(GOT_ERR_BAD_DELTA);
300 got_deltify_free(dt);
303 return (err == NULL);
307 deltify_abc_axc_mem_mem(void)
309 const struct got_error *err = NULL;
312 uint8_t base_file[3 * GOT_DELTIFY_MAXCHUNK];
313 uint8_t derived_file[3 * GOT_DELTIFY_MAXCHUNK];
314 struct got_delta_table *dt;
315 struct got_delta_instruction *deltas;
317 int have_nblocks = 0;
322 result_file = got_opentemp();
323 if (result_file == NULL)
326 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
328 derived_file[i] = 'a';
330 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
331 base_file[GOT_DELTIFY_MAXCHUNK + i] = 'b';
332 derived_file[GOT_DELTIFY_MAXCHUNK + i] = 'x';
334 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
335 base_file[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
336 derived_file[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
339 err = got_deltify_init_mem(&dt, base_file, 0, 3 * GOT_DELTIFY_MAXCHUNK,
344 for (i = 0; i < dt->nalloc; i++) {
345 if (dt->blocks[i].len > 0)
348 if (have_nblocks != dt->nblocks) {
349 err = got_error(GOT_ERR_BAD_DELTA);
353 err = got_deltify_mem_mem(&deltas, &ndeltas, derived_file, 0,
354 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_file, 0,
355 3 * GOT_DELTIFY_MAXCHUNK);
360 err = got_error(GOT_ERR_BAD_DELTA);
363 /* Copy 'aaaa...' from base file. */
364 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
365 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
366 err = got_error(GOT_ERR_BAD_DELTA);
369 /* Copy 'xxxx...' from derived file. */
370 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
371 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
372 err = got_error(GOT_ERR_BAD_DELTA);
375 /* Copy 'ccccc...' from base file. */
376 if (!(deltas[2].copy == 1 &&
377 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
378 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
379 err = got_error(GOT_ERR_BAD_DELTA);
384 got_deltify_free(dt);
386 return (err == NULL);
391 #define RUN_TEST(expr, name) \
392 { test_ok = (expr); \
393 if (!quiet) printf("test_%s %s\n", (name), test_ok ? "ok" : "failed"); \
394 failure = (failure || !test_ok); }
399 fprintf(stderr, "usage: delta_test [-q]\n");
403 main(int argc, char *argv[])
409 while ((ch = getopt(argc, argv, "q")) != -1) {
429 if (pledge("stdio rpath wpath cpath unveil", NULL) == -1)
432 if (unveil(GOT_TMPDIR_STR, "rwc") != 0)
435 if (unveil(NULL, NULL) != 0)
438 RUN_TEST(deltify_abc_axc(), "deltify_abc_axc");
439 RUN_TEST(deltify_abc_axc_file_mem(), "deltify_abc_axc_file_mem");
440 RUN_TEST(deltify_abc_axc_mem_file(), "deltify_abc_axc_mem_file");
441 RUN_TEST(deltify_abc_axc_mem_mem(), "deltify_abc_axc_mem_mem");
443 return failure ? 1 : 0;