diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2008-06-20 04:06:06 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2008-06-20 04:06:06 +0000 |
commit | c31f63a124fc6221ee82e9563bb7aeeb238c92e8 (patch) | |
tree | e2a5e621fe228db5c972223c3891c49bf7f06241 | |
parent | 9cbfc47a5aa5bd5d2f61a5dc4a969336d27485fa (diff) |
Add a new test file, add a Mersenne Twister implementation, and
begin work on a new merge command. The new "file_spec" model will
allow working with randomly-generated inputs without having to write
the entire file to disk, allowing better streaming tests: next!
-rw-r--r-- | xdelta3/Makefile | 1 | ||||
-rw-r--r-- | xdelta3/Makefile.mingw | 1 | ||||
-rw-r--r-- | xdelta3/xdelta3-test.h | 140 | ||||
-rw-r--r-- | xdelta3/xdelta3-test2.h | 188 |
4 files changed, 302 insertions, 28 deletions
diff --git a/xdelta3/Makefile b/xdelta3/Makefile index aa35a4a..83fcbd6 100644 --- a/xdelta3/Makefile +++ b/xdelta3/Makefile | |||
@@ -25,6 +25,7 @@ SOURCES = xdelta3-cfgs.h \ | |||
25 | xdelta3-python.h \ | 25 | xdelta3-python.h \ |
26 | xdelta3-second.h \ | 26 | xdelta3-second.h \ |
27 | xdelta3-test.h \ | 27 | xdelta3-test.h \ |
28 | xdelta3-test2.h \ | ||
28 | xdelta3.c \ | 29 | xdelta3.c \ |
29 | xdelta3.h | 30 | xdelta3.h |
30 | 31 | ||
diff --git a/xdelta3/Makefile.mingw b/xdelta3/Makefile.mingw index 4e84527..5a19a1a 100644 --- a/xdelta3/Makefile.mingw +++ b/xdelta3/Makefile.mingw | |||
@@ -26,6 +26,7 @@ SOURCES = xdelta3-cfgs.h \ | |||
26 | xdelta3-python.h \ | 26 | xdelta3-python.h \ |
27 | xdelta3-second.h \ | 27 | xdelta3-second.h \ |
28 | xdelta3-test.h \ | 28 | xdelta3-test.h \ |
29 | xdelta3-test2.h \ | ||
29 | xdelta3.c \ | 30 | xdelta3.c \ |
30 | xdelta3.h | 31 | xdelta3.h |
31 | 32 | ||
diff --git a/xdelta3/xdelta3-test.h b/xdelta3/xdelta3-test.h index 5389d57..4a94a2f 100644 --- a/xdelta3/xdelta3-test.h +++ b/xdelta3/xdelta3-test.h | |||
@@ -16,6 +16,74 @@ | |||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | /* The code in this file is being gradually migrated to | ||
20 | * xdelta3-test2.h, which has a more solid foundation. That file is | ||
21 | * included immediatly after this random number generator code, which | ||
22 | * is all that is currently shared by the two files. */ | ||
23 | |||
24 | /* This is public-domain Mersenne Twister code, | ||
25 | * attributed to Michael Brundage. Thanks! | ||
26 | * http://www.qbrundage.com/michaelb/pubs/essays/random_number_generation.html | ||
27 | */ | ||
28 | #define MT_LEN 624 | ||
29 | #define MT_IA 397 | ||
30 | #define MT_IB (MT_LEN - MT_IA) | ||
31 | #define UPPER_MASK 0x80000000 | ||
32 | #define LOWER_MASK 0x7FFFFFFF | ||
33 | #define MATRIX_A 0x9908B0DF | ||
34 | #define TWIST(b,i,j) ((b)[i] & UPPER_MASK) | ((b)[j] & LOWER_MASK) | ||
35 | #define MAGIC(s) (((s)&1)*MATRIX_A) | ||
36 | |||
37 | struct mtrand_ { | ||
38 | int mt_index; | ||
39 | usize_t mt_buffer[MT_LEN]; | ||
40 | }; | ||
41 | |||
42 | typedef struct mtrand_ mtrand; | ||
43 | |||
44 | static void mt_init (mtrand *mt, int seed) { | ||
45 | int i; | ||
46 | srand (seed); | ||
47 | for (i = 0; i < MT_LEN; i++) | ||
48 | { | ||
49 | mt->mt_buffer[i] = rand (); | ||
50 | } | ||
51 | mt->mt_index = 0; | ||
52 | } | ||
53 | |||
54 | static usize_t mt_random (mtrand *mt) { | ||
55 | usize_t * b = mt->mt_buffer; | ||
56 | int idx = mt->mt_index; | ||
57 | usize_t s; | ||
58 | int i; | ||
59 | |||
60 | if (idx == MT_LEN*sizeof(usize_t)) | ||
61 | { | ||
62 | idx = 0; | ||
63 | i = 0; | ||
64 | for (; i < MT_IB; i++) { | ||
65 | s = TWIST(b, i, i+1); | ||
66 | b[i] = b[i + MT_IA] ^ (s >> 1) ^ MAGIC(s); | ||
67 | } | ||
68 | for (; i < MT_LEN-1; i++) { | ||
69 | s = TWIST(b, i, i+1); | ||
70 | b[i] = b[i - MT_IB] ^ (s >> 1) ^ MAGIC(s); | ||
71 | } | ||
72 | |||
73 | s = TWIST(b, MT_LEN-1, 0); | ||
74 | b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s); | ||
75 | } | ||
76 | mt->mt_index = idx + sizeof(usize_t); | ||
77 | return *(usize_t *)((unsigned char *)b + idx); | ||
78 | } | ||
79 | |||
80 | static mtrand static_mtrand; | ||
81 | |||
82 | #include "xdelta3-test2.h" | ||
83 | |||
84 | /* Everything below this line is old! The tests are still good, but | ||
85 | * better tests are being written in xdelta3-test2.h. */ | ||
86 | |||
19 | #include <math.h> | 87 | #include <math.h> |
20 | 88 | ||
21 | #ifndef WIN32 | 89 | #ifndef WIN32 |
@@ -90,13 +158,14 @@ static int do_fail (xd3_stream *stream, const char *buf) | |||
90 | } | 158 | } |
91 | 159 | ||
92 | static int | 160 | static int |
93 | test_exponential_dist (usize_t mean, usize_t max) | 161 | test_exponential_dist (usize_t mean, usize_t max_value) |
94 | { | 162 | { |
95 | double mean_d = mean; | 163 | double mean_d = mean; |
96 | double erand = log (1.0 / (rand () / (double)RAND_MAX)); | 164 | double erand = log (1.0 / (mt_random (&static_mtrand) / |
165 | (double)USIZE_T_MAX)); | ||
97 | usize_t x = (usize_t) (mean_d * erand + 0.5); | 166 | usize_t x = (usize_t) (mean_d * erand + 0.5); |
98 | 167 | ||
99 | return min (x, max); | 168 | return min (x, max_value); |
100 | } | 169 | } |
101 | 170 | ||
102 | /* Test that the exponential distribution actually produces its mean. */ | 171 | /* Test that the exponential distribution actually produces its mean. */ |
@@ -108,7 +177,9 @@ test_random_numbers (xd3_stream *stream, int ignore) | |||
108 | usize_t mean = 50; | 177 | usize_t mean = 50; |
109 | usize_t n_rounds = 10000; | 178 | usize_t n_rounds = 10000; |
110 | double average, error; | 179 | double average, error; |
111 | double allowed_error = 1.0; | 180 | double allowed_error = 2.0; |
181 | |||
182 | mt_init (& static_mtrand, 0x9f73f7fc); | ||
112 | 183 | ||
113 | for (i = 0; i < n_rounds; i += 1) | 184 | for (i = 0; i < n_rounds; i += 1) |
114 | { | 185 | { |
@@ -120,10 +191,10 @@ test_random_numbers (xd3_stream *stream, int ignore) | |||
120 | 191 | ||
121 | if (error < allowed_error && error > -allowed_error) | 192 | if (error < allowed_error && error > -allowed_error) |
122 | { | 193 | { |
123 | /*DP(RINT "error is %f\n", error);*/ | ||
124 | return 0; | 194 | return 0; |
125 | } | 195 | } |
126 | 196 | ||
197 | DP(RINT "error is %f\n", error); | ||
127 | stream->msg = "random distribution looks broken"; | 198 | stream->msg = "random distribution looks broken"; |
128 | return XD3_INTERNAL; | 199 | return XD3_INTERNAL; |
129 | } | 200 | } |
@@ -135,9 +206,9 @@ test_unlink (char* file) | |||
135 | while (unlink (file) != 0) | 206 | while (unlink (file) != 0) |
136 | { | 207 | { |
137 | if (errno == ENOENT) | 208 | if (errno == ENOENT) |
138 | { | 209 | { |
139 | break; | 210 | break; |
140 | } | 211 | } |
141 | sprintf (buf, "rm -f %s", file); | 212 | sprintf (buf, "rm -f %s", file); |
142 | system (buf); | 213 | system (buf); |
143 | } | 214 | } |
@@ -174,8 +245,8 @@ test_setup (void) | |||
174 | static int | 245 | static int |
175 | test_make_inputs (xd3_stream *stream, xoff_t *ss_out, xoff_t *ts_out) | 246 | test_make_inputs (xd3_stream *stream, xoff_t *ss_out, xoff_t *ts_out) |
176 | { | 247 | { |
177 | usize_t ts = (rand () % TEST_FILE_MEAN) + TEST_FILE_MEAN / 2; | 248 | usize_t ts = (mt_random (&static_mtrand) % TEST_FILE_MEAN) + TEST_FILE_MEAN / 2; |
178 | usize_t ss = (rand () % TEST_FILE_MEAN) + TEST_FILE_MEAN / 2; | 249 | usize_t ss = (mt_random (&static_mtrand) % TEST_FILE_MEAN) + TEST_FILE_MEAN / 2; |
179 | uint8_t *buf = malloc (ts + ss), *sbuf = buf, *tbuf = buf + ss; | 250 | uint8_t *buf = malloc (ts + ss), *sbuf = buf, *tbuf = buf + ss; |
180 | usize_t sadd = 0, sadd_max = ss * TEST_ADD_RATIO; | 251 | usize_t sadd = 0, sadd_max = ss * TEST_ADD_RATIO; |
181 | FILE *tf = NULL, *sf = NULL; | 252 | FILE *tf = NULL, *sf = NULL; |
@@ -196,7 +267,7 @@ test_make_inputs (xd3_stream *stream, xoff_t *ss_out, xoff_t *ts_out) | |||
196 | { | 267 | { |
197 | for (i = 0; i < ss; ) | 268 | for (i = 0; i < ss; ) |
198 | { | 269 | { |
199 | sbuf[i++] = rand (); | 270 | sbuf[i++] = mt_random (&static_mtrand); |
200 | } | 271 | } |
201 | } | 272 | } |
202 | 273 | ||
@@ -215,7 +286,7 @@ test_make_inputs (xd3_stream *stream, xoff_t *ss_out, xoff_t *ts_out) | |||
215 | int do_copy; | 286 | int do_copy; |
216 | 287 | ||
217 | next = min (left, next); | 288 | next = min (left, next); |
218 | do_copy = (next > add_left || (rand() / (double)RAND_MAX) >= add_prob); | 289 | do_copy = (next > add_left || (mt_random (&static_mtrand) / (double)USIZE_T_MAX) >= add_prob); |
219 | 290 | ||
220 | if (ss_out == NULL) | 291 | if (ss_out == NULL) |
221 | { | 292 | { |
@@ -229,7 +300,7 @@ test_make_inputs (xd3_stream *stream, xoff_t *ss_out, xoff_t *ts_out) | |||
229 | if (do_copy) | 300 | if (do_copy) |
230 | { | 301 | { |
231 | /* Copy */ | 302 | /* Copy */ |
232 | size_t offset = rand () % ((ss_out == NULL) ? i : (ss - next)); | 303 | size_t offset = mt_random (&static_mtrand) % ((ss_out == NULL) ? i : (ss - next)); |
233 | /* DP(RINT "[%u] copy %u at %u ", i, next, offset); */ | 304 | /* DP(RINT "[%u] copy %u at %u ", i, next, offset); */ |
234 | 305 | ||
235 | for (j = 0; j < next; j += 1) | 306 | for (j = 0; j < next; j += 1) |
@@ -246,7 +317,7 @@ test_make_inputs (xd3_stream *stream, xoff_t *ss_out, xoff_t *ts_out) | |||
246 | /* DP(RINT "[%u] add %u ", i, next); */ | 317 | /* DP(RINT "[%u] add %u ", i, next); */ |
247 | for (j = 0; j < next; j += 1) | 318 | for (j = 0; j < next; j += 1) |
248 | { | 319 | { |
249 | char c = rand (); | 320 | char c = mt_random (&static_mtrand); |
250 | /* DP(RINT "%x%x", (c >> 4) & 0xf, c & 0xf); */ | 321 | /* DP(RINT "%x%x", (c >> 4) & 0xf, c & 0xf); */ |
251 | tbuf[i++] = c; | 322 | tbuf[i++] = c; |
252 | } | 323 | } |
@@ -625,7 +696,7 @@ test_address_cache (xd3_stream *stream, int unused) | |||
625 | 696 | ||
626 | addrs[0] = 0; | 697 | addrs[0] = 0; |
627 | 698 | ||
628 | srand (0x9f73f7fc); | 699 | mt_init (& static_mtrand, 0x9f73f7fc); |
629 | 700 | ||
630 | /* First pass: encode addresses */ | 701 | /* First pass: encode addresses */ |
631 | xd3_init_cache (& stream->acache); | 702 | xd3_init_cache (& stream->acache); |
@@ -637,9 +708,9 @@ test_address_cache (xd3_stream *stream, int unused) | |||
637 | usize_t prev_i; | 708 | usize_t prev_i; |
638 | usize_t nearby; | 709 | usize_t nearby; |
639 | 710 | ||
640 | p = (rand () / (double)RAND_MAX); | 711 | p = (mt_random (&static_mtrand) / (double)USIZE_T_MAX); |
641 | prev_i = rand () % offset; | 712 | prev_i = mt_random (&static_mtrand) % offset; |
642 | nearby = (rand () % 256) % offset, 1; | 713 | nearby = (mt_random (&static_mtrand) % 256) % offset, 1; |
643 | nearby = max (1U, nearby); | 714 | nearby = max (1U, nearby); |
644 | 715 | ||
645 | if (p < 0.1) { addr = addrs[offset-nearby]; } | 716 | if (p < 0.1) { addr = addrs[offset-nearby]; } |
@@ -1081,7 +1152,7 @@ sec_dist_func6 (xd3_stream *stream, xd3_output *data) | |||
1081 | int i, ret, x; | 1152 | int i, ret, x; |
1082 | for (i = 0; i < ALPHABET_SIZE*20; i += 1) | 1153 | for (i = 0; i < ALPHABET_SIZE*20; i += 1) |
1083 | { | 1154 | { |
1084 | x = rand () % (ALPHABET_SIZE/2); | 1155 | x = mt_random (&static_mtrand) % (ALPHABET_SIZE/2); |
1085 | if ((ret = xd3_emit_byte (stream, & data, x))) { return ret; } | 1156 | if ((ret = xd3_emit_byte (stream, & data, x))) { return ret; } |
1086 | } | 1157 | } |
1087 | return 0; | 1158 | return 0; |
@@ -1094,7 +1165,7 @@ sec_dist_func7 (xd3_stream *stream, xd3_output *data) | |||
1094 | int i, ret, x; | 1165 | int i, ret, x; |
1095 | for (i = 0; i < ALPHABET_SIZE*20; i += 1) | 1166 | for (i = 0; i < ALPHABET_SIZE*20; i += 1) |
1096 | { | 1167 | { |
1097 | x = rand () % ALPHABET_SIZE; | 1168 | x = mt_random (&static_mtrand) % ALPHABET_SIZE; |
1098 | if ((ret = xd3_emit_byte (stream, & data, x))) { return ret; } | 1169 | if ((ret = xd3_emit_byte (stream, & data, x))) { return ret; } |
1099 | } | 1170 | } |
1100 | return 0; | 1171 | return 0; |
@@ -1272,7 +1343,7 @@ test_secondary (xd3_stream *stream, const xd3_sec_type *sec, int groups) | |||
1272 | DP(RINT "\n..."); | 1343 | DP(RINT "\n..."); |
1273 | for (test_i = 0; test_i < SIZEOF_ARRAY (sec_dists); test_i += 1) | 1344 | for (test_i = 0; test_i < SIZEOF_ARRAY (sec_dists); test_i += 1) |
1274 | { | 1345 | { |
1275 | srand (0x84687674); | 1346 | mt_init (& static_mtrand, 0x9f73f7fc); |
1276 | 1347 | ||
1277 | in_head = xd3_alloc_output (stream, NULL); | 1348 | in_head = xd3_alloc_output (stream, NULL); |
1278 | out_head = xd3_alloc_output (stream, NULL); | 1349 | out_head = xd3_alloc_output (stream, NULL); |
@@ -1631,7 +1702,7 @@ test_command_line_arguments (xd3_stream *stream, int ignore) | |||
1631 | xoff_t dsize; | 1702 | xoff_t dsize; |
1632 | double ratio; | 1703 | double ratio; |
1633 | 1704 | ||
1634 | srand (0x89162337); | 1705 | mt_init (& static_mtrand, 0x9f73f7fc); |
1635 | 1706 | ||
1636 | for (i = 0; i < pairs; i += 1) | 1707 | for (i = 0; i < pairs; i += 1) |
1637 | { | 1708 | { |
@@ -2019,7 +2090,7 @@ test_externally_compressed_io (xd3_stream *stream, int ignore) | |||
2019 | int i, ret; | 2090 | int i, ret; |
2020 | char buf[TESTBUFSIZE]; | 2091 | char buf[TESTBUFSIZE]; |
2021 | 2092 | ||
2022 | srand (0x91723913); | 2093 | mt_init (& static_mtrand, 0x9f73f7fc); |
2023 | 2094 | ||
2024 | if ((ret = test_make_inputs (stream, NULL, NULL))) { return ret; } | 2095 | if ((ret = test_make_inputs (stream, NULL, NULL))) { return ret; } |
2025 | 2096 | ||
@@ -2069,7 +2140,7 @@ test_source_decompression (xd3_stream *stream, int ignore) | |||
2069 | char buf[TESTBUFSIZE]; | 2140 | char buf[TESTBUFSIZE]; |
2070 | const main_extcomp *ext; | 2141 | const main_extcomp *ext; |
2071 | 2142 | ||
2072 | srand (0x9ff56acb); | 2143 | mt_init (& static_mtrand, 0x9f73f7fc); |
2073 | 2144 | ||
2074 | test_setup (); | 2145 | test_setup (); |
2075 | if ((ret = test_make_inputs (stream, NULL, NULL))) { return ret; } | 2146 | if ((ret = test_make_inputs (stream, NULL, NULL))) { return ret; } |
@@ -2265,7 +2336,7 @@ test_identical_behavior (xd3_stream *stream, int ignore) | |||
2265 | usize_t delpos = 0, recsize; | 2336 | usize_t delpos = 0, recsize; |
2266 | xd3_config config; | 2337 | xd3_config config; |
2267 | 2338 | ||
2268 | for (i = 0; i < IDB_TGTSZ; i += 1) { buf[i] = rand (); } | 2339 | for (i = 0; i < IDB_TGTSZ; i += 1) { buf[i] = mt_random (&static_mtrand); } |
2269 | 2340 | ||
2270 | stream->winsize = IDB_WINSZ; | 2341 | stream->winsize = IDB_WINSZ; |
2271 | 2342 | ||
@@ -2669,18 +2740,29 @@ xd3_selftest (void) | |||
2669 | xd3_stream stream; \ | 2740 | xd3_stream stream; \ |
2670 | xd3_config config; \ | 2741 | xd3_config config; \ |
2671 | xd3_init_config (& config, flags); \ | 2742 | xd3_init_config (& config, flags); \ |
2672 | DP(RINT "xdelta3: testing " #fn "%s...", \ | 2743 | DP(RINT "xdelta3: testing " #fn "%s...", \ |
2673 | flags ? (" (" #flags ")") : ""); \ | 2744 | flags ? (" (" #flags ")") : ""); \ |
2674 | if ((ret = xd3_config_stream (& stream, & config) == 0) && \ | 2745 | if ((ret = xd3_config_stream (& stream, & config) == 0) && \ |
2675 | (ret = test_ ## fn (& stream, arg)) == 0) { \ | 2746 | (ret = test_ ## fn (& stream, arg)) == 0) { \ |
2676 | DP(RINT " success\n"); \ | 2747 | DP(RINT " success\n"); \ |
2677 | } else { \ | 2748 | } else { \ |
2678 | DP(RINT " failed: %s: %s\n", xd3_errstring (& stream), \ | 2749 | DP(RINT " failed: %s: %s\n", xd3_errstring (& stream), \ |
2679 | xd3_mainerror (ret)); } \ | 2750 | xd3_mainerror (ret)); } \ |
2680 | xd3_free_stream (& stream); \ | 2751 | xd3_free_stream (& stream); \ |
2681 | if (ret != 0) { goto failure; } \ | 2752 | if (ret != 0) { goto failure; } \ |
2682 | } while (0) | 2753 | } while (0) |
2683 | 2754 | ||
2755 | #define DO_TEST2(fn) \ | ||
2756 | do { \ | ||
2757 | DP(RINT "xdelta3: testing " #fn "%s..."); \ | ||
2758 | if ((ret = test_ ## fn ()) == 0) { \ | ||
2759 | DP(RINT " success\n"); \ | ||
2760 | } else { \ | ||
2761 | DP(RINT " failed!\n"); \ | ||
2762 | } \ | ||
2763 | if (ret != 0) { goto failure; } \ | ||
2764 | } while (0) | ||
2765 | |||
2684 | int ret; | 2766 | int ret; |
2685 | 2767 | ||
2686 | #ifndef WIN32 | 2768 | #ifndef WIN32 |
@@ -2714,6 +2796,8 @@ xd3_selftest (void) | |||
2714 | DO_TEST (iopt_flush_instructions, 0, 0); | 2796 | DO_TEST (iopt_flush_instructions, 0, 0); |
2715 | DO_TEST (source_cksum_offset, 0, 0); | 2797 | DO_TEST (source_cksum_offset, 0, 0); |
2716 | 2798 | ||
2799 | DO_TEST2 (merge_command); | ||
2800 | |||
2717 | DO_TEST (decompress_single_bit_error, 0, 3); | 2801 | DO_TEST (decompress_single_bit_error, 0, 3); |
2718 | DO_TEST (decompress_single_bit_error, XD3_ADLER32, 3); | 2802 | DO_TEST (decompress_single_bit_error, XD3_ADLER32, 3); |
2719 | 2803 | ||
diff --git a/xdelta3/xdelta3-test2.h b/xdelta3/xdelta3-test2.h new file mode 100644 index 0000000..d2ce1ef --- /dev/null +++ b/xdelta3/xdelta3-test2.h | |||
@@ -0,0 +1,188 @@ | |||
1 | /* xdelta 3 - delta compression tools and library | ||
2 | * Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007. Joshua P. MacDonald | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | /* This file was started because xdelta3-test.h is large enough as-is, | ||
20 | * and has lots of old cruft. This is the shiny new test I always wanted. */ | ||
21 | |||
22 | static const int TESTS_PER_PARAMETER = 100; | ||
23 | |||
24 | struct random_file_spec_ { | ||
25 | int size; | ||
26 | char *tmp_copy; | ||
27 | char *tmp_delta; | ||
28 | mtrand mt; | ||
29 | }; | ||
30 | |||
31 | struct random_parameters_ { | ||
32 | int file_size; | ||
33 | int window_size; | ||
34 | int add_size; | ||
35 | int del_size; | ||
36 | }; | ||
37 | |||
38 | typedef struct random_file_spec_ random_file_spec; | ||
39 | typedef struct random_parameters_ random_parameters; | ||
40 | |||
41 | static const random_parameters test_parameters[] = { | ||
42 | { 16384, 4096, 128, 0 }, | ||
43 | { 16384, 4096, 0, 128 }, | ||
44 | { 16384, 4096, 128, 128 }, | ||
45 | { 16384, 4096, 128, 128 }, | ||
46 | }; | ||
47 | |||
48 | static random_parameters current_parameters; | ||
49 | static int test2_malloc_count; | ||
50 | |||
51 | void | ||
52 | set_test_parameters (const random_parameters *params) | ||
53 | { | ||
54 | current_parameters = *params; | ||
55 | } | ||
56 | |||
57 | void | ||
58 | set_random_parameters () | ||
59 | { | ||
60 | // TODO(jmacd) | ||
61 | current_parameters = test_parameters[0]; | ||
62 | } | ||
63 | |||
64 | void | ||
65 | test2_free (void *ptr) | ||
66 | { | ||
67 | test2_malloc_count--; | ||
68 | free (ptr); | ||
69 | XD3_ASSERT (test2_malloc_count >= 0); | ||
70 | } | ||
71 | |||
72 | void | ||
73 | random_file_spec_clear (random_file_spec *spec) | ||
74 | { | ||
75 | if (spec->tmp_copy) | ||
76 | { | ||
77 | unlink (spec->tmp_copy); /* TODO(jmacd): make portable */ | ||
78 | test2_free (spec->tmp_copy); | ||
79 | } | ||
80 | |||
81 | if (spec->tmp_delta) | ||
82 | { | ||
83 | unlink (spec->tmp_delta); | ||
84 | test2_free (spec->tmp_delta); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | void | ||
89 | random_file_spec_swap (random_file_spec *a, | ||
90 | random_file_spec *b) | ||
91 | { | ||
92 | random_file_spec t = *a; | ||
93 | *a = *b; | ||
94 | *b = t; | ||
95 | } | ||
96 | |||
97 | int | ||
98 | random_file_spec_generate (random_file_spec *spec) | ||
99 | { | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | int | ||
104 | random_file_spec_write (random_file_spec *spec) | ||
105 | { | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | int | ||
110 | random_file_spec_mutate (random_file_spec *from, random_file_spec *to) | ||
111 | { | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | int | ||
116 | random_file_spec_delta (random_file_spec *from, random_file_spec *to) | ||
117 | { | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | int | ||
122 | test_merge_chain (random_file_spec *specs, int number) | ||
123 | { | ||
124 | /* "number" is from 1 (a single delta) between specs[0] and | ||
125 | * specs[1], to N, an (N-1) chain from specs[0] to specs[N]. */ | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int | ||
130 | test_merge_command () | ||
131 | { | ||
132 | /* Repeat random-input testing for a number of iterations. | ||
133 | * Test 2, 3, and 4-file scenarios (i.e., 1, 2, and 3-delta merges). */ | ||
134 | int ret; | ||
135 | int iter = 0, param = 0; | ||
136 | random_file_spec spec[4]; | ||
137 | |||
138 | memset (spec, 0, sizeof (spec)); | ||
139 | |||
140 | /* Repeat this loop for TESTS_PER_PARAMETER * #parameters * 2. The | ||
141 | * first #parameters repeats are for the provided values, the second | ||
142 | * set of repeats use random parameters. */ | ||
143 | for (; param < (2 * SIZEOF_ARRAY(test_parameters)); iter++) | ||
144 | { | ||
145 | if (iter % TESTS_PER_PARAMETER == 0) | ||
146 | { | ||
147 | if (param < SIZEOF_ARRAY(test_parameters)) | ||
148 | { | ||
149 | set_test_parameters (&test_parameters[param]); | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | set_random_parameters (); | ||
154 | } | ||
155 | |||
156 | param++; | ||
157 | |||
158 | if ((ret = random_file_spec_generate (&spec[0]))) { return ret; } | ||
159 | if ((ret = random_file_spec_write (&spec[0]))) { return ret; } | ||
160 | |||
161 | if ((ret = random_file_spec_mutate (&spec[0], &spec[1]))) { return ret; } | ||
162 | if ((ret = random_file_spec_write (&spec[1]))) { return ret; } | ||
163 | if ((ret = random_file_spec_delta (&spec[0], &spec[1]))) { return ret; } | ||
164 | |||
165 | if ((ret = random_file_spec_mutate (&spec[1], &spec[2]))) { return ret; } | ||
166 | if ((ret = random_file_spec_write (&spec[2]))) { return ret; } | ||
167 | if ((ret = random_file_spec_delta (&spec[1], &spec[2]))) { return ret; } | ||
168 | } | ||
169 | |||
170 | /* Each iteration creates a new mutation. */ | ||
171 | if ((ret = random_file_spec_mutate (&spec[2], &spec[3]))) { return ret; } | ||
172 | if ((ret = random_file_spec_write (&spec[3]))) { return ret; } | ||
173 | if ((ret = random_file_spec_delta (&spec[2], &spec[3]))) { return ret; } | ||
174 | |||
175 | /* Test 1, 2, and 3 */ | ||
176 | if ((ret = test_merge_chain (spec, 1))) { return ret; } | ||
177 | if ((ret = test_merge_chain (spec, 2))) { return ret; } | ||
178 | if ((ret = test_merge_chain (spec, 3))) { return ret; } | ||
179 | |||
180 | /* Clear 1st input, shift inputs */ | ||
181 | random_file_spec_clear (&spec[0]); | ||
182 | random_file_spec_swap (&spec[0], &spec[1]); | ||
183 | random_file_spec_swap (&spec[1], &spec[2]); | ||
184 | random_file_spec_swap (&spec[2], &spec[3]); | ||
185 | } | ||
186 | |||
187 | return 0; | ||
188 | } | ||