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>
26 #include "got_error.h"
27 #include "got_opentemp.h"
29 #include "got_lib_deltify.h"
32 #define nitems(_a) (sizeof(_a) / sizeof((_a)[0]))
38 const struct got_error *err = NULL;
40 FILE *base_file, *derived_file, *result_file;
41 struct got_delta_table *dt;
42 struct got_delta_instruction *deltas;
49 base_file = got_opentemp();
50 if (base_file == NULL)
53 derived_file = got_opentemp();
54 if (derived_file == NULL)
57 result_file = got_opentemp();
58 if (result_file == NULL)
61 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
62 fputc('a', base_file);
63 fputc('a', derived_file);
65 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
66 fputc('b', base_file);
67 fputc('x', derived_file);
69 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
70 fputc('c', base_file);
71 fputc('c', derived_file);
77 err = got_deltify_init(&dt, base_file, 0, 3 * GOT_DELTIFY_MAXCHUNK,
82 for (i = 0; i < dt->nalloc; i++) {
83 if (dt->blocks[i].len > 0)
86 if (have_nblocks != dt->nblocks) {
87 err = got_error(GOT_ERR_BAD_DELTA);
91 err = got_deltify(&deltas, &ndeltas, derived_file, 0,
92 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_file, 0,
93 3 * GOT_DELTIFY_MAXCHUNK);
98 err = got_error(GOT_ERR_BAD_DELTA);
101 /* Copy 'aaaa...' from base file. */
102 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
103 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
104 err = got_error(GOT_ERR_BAD_DELTA);
107 /* Copy 'xxxx...' from derived file. */
108 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
109 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
110 err = got_error(GOT_ERR_BAD_DELTA);
113 /* Copy 'ccccc...' from base file. */
114 if (!(deltas[2].copy == 1 &&
115 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
116 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
117 err = got_error(GOT_ERR_BAD_DELTA);
122 got_deltify_free(dt);
124 fclose(derived_file);
126 return (err == NULL);
130 deltify_abc_axc_file_mem(void)
132 const struct got_error *err = NULL;
134 uint8_t base_data[3 * GOT_DELTIFY_MAXCHUNK];
135 FILE *derived_file, *result_file;
136 struct got_delta_table *dt;
137 struct got_delta_instruction *deltas;
139 int have_nblocks = 0;
144 derived_file = got_opentemp();
145 if (derived_file == NULL)
148 result_file = got_opentemp();
149 if (result_file == NULL)
152 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
154 fputc('a', derived_file);
156 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
157 base_data[GOT_DELTIFY_MAXCHUNK + i] = 'b';
158 fputc('x', derived_file);
160 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
161 base_data[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
162 fputc('c', derived_file);
165 rewind(derived_file);
167 err = got_deltify_init_mem(&dt, base_data, 0, 3 * GOT_DELTIFY_MAXCHUNK,
172 for (i = 0; i < dt->nalloc; i++) {
173 if (dt->blocks[i].len > 0)
176 if (have_nblocks != dt->nblocks) {
177 err = got_error(GOT_ERR_BAD_DELTA);
181 err = got_deltify_file_mem(&deltas, &ndeltas, derived_file, 0,
182 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_data, 0,
183 3 * GOT_DELTIFY_MAXCHUNK);
188 err = got_error(GOT_ERR_BAD_DELTA);
191 /* Copy 'aaaa...' from base file. */
192 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
193 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
194 err = got_error(GOT_ERR_BAD_DELTA);
197 /* Copy 'xxxx...' from derived file. */
198 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
199 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
200 err = got_error(GOT_ERR_BAD_DELTA);
203 /* Copy 'ccccc...' from base file. */
204 if (!(deltas[2].copy == 1 &&
205 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
206 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
207 err = got_error(GOT_ERR_BAD_DELTA);
212 got_deltify_free(dt);
213 fclose(derived_file);
215 return (err == NULL);
219 deltify_abc_axc_mem_file(void)
221 const struct got_error *err = NULL;
223 FILE *base_file, *result_file;
224 uint8_t derived_file[3 * GOT_DELTIFY_MAXCHUNK];
225 struct got_delta_table *dt;
226 struct got_delta_instruction *deltas;
228 int have_nblocks = 0;
233 base_file = got_opentemp();
234 if (base_file == NULL)
237 result_file = got_opentemp();
238 if (result_file == NULL)
241 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
242 fputc('a', base_file);
243 derived_file[i] = 'a';
245 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
246 fputc('b', base_file);
247 derived_file[GOT_DELTIFY_MAXCHUNK + i] = 'x';
249 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
250 fputc('c', base_file);
251 derived_file[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
256 err = got_deltify_init(&dt, base_file, 0, 3 * GOT_DELTIFY_MAXCHUNK,
261 for (i = 0; i < dt->nalloc; i++) {
262 if (dt->blocks[i].len > 0)
265 if (have_nblocks != dt->nblocks) {
266 err = got_error(GOT_ERR_BAD_DELTA);
270 err = got_deltify_mem_file(&deltas, &ndeltas, derived_file, 0,
271 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_file, 0,
272 3 * GOT_DELTIFY_MAXCHUNK);
277 err = got_error(GOT_ERR_BAD_DELTA);
280 /* Copy 'aaaa...' from base file. */
281 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
282 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
283 err = got_error(GOT_ERR_BAD_DELTA);
286 /* Copy 'xxxx...' from derived file. */
287 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
288 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
289 err = got_error(GOT_ERR_BAD_DELTA);
292 /* Copy 'ccccc...' from base file. */
293 if (!(deltas[2].copy == 1 &&
294 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
295 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
296 err = got_error(GOT_ERR_BAD_DELTA);
301 got_deltify_free(dt);
304 return (err == NULL);
308 deltify_abc_axc_mem_mem(void)
310 const struct got_error *err = NULL;
313 uint8_t base_file[3 * GOT_DELTIFY_MAXCHUNK];
314 uint8_t derived_file[3 * GOT_DELTIFY_MAXCHUNK];
315 struct got_delta_table *dt;
316 struct got_delta_instruction *deltas;
318 int have_nblocks = 0;
323 result_file = got_opentemp();
324 if (result_file == NULL)
327 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
329 derived_file[i] = 'a';
331 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
332 base_file[GOT_DELTIFY_MAXCHUNK + i] = 'b';
333 derived_file[GOT_DELTIFY_MAXCHUNK + i] = 'x';
335 for (i = 0; i < GOT_DELTIFY_MAXCHUNK; i++) {
336 base_file[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
337 derived_file[2 * GOT_DELTIFY_MAXCHUNK + i] = 'c';
340 err = got_deltify_init_mem(&dt, base_file, 0, 3 * GOT_DELTIFY_MAXCHUNK,
345 for (i = 0; i < dt->nalloc; i++) {
346 if (dt->blocks[i].len > 0)
349 if (have_nblocks != dt->nblocks) {
350 err = got_error(GOT_ERR_BAD_DELTA);
354 err = got_deltify_mem_mem(&deltas, &ndeltas, derived_file, 0,
355 3 * GOT_DELTIFY_MAXCHUNK, seed, dt, base_file, 0,
356 3 * GOT_DELTIFY_MAXCHUNK);
361 err = got_error(GOT_ERR_BAD_DELTA);
364 /* Copy 'aaaa...' from base file. */
365 if (!(deltas[0].copy == 1 && deltas[0].offset == 0 &&
366 deltas[0].len == GOT_DELTIFY_MAXCHUNK)) {
367 err = got_error(GOT_ERR_BAD_DELTA);
370 /* Copy 'xxxx...' from derived file. */
371 if (!(deltas[1].copy == 0 && deltas[1].offset == GOT_DELTIFY_MAXCHUNK &&
372 deltas[1].len == GOT_DELTIFY_MAXCHUNK)) {
373 err = got_error(GOT_ERR_BAD_DELTA);
376 /* Copy 'ccccc...' from base file. */
377 if (!(deltas[2].copy == 1 &&
378 deltas[2].offset == 2 * GOT_DELTIFY_MAXCHUNK &&
379 deltas[2].len == GOT_DELTIFY_MAXCHUNK)) {
380 err = got_error(GOT_ERR_BAD_DELTA);
385 got_deltify_free(dt);
387 return (err == NULL);
392 #define RUN_TEST(expr, name) \
393 { test_ok = (expr); \
394 if (!quiet) printf("test_%s %s\n", (name), test_ok ? "ok" : "failed"); \
395 failure = (failure || !test_ok); }
400 fprintf(stderr, "usage: delta_test [-q]\n");
404 main(int argc, char *argv[])
410 while ((ch = getopt(argc, argv, "q")) != -1) {
430 if (pledge("stdio rpath wpath cpath unveil", NULL) == -1)
433 if (unveil(GOT_TMPDIR_STR, "rwc") != 0)
436 if (unveil(NULL, NULL) != 0)
439 RUN_TEST(deltify_abc_axc(), "deltify_abc_axc");
440 RUN_TEST(deltify_abc_axc_file_mem(), "deltify_abc_axc_file_mem");
441 RUN_TEST(deltify_abc_axc_mem_file(), "deltify_abc_axc_mem_file");
442 RUN_TEST(deltify_abc_axc_mem_mem(), "deltify_abc_axc_mem_mem");
444 return failure ? 1 : 0;