OXYGENHUB
◆ main openmsx / src / unittest / TigerTree_test.cc
2.8 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "catch.hpp"
2
3
#include "TigerTree.hh"
4
#include "ranges.hh"
5
#include "tiger.hh"
6
7
#include <algorithm>
8
#include <span>
9
10
using namespace openmsx;
11
12
struct TTTestData final : public TTData
13
{
14
	uint8_t* getData(size_t offset, size_t /*size*/) override
15
	{
16
		return buffer + offset;
17
	}
18
19
	bool isCacheStillValid(time_t&) override
20
	{
21
		return false;
22
	}
23
24
	uint8_t* buffer;
25
};
26
27
28
// TODO check that hash (re)calculation is indeed incremental
29
30
TEST_CASE("TigerTree")
31
{
32
	static constexpr auto BLOCK_SIZE = TigerTree::BLOCK_SIZE;
33
	std::array<uint8_t, 8 * BLOCK_SIZE + 1> buffer_;
34
	auto buffer = subspan(buffer_, 1);
35
	TTTestData data;
36
	data.buffer = buffer.data();
37
38
	std::string dummyName;
39
	time_t dummyTime = 0;
40
	auto dummyCallback = [](size_t, size_t) {};
41
42
	// Note: hash-values (manually) verified via the tool:
43
	//     rhash --tth <filename>
44
	SECTION("zero sized buffer") {
45
		TigerTree tt(data, 0, dummyName);
46
47
		CHECK(tt.calcHash(dummyCallback).toString() ==
48
		      "LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ");
49
	}
50
	SECTION("size less than 1 block") {
51
		TigerTree tt(data, 100, dummyName);
52
		std::ranges::fill(subspan<100>(buffer), 0);
53
		CHECK(tt.calcHash(dummyCallback).toString() ==
54
		      "EOIEKIQO6BSNCNRX2UB2MB466INV6LICZ6MPUWQ");
55
		std::ranges::fill(subspan<10>(buffer, 20), 1);
56
		tt.notifyChange(20, 10, dummyTime);
57
		CHECK(tt.calcHash(dummyCallback).toString() ==
58
		      "GOTZVYW3WIE37XFCDOY66PLLXWGP6DPN3CQRHWA");
59
	}
60
	SECTION("3 full and 1 partial block") {
61
		TigerTree tt(data, 3 * BLOCK_SIZE + 500, dummyName);
62
		std::ranges::fill(subspan<3 * BLOCK_SIZE + 500>(buffer), 0);
63
		CHECK(tt.calcHash(dummyCallback).toString() ==
64
		      "K6NHCUINLFZ7OUMUZ44JSRABL5C62WTCY2BONUI");
65
66
		std::ranges::fill(subspan<10>(buffer, BLOCK_SIZE + 500), 1);
67
		tt.notifyChange(BLOCK_SIZE + 500, 10, dummyTime); // change a single block
68
		CHECK(tt.calcHash(dummyCallback).toString() ==
69
		      "WGRG4PY3CZDLYLTC6BZ2X3G22H6DEB77JH4XPBA");
70
71
		std::ranges::fill(subspan<100>(buffer, 2 * BLOCK_SIZE - 50), 1);
72
		tt.notifyChange(2 * BLOCK_SIZE - 50, 100, dummyTime); // change 2 blocks
73
		CHECK(tt.calcHash(dummyCallback).toString() ==
74
		      "YV4NHQASK3QCYJH7FCOO4K3ABNC3WFVDDZ6FYAY");
75
76
	}
77
	SECTION("7 full blocks (unbalanced internal binary tree)") {
78
		TigerTree tt(data, 7 * BLOCK_SIZE, dummyName);
79
		std::ranges::fill(subspan<7 * BLOCK_SIZE>(buffer), 0);
80
		CHECK(tt.calcHash(dummyCallback).toString() ==
81
		      "FPSZ35773WS4WGBVXM255KWNETQZXMTEJGFMLTA");
82
83
		std::ranges::fill(subspan<500>(buffer, 500), 1);
84
		tt.notifyChange(500, 500, dummyTime); // part of block-0
85
		CHECK(tt.calcHash(dummyCallback).toString() ==
86
		      "NBCRBTHDNUDTAKZRMYO6TIQGQJIWX74BYNTYXBA");
87
88
		std::ranges::fill(subspan<4 * BLOCK_SIZE>(buffer, 3 * BLOCK_SIZE), 1);
89
		tt.notifyChange(3 * BLOCK_SIZE, 4 * BLOCK_SIZE, dummyTime); // blocks 3-6
90
		CHECK(tt.calcHash(dummyCallback).toString() ==
91
		      "PLHCYOTPV4TTXTUPHYGGVPMARGMFE4U5JYRV4VA");
92
	}
93
}