diff options
author | Josh MacDonald <josh.macdonald@gmail.com> | 2015-09-29 23:56:19 -0700 |
---|---|---|
committer | Josh MacDonald <josh.macdonald@gmail.com> | 2015-09-29 23:56:19 -0700 |
commit | f63acfe3692478b983df1473bc1e7a1df3397b7f (patch) | |
tree | 7d6b42074cbb49e697b4536b5f2434f5eb4fd756 /xdelta3/testing/regtest.cc | |
parent | 1e7f716f0854ad67df9a77341a829c84e4e6b1e5 (diff) | |
parent | c6493c5a57e1edc95fa27123e86fe14c3695f284 (diff) |
Merge from HEAD
Diffstat (limited to 'xdelta3/testing/regtest.cc')
-rw-r--r-- | xdelta3/testing/regtest.cc | 118 |
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() { | 371 | void 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++) { | 380 | void 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 | ||
1003 | void FourWayMergeTest(const FileSpec &spec0, | 1011 | void 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 | ||
1211 | void 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() { | |||
1208 | template <class T> | 1254 | template <class T> |
1209 | void UnitTest() { | 1255 | void 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. |
1223 | template <class T> | 1270 | template <class T> |
1224 | void MainTest() { | 1271 | void 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 | } |