summaryrefslogtreecommitdiff
path: root/xdelta3/testing/regtest.cc
diff options
context:
space:
mode:
authorJosh MacDonald <josh.macdonald@gmail.com>2015-09-29 23:56:19 -0700
committerJosh MacDonald <josh.macdonald@gmail.com>2015-09-29 23:56:19 -0700
commitf63acfe3692478b983df1473bc1e7a1df3397b7f (patch)
tree7d6b42074cbb49e697b4536b5f2434f5eb4fd756 /xdelta3/testing/regtest.cc
parent1e7f716f0854ad67df9a77341a829c84e4e6b1e5 (diff)
parentc6493c5a57e1edc95fa27123e86fe14c3695f284 (diff)
Merge from HEAD
Diffstat (limited to 'xdelta3/testing/regtest.cc')
-rw-r--r--xdelta3/testing/regtest.cc118
1 files changed, 83 insertions, 35 deletions
diff --git a/xdelta3/testing/regtest.cc b/xdelta3/testing/regtest.cc
index afeb5e2..bee7477 100644
--- a/xdelta3/testing/regtest.cc
+++ b/xdelta3/testing/regtest.cc
@@ -12,12 +12,14 @@ public:
12 Options() 12 Options()
13 : encode_srcwin_maxsz(1<<20), 13 : encode_srcwin_maxsz(1<<20),
14 block_size(Constants::BLOCK_SIZE), 14 block_size(Constants::BLOCK_SIZE),
15 window_size(Constants::WINDOW_SIZE),
15 size_known(false), 16 size_known(false),
16 iopt_size(XD3_DEFAULT_IOPT_SIZE), 17 iopt_size(XD3_DEFAULT_IOPT_SIZE),
17 smatch_cfg(XD3_SMATCH_DEFAULT) { } 18 smatch_cfg(XD3_SMATCH_DEFAULT) { }
18 19
19 xoff_t encode_srcwin_maxsz; 20 xoff_t encode_srcwin_maxsz;
20 size_t block_size; 21 size_t block_size;
22 xoff_t window_size;
21 bool size_known; 23 bool size_known;
22 usize_t iopt_size; 24 usize_t iopt_size;
23 xd3_smatch_cfg smatch_cfg; 25 xd3_smatch_cfg smatch_cfg;
@@ -56,7 +58,7 @@ public:
56 xd3_init_config(&encode_config, XD3_ADLER32); 58 xd3_init_config(&encode_config, XD3_ADLER32);
57 xd3_init_config(&decode_config, XD3_ADLER32); 59 xd3_init_config(&decode_config, XD3_ADLER32);
58 60
59 encode_config.winsize = Constants::WINDOW_SIZE; 61 encode_config.winsize = options.window_size;
60 encode_config.iopt_size = options.iopt_size; 62 encode_config.iopt_size = options.iopt_size;
61 encode_config.smatch_cfg = options.smatch_cfg; 63 encode_config.smatch_cfg = options.smatch_cfg;
62 64
@@ -151,11 +153,11 @@ public:
151 xd3_source *src = (encoding ? &encode_source : &decode_source); 153 xd3_source *src = (encoding ? &encode_source : &decode_source);
152 Block *block = (encoding ? &encode_source_block : &decode_source_block); 154 Block *block = (encoding ? &encode_source_block : &decode_source_block);
153 if (encoding) { 155 if (encoding) {
154 IF_DEBUG1(XPR(NTR "[srcblock] %"Q" last srcpos %"Q" " 156 IF_DEBUG1(XPR(NTR "[srcblock] %"Q"u last srcpos %"Q"u "
155 "encodepos %"Q"\n", 157 "encodepos %"Q"u\n",
156 encode_source.getblkno, 158 encode_source.getblkno,
157 encode_stream.match_last_srcpos, 159 encode_stream.match_last_srcpos,
158 encode_stream.input_position + encode_stream.total_in)); 160 encode_stream.input_position + encode_stream.total_in));
159 } 161 }
160 162
161 source_iterator.SetBlock(src->getblkno); 163 source_iterator.SetBlock(src->getblkno);
@@ -228,10 +230,10 @@ public:
228 ExtFile *coded_data, 230 ExtFile *coded_data,
229 const Options &options) { 231 const Options &options) {
230 vector<const char*> ecmd; 232 vector<const char*> ecmd;
231 char wbuf[16]; 233 char bbuf[16];
232 snprintf(wbuf, sizeof(wbuf), "-B%"Q, options.encode_srcwin_maxsz); 234 snprintf(bbuf, sizeof(bbuf), "-B%"Q"u", options.encode_srcwin_maxsz);
233 ecmd.push_back("xdelta3"); 235 ecmd.push_back("xdelta3");
234 ecmd.push_back(wbuf); 236 ecmd.push_back(bbuf);
235 ecmd.push_back("-s"); 237 ecmd.push_back("-s");
236 ecmd.push_back(source_file.Name()); 238 ecmd.push_back(source_file.Name());
237 ecmd.push_back(target_file.Name()); 239 ecmd.push_back(target_file.Name());
@@ -244,7 +246,7 @@ public:
244 vector<const char*> dcmd; 246 vector<const char*> dcmd;
245 ExtFile recon_file; 247 ExtFile recon_file;
246 dcmd.push_back("xdelta3"); 248 dcmd.push_back("xdelta3");
247 ecmd.push_back(wbuf); 249 ecmd.push_back(bbuf);
248 dcmd.push_back("-d"); 250 dcmd.push_back("-d");
249 dcmd.push_back("-s"); 251 dcmd.push_back("-s");
250 dcmd.push_back(source_file.Name()); 252 dcmd.push_back(source_file.Name());
@@ -364,28 +366,37 @@ public:
364 CHECK_EQ(0, CmpDifferentBlockBytes(to, recon)); 366 CHECK_EQ(0, CmpDifferentBlockBytes(to, recon));
365 } 367 }
366 368
367 ////////////////////////////////////////////////////////////////////// 369//////////////////////////////////////////////////////////////////////
368 370
369 void TestRandomNumbers() { 371void TestPrintf() {
370 MTRandom rand; 372 char buf[64];
371 int rounds = 1<<20; 373 xoff_t x = XOFF_T_MAX;
372 uint64_t usum = 0; 374 snprintf_func (buf, sizeof(buf), "%"Q"u", x);
373 uint64_t esum = 0; 375 const char *expect = XD3_USE_LARGEFILE64 ?
376 "18446744073709551615" : "4294967295";
377 XD3_ASSERT(strcmp (buf, expect) == 0);
378}
374 379
375 for (int i = 0; i < rounds; i++) { 380void TestRandomNumbers() {
376 usum += rand.Rand32(); 381 MTRandom rand;
377 esum += rand.ExpRand32(1024); 382 int rounds = 1<<20;
378 } 383 uint64_t usum = 0;
384 uint64_t esum = 0;
379 385
380 double allowed_error = 0.01; 386 for (int i = 0; i < rounds; i++) {
387 usum += rand.Rand32();
388 esum += rand.ExpRand32(1024);
389 }
390
391 double allowed_error = 0.01;
381 392
382 uint32_t umean = usum / rounds; 393 uint32_t umean = usum / rounds;
383 uint32_t emean = esum / rounds; 394 uint32_t emean = esum / rounds;
384 395
385 uint32_t uexpect = UINT32_MAX / 2; 396 uint32_t uexpect = UINT32_MAX / 2;
386 uint32_t eexpect = 1024; 397 uint32_t eexpect = 1024;
387 398
388 if (umean < uexpect * (1.0 - allowed_error) || 399 if (umean < uexpect * (1.0 - allowed_error) ||
389 umean > uexpect * (1.0 + allowed_error)) { 400 umean > uexpect * (1.0 + allowed_error)) {
390 XPR(NT "uniform mean error: %u != %u\n", umean, uexpect); 401 XPR(NT "uniform mean error: %u != %u\n", umean, uexpect);
391 abort(); 402 abort();
@@ -574,7 +585,7 @@ void TestDeleteMutator() {
574 585
575 for (size_t i = 0; i < SIZEOF_ARRAY(test_cases); i++) { 586 for (size_t i = 0; i < SIZEOF_ARRAY(test_cases); i++) {
576 ChangeList cl1; 587 ChangeList cl1;
577 cl1.push_back(Change(Change::DELETE, test_cases[i].size, 588 cl1.push_back(Change(Change::DELRANGE, test_cases[i].size,
578 test_cases[i].addr)); 589 test_cases[i].addr));
579 spec0.ModifyTo(ChangeListMutator(cl1), &spec1); 590 spec0.ModifyTo(ChangeListMutator(cl1), &spec1);
580 CHECK_EQ(spec0.Size() - test_cases[i].size, spec1.Size()); 591 CHECK_EQ(spec0.Size() - test_cases[i].size, spec1.Size());
@@ -837,7 +848,6 @@ void TestCopyWindow() {
837 options.encode_srcwin_maxsz = size; 848 options.encode_srcwin_maxsz = size;
838 options.iopt_size = 128; 849 options.iopt_size = 128;
839 options.smatch_cfg = XD3_SMATCH_SLOW; 850 options.smatch_cfg = XD3_SMATCH_SLOW;
840 options.size_known = false;
841 851
842 Block block1; 852 Block block1;
843 InMemoryEncodeDecode(spec0, spec1, &block1, options); 853 InMemoryEncodeDecode(spec0, spec1, &block1, options);
@@ -978,7 +988,6 @@ void TestHalfBlockCopy() {
978 // When there are fewer than 3 source blocks. 988 // When there are fewer than 3 source blocks.
979 CHECK_EQ(nocopy_adds, delta1.AddedBytes()); 989 CHECK_EQ(nocopy_adds, delta1.AddedBytes());
980 } 990 }
981 // XPR(NT "0=%zu 1=%zu\n", delta0.AddedBytes(), delta1.AddedBytes());
982 } 991 }
983 992
984 Options options; 993 Options options;
@@ -997,7 +1006,6 @@ void TestHalfBlockCopy() {
997 CHECK_GE(onecopy_adds + 1, delta0.AddedBytes()); 1006 CHECK_GE(onecopy_adds + 1, delta0.AddedBytes());
998 1007
999 CHECK_EQ(onecopy_adds, delta1.AddedBytes()); 1008 CHECK_EQ(onecopy_adds, delta1.AddedBytes());
1000 // XPR(NT "0=%zu 1=%zu\n", delta0.AddedBytes(), delta1.AddedBytes());
1001} 1009}
1002 1010
1003void FourWayMergeTest(const FileSpec &spec0, 1011void FourWayMergeTest(const FileSpec &spec0,
@@ -1130,7 +1138,7 @@ void TestMergeCommand1() {
1130 } 1138 }
1131 1139
1132 cl1.push_back(Change(Change::ADD, change1, add1_pos)); 1140 cl1.push_back(Change(Change::ADD, change1, add1_pos));
1133 cl2.push_back(Change(Change::DELETE, change1, del2_pos)); 1141 cl2.push_back(Change(Change::DELRANGE, change1, del2_pos));
1134 cl3.push_back(Change(Change::MODIFY, change3, change3_pos)); 1142 cl3.push_back(Change(Change::MODIFY, change3, change3_pos));
1135 1143
1136 spec0.ModifyTo(ChangeListMutator(cl1), &spec1); 1144 spec0.ModifyTo(ChangeListMutator(cl1), &spec1);
@@ -1184,9 +1192,9 @@ void TestMergeCommand2() {
1184 1192
1185 ChangeList cl1, cl2, cl3; 1193 ChangeList cl1, cl2, cl3;
1186 1194
1187 cl1.push_back(Change(Change::DELETE, size0 - size1, 0)); 1195 cl1.push_back(Change(Change::DELRANGE, size0 - size1, 0));
1188 cl2.push_back(Change(Change::DELETE, size0 - size2, 0)); 1196 cl2.push_back(Change(Change::DELRANGE, size0 - size2, 0));
1189 cl3.push_back(Change(Change::DELETE, size0 - size3, 0)); 1197 cl3.push_back(Change(Change::DELRANGE, size0 - size3, 0));
1190 1198
1191 spec0.ModifyTo(ChangeListMutator(cl1), &spec1); 1199 spec0.ModifyTo(ChangeListMutator(cl1), &spec1);
1192 spec0.ModifyTo(ChangeListMutator(cl2), &spec2); 1200 spec0.ModifyTo(ChangeListMutator(cl2), &spec2);
@@ -1200,6 +1208,44 @@ void TestMergeCommand2() {
1200 } 1208 }
1201} 1209}
1202 1210
1211void TestLastFrontierBlock() {
1212 // This test constructs an input that can expose
1213 // https://github.com/jmacd/xdelta/issues/188
1214 // when run through the command-line with source via a FIFO.
1215 // That is not tested here, but the test stays.
1216 if (Constants::WINDOW_SIZE < XD3_ALLOCSIZE)
1217 {
1218 return;
1219 }
1220
1221 MTRandom rand;
1222 FileSpec spec0(&rand);
1223 FileSpec spec1(&rand);
1224 const xoff_t size = XD3_ALLOCSIZE * 64; // == XD3_MINSRCWINSZ * 2
1225 const xoff_t edit = XD3_ALLOCSIZE;
1226
1227 Options options;
1228 options.encode_srcwin_maxsz = XD3_MINSRCWINSZ;
1229 options.block_size = XD3_ALLOCSIZE;
1230 options.window_size = XD3_MINSRCWINSZ;
1231 options.size_known = false;
1232
1233 spec0.GenerateFixedSize(size);
1234
1235 ChangeList cl;
1236
1237 // Modify the 0th byte in order to induce indexing of subsequent
1238 // bytes, but allow copying most of the file to keep the test fast.
1239 cl.push_back(Change(Change::MODIFY, 1, edit * 31));
1240 cl.push_back(Change(Change::COPYOVER, edit, edit * 31, edit * 63));
1241
1242 spec0.ModifyTo(ChangeListMutator(cl), &spec1);
1243
1244 Block noblock;
1245 InMemoryEncodeDecode(spec0, spec1, &noblock, options);
1246 InMemoryEncodeDecode(spec1, spec0, &noblock, options);
1247}
1248
1203}; // class Regtest<Constants> 1249}; // class Regtest<Constants>
1204 1250
1205#define TEST(x) XPR(NTR #x "...\n"); regtest.x() 1251#define TEST(x) XPR(NTR #x "...\n"); regtest.x()
@@ -1208,6 +1254,7 @@ void TestMergeCommand2() {
1208template <class T> 1254template <class T>
1209void UnitTest() { 1255void UnitTest() {
1210 Regtest<T> regtest; 1256 Regtest<T> regtest;
1257 TEST(TestPrintf);
1211 TEST(TestRandomNumbers); 1258 TEST(TestRandomNumbers);
1212 TEST(TestRandomFile); 1259 TEST(TestRandomFile);
1213 TEST(TestFirstByte); 1260 TEST(TestFirstByte);
@@ -1222,7 +1269,7 @@ void UnitTest() {
1222// These are Xdelta tests. 1269// These are Xdelta tests.
1223template <class T> 1270template <class T>
1224void MainTest() { 1271void MainTest() {
1225 XPR(NT "Blocksize %"Q" windowsize %zu\n", 1272 XPR(NT "Blocksize %"Q"u windowsize %"Z"u\n",
1226 T::BLOCK_SIZE, T::WINDOW_SIZE); 1273 T::BLOCK_SIZE, T::WINDOW_SIZE);
1227 Regtest<T> regtest; 1274 Regtest<T> regtest;
1228 TEST(TestEmptyInMemory); 1275 TEST(TestEmptyInMemory);
@@ -1232,6 +1279,7 @@ void MainTest() {
1232 TEST(TestCopyFromEnd); 1279 TEST(TestCopyFromEnd);
1233 TEST(TestNonBlocking); 1280 TEST(TestNonBlocking);
1234 TEST(TestHalfBlockCopy); 1281 TEST(TestHalfBlockCopy);
1282 TEST(TestLastFrontierBlock);
1235 TEST(TestMergeCommand1); 1283 TEST(TestMergeCommand1);
1236 TEST(TestMergeCommand2); 1284 TEST(TestMergeCommand2);
1237} 1285}