summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xdelta3/testing/regtest.cc32
-rw-r--r--xdelta3/testing/sizes.h55
-rw-r--r--xdelta3/testing/test.h4
-rw-r--r--xdelta3/xdelta3-test.h46
-rw-r--r--xdelta3/xdelta3.c1
-rw-r--r--xdelta3/xdelta3.h2
6 files changed, 96 insertions, 44 deletions
diff --git a/xdelta3/testing/regtest.cc b/xdelta3/testing/regtest.cc
index f64111e..3b4d4c6 100644
--- a/xdelta3/testing/regtest.cc
+++ b/xdelta3/testing/regtest.cc
@@ -68,8 +68,8 @@ void InMemoryEncodeDecode(FileSpec &source_file, FileSpec &target_file) {
68 ret = xd3_decode_input(&decode_stream); 68 ret = xd3_decode_input(&decode_stream);
69 } 69 }
70 70
71 DP(RINT "%s = %s\n", encoding ? "encoding" : "decoding", 71 //DP(RINT "%s = %s\n", encoding ? "encoding" : "decoding",
72 xd3_strerror(ret)); 72 // xd3_strerror(ret));
73 73
74 switch (ret) { 74 switch (ret) {
75 case XD3_OUTPUT: 75 case XD3_OUTPUT:
@@ -117,7 +117,7 @@ void InMemoryEncodeDecode(FileSpec &source_file, FileSpec &target_file) {
117 encoding = false; 117 encoding = false;
118 } else { 118 } else {
119 CHECK_EQ(0, CmpDifferentBlockBytes(decoded_block, target_block)); 119 CHECK_EQ(0, CmpDifferentBlockBytes(decoded_block, target_block));
120 DP(RINT "verified block %"Q"u\n", target_iterator.Blkno()); 120 //DP(RINT "verified block %"Q"u\n", target_iterator.Blkno());
121 decoded_block.Reset(); 121 decoded_block.Reset();
122 encoding = true; 122 encoding = true;
123 } 123 }
@@ -236,23 +236,18 @@ void TestFirstByte() {
236 spec0.GenerateFixedSize(Constants::BLOCK_SIZE + 1); 236 spec0.GenerateFixedSize(Constants::BLOCK_SIZE + 1);
237 spec0.ModifyTo<Modify1stByte>(&spec1); 237 spec0.ModifyTo<Modify1stByte>(&spec1);
238 CHECK_EQ(1, CmpDifferentBytes(spec0, spec1)); 238 CHECK_EQ(1, CmpDifferentBytes(spec0, spec1));
239}
240
241void TestBasicEncodeDecode() {
242 MTRandom rand;
243 FileSpec spec0(&rand);
244 FileSpec spec1(&rand);
245 spec0.GenerateFixedSize(1024);
246 spec0.ModifyTo<Modify1stByte>(&spec1);
247 InMemoryEncodeDecode(spec0, spec1);
248 239
249 spec0.GenerateFixedSize(Constants::BLOCK_SIZE); 240 SizeIterator<size_t, SmallSizes> si(&rand, 20);
250 spec0.ModifyTo<Modify1stByte>(&spec1);
251 InMemoryEncodeDecode(spec0, spec1);
252 241
253 spec0.GenerateFixedSize(Constants::BLOCK_SIZE * 2); 242 for (; !si.Done(); si.Next()) {
254 spec0.ModifyTo<Modify1stByte>(&spec1); 243 size_t size = si.Get();
255 InMemoryEncodeDecode(spec0, spec1); 244 if (size == 0) {
245 continue;
246 }
247 spec0.GenerateFixedSize(size);
248 spec0.ModifyTo<Modify1stByte>(&spec1);
249 InMemoryEncodeDecode(spec0, spec1);
250 }
256} 251}
257 252
258int main(int argc, char **argv) { 253int main(int argc, char **argv) {
@@ -260,7 +255,6 @@ int main(int argc, char **argv) {
260 TEST(TestRandomNumbers); 255 TEST(TestRandomNumbers);
261 TEST(TestRandomFile); 256 TEST(TestRandomFile);
262 TEST(TestFirstByte); 257 TEST(TestFirstByte);
263 TEST(TestBasicEncodeDecode);
264 return 0; 258 return 0;
265} 259}
266 260
diff --git a/xdelta3/testing/sizes.h b/xdelta3/testing/sizes.h
new file mode 100644
index 0000000..8913baa
--- /dev/null
+++ b/xdelta3/testing/sizes.h
@@ -0,0 +1,55 @@
1// -*- Mode: C++ -*-
2namespace regtest {
3
4template <typename T, typename U>
5class SizeIterator {
6 public:
7 SizeIterator(MTRandom *rand, size_t howmany)
8 : rand_(rand),
9 count_(0),
10 fixed_(U::sizes),
11 fixed_size_(SIZEOF_ARRAY(U::sizes)),
12 howmany_(howmany) { }
13
14 T Get() {
15 if (count_ < fixed_size_) {
16 return fixed_[count_];
17 }
18 return rand_->Rand<T>() % U::max_value;
19 }
20
21 bool Done() {
22 return count_ >= howmany_;
23 }
24
25 void Next() {
26 count_++;
27 }
28
29 private:
30 MTRandom *rand_;
31 size_t count_;
32 T* fixed_;
33 size_t fixed_size_;
34 size_t howmany_;
35};
36
37class SmallSizes {
38public:
39 static size_t sizes[];
40 static size_t max_value;
41};
42
43size_t SmallSizes::sizes[] = {
44 0, 1, 1024, 3333,
45 Constants::BLOCK_SIZE - 3333,
46 Constants::BLOCK_SIZE,
47 Constants::BLOCK_SIZE + 3333,
48 2 * Constants::BLOCK_SIZE - 3333,
49 2 * Constants::BLOCK_SIZE,
50 2 * Constants::BLOCK_SIZE + 3333,
51};
52
53size_t SmallSizes::max_value = Constants::BLOCK_SIZE * 3;
54
55} // namespace regtest
diff --git a/xdelta3/testing/test.h b/xdelta3/testing/test.h
index 74767fd..4d2dc8a 100644
--- a/xdelta3/testing/test.h
+++ b/xdelta3/testing/test.h
@@ -59,3 +59,7 @@ using regtest::Modify1stByte;
59 59
60#include "cmp.h" 60#include "cmp.h"
61using regtest::CmpDifferentBytes; 61using regtest::CmpDifferentBytes;
62
63#include "sizes.h"
64using regtest::SizeIterator;
65using regtest::SmallSizes;
diff --git a/xdelta3/xdelta3-test.h b/xdelta3/xdelta3-test.h
index 02c440a..c34aa3f 100644
--- a/xdelta3/xdelta3-test.h
+++ b/xdelta3/xdelta3-test.h
@@ -31,7 +31,7 @@
31 31
32struct mtrand_ { 32struct mtrand_ {
33 int mt_index; 33 int mt_index;
34 usize_t mt_buffer[MT_LEN]; 34 uint32_t mt_buffer[MT_LEN];
35}; 35};
36 36
37typedef struct mtrand_ mtrand; 37typedef struct mtrand_ mtrand;
@@ -46,13 +46,13 @@ static void mt_init (mtrand *mt, int seed) {
46 mt->mt_index = 0; 46 mt->mt_index = 0;
47} 47}
48 48
49static usize_t mt_random (mtrand *mt) { 49static uint32_t mt_random (mtrand *mt) {
50 usize_t * b = mt->mt_buffer; 50 uint32_t * b = mt->mt_buffer;
51 int idx = mt->mt_index; 51 int idx = mt->mt_index;
52 usize_t s; 52 uint32_t s;
53 int i; 53 int i;
54 54
55 if (idx == MT_LEN*sizeof(usize_t)) 55 if (idx == MT_LEN*sizeof(uint32_t))
56 { 56 {
57 idx = 0; 57 idx = 0;
58 i = 0; 58 i = 0;
@@ -68,14 +68,25 @@ static usize_t mt_random (mtrand *mt) {
68 s = TWIST(b, MT_LEN-1, 0); 68 s = TWIST(b, MT_LEN-1, 0);
69 b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s); 69 b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s);
70 } 70 }
71 mt->mt_index = idx + sizeof(usize_t); 71 mt->mt_index = idx + sizeof(uint32_t);
72 return *(usize_t *)((unsigned char *)b + idx); 72 return *(uint32_t *)((unsigned char *)b + idx);
73} 73}
74 74
75static mtrand static_mtrand; 75static mtrand static_mtrand;
76 76
77#include <math.h> 77#include <math.h>
78 78
79static uint32_t
80mt_exp_rand (uint32_t mean, uint32_t max_value)
81{
82 double mean_d = mean;
83 double erand = log (1.0 / (mt_random (&static_mtrand) /
84 (double)UINT32_MAX));
85 uint32_t x = (uint32_t) (mean_d * erand + 0.5);
86
87 return min (x, max_value);
88}
89
79#ifndef WIN32 90#ifndef WIN32
80#include <sys/wait.h> 91#include <sys/wait.h>
81#endif 92#endif
@@ -103,8 +114,6 @@ static char TEST_RECON2_FILE[TESTFILESIZE];
103static char TEST_COPY_FILE[TESTFILESIZE]; 114static char TEST_COPY_FILE[TESTFILESIZE];
104static char TEST_NOPERM_FILE[TESTFILESIZE]; 115static char TEST_NOPERM_FILE[TESTFILESIZE];
105 116
106static int test_exponential_dist (usize_t mean, usize_t max);
107
108#define CHECK(cond) if (!(cond)) { DP(RINT "check failure: " #cond); abort(); } 117#define CHECK(cond) if (!(cond)) { DP(RINT "check failure: " #cond); abort(); }
109 118
110/* Use a fixed soft config so that test values are fixed. See also 119/* Use a fixed soft config so that test values are fixed. See also
@@ -149,17 +158,6 @@ static int do_fail (xd3_stream *stream, const char *buf)
149 return 0; 158 return 0;
150} 159}
151 160
152static int
153test_exponential_dist (usize_t mean, usize_t max_value)
154{
155 double mean_d = mean;
156 double erand = log (1.0 / (mt_random (&static_mtrand) /
157 (double)USIZE_T_MAX));
158 usize_t x = (usize_t) (mean_d * erand + 0.5);
159
160 return min (x, max_value);
161}
162
163/* Test that the exponential distribution actually produces its mean. */ 161/* Test that the exponential distribution actually produces its mean. */
164static int 162static int
165test_random_numbers (xd3_stream *stream, int ignore) 163test_random_numbers (xd3_stream *stream, int ignore)
@@ -175,7 +173,7 @@ test_random_numbers (xd3_stream *stream, int ignore)
175 173
176 for (i = 0; i < n_rounds; i += 1) 174 for (i = 0; i < n_rounds; i += 1)
177 { 175 {
178 sum += test_exponential_dist (mean, USIZE_T_MAX); 176 sum += mt_exp_rand (mean, USIZE_T_MAX);
179 } 177 }
180 178
181 average = (double) sum / (double) n_rounds; 179 average = (double) sum / (double) n_rounds;
@@ -272,7 +270,7 @@ test_make_inputs (xd3_stream *stream, xoff_t *ss_out, xoff_t *ts_out)
272 for (i = 0; i < ts; ) 270 for (i = 0; i < ts; )
273 { 271 {
274 size_t left = ts - i; 272 size_t left = ts - i;
275 size_t next = test_exponential_dist (TEST_ADD_MEAN, TEST_ADD_MAX); 273 size_t next = mt_exp_rand (TEST_ADD_MEAN, TEST_ADD_MAX);
276 size_t add_left = sadd_max - sadd; 274 size_t add_left = sadd_max - sadd;
277 double add_prob = (left == 0) ? 0 : (add_left / (double) left); 275 double add_prob = (left == 0) ? 0 : (add_left / (double) left);
278 int do_copy; 276 int do_copy;
@@ -1120,7 +1118,7 @@ sec_dist_func4 (xd3_stream *stream, xd3_output *data)
1120 int i, ret, x; 1118 int i, ret, x;
1121 for (i = 0; i < ALPHABET_SIZE*20; i += 1) 1119 for (i = 0; i < ALPHABET_SIZE*20; i += 1)
1122 { 1120 {
1123 x = test_exponential_dist (10, ALPHABET_SIZE/2); 1121 x = mt_exp_rand (10, ALPHABET_SIZE/2);
1124 if ((ret = xd3_emit_byte (stream, & data, x))) { return ret; } 1122 if ((ret = xd3_emit_byte (stream, & data, x))) { return ret; }
1125 } 1123 }
1126 return 0; 1124 return 0;
@@ -1133,7 +1131,7 @@ sec_dist_func5 (xd3_stream *stream, xd3_output *data)
1133 int i, ret, x; 1131 int i, ret, x;
1134 for (i = 0; i < ALPHABET_SIZE*20; i += 1) 1132 for (i = 0; i < ALPHABET_SIZE*20; i += 1)
1135 { 1133 {
1136 x = test_exponential_dist (10, ALPHABET_SIZE-1); 1134 x = mt_exp_rand (10, ALPHABET_SIZE-1);
1137 if ((ret = xd3_emit_byte (stream, & data, x))) { return ret; } 1135 if ((ret = xd3_emit_byte (stream, & data, x))) { return ret; }
1138 } 1136 }
1139 return 0; 1137 return 0;
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c
index 60a348d..77fc534 100644
--- a/xdelta3/xdelta3.c
+++ b/xdelta3/xdelta3.c
@@ -3801,6 +3801,7 @@ xd3_encode_input (xd3_stream *stream)
3801 else 3801 else
3802 { 3802 {
3803 stream->match_state = MATCH_SEARCHING; 3803 stream->match_state = MATCH_SEARCHING;
3804 stream->match_fwd = 0;
3804 } 3805 }
3805 XD3_ASSERT (stream->match_fwd == 0); 3806 XD3_ASSERT (stream->match_fwd == 0);
3806 3807
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h
index f5b75d1..fa5b332 100644
--- a/xdelta3/xdelta3.h
+++ b/xdelta3/xdelta3.h
@@ -1207,7 +1207,7 @@ void xd3_avail_input (xd3_stream *stream,
1207 * xd3_avail_input it will return XD3_INPUT right away without 1207 * xd3_avail_input it will return XD3_INPUT right away without
1208 * allocating a stream->winsize buffer. This is to avoid an 1208 * allocating a stream->winsize buffer. This is to avoid an
1209 * unwanted allocation. */ 1209 * unwanted allocation. */
1210 XD3_ASSERT (idata != NULL); 1210 XD3_ASSERT (idata != NULL || isize == 0);
1211 1211
1212 stream->next_in = idata; 1212 stream->next_in = idata;
1213 stream->avail_in = isize; 1213 stream->avail_in = isize;