OXYGENHUB
◆ main openmsx / src / unittest / FilePoolCore_test.cc
4.4 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "catch.hpp"
2
3
#include "FilePoolCore.hh"
4
#include "File.hh"
5
#include "FileOperations.hh"
6
#include "one_of.hh"
7
#include "StringOp.hh"
8
#include "Timer.hh"
9
#include <iostream>
10
#include <fstream>
11
12
using namespace openmsx;
13
14
static void createFile(const std::string& filename, const std::string& content)
15
{
16
	std::ofstream of(filename);
17
	of << content;
18
}
19
20
static std::vector<std::string> readLines(const std::string& filename)
21
{
22
	std::vector<std::string> result;
23
	std::ifstream is(filename);
24
	std::string line;
25
	while (std::getline(is, line)) {
26
		result.push_back(line);
27
	}
28
	return result;
29
}
30
31
TEST_CASE("FilePoolCore")
32
{
33
	auto tmp = FileOperations::getTempDir() + "/filepool_unittest";
34
	FileOperations::deleteRecursive(tmp);
35
	FileOperations::mkdirp(tmp);
36
	createFile(tmp + "/a",  "aaa"); // 7e240de74fb1ed08fa08d38063f6a6a91462a815
37
	createFile(tmp + "/a2", "aaa"); // same content, different filename
38
	createFile(tmp + "/b",  "bbb"); // 5cb138284d431abd6a053a56625ec088bfb88912
39
40
	auto getDirectories = [&] {
41
		FilePoolCore::Directories result;
42
		result.emplace_back(tmp, FileType::ROM);
43
		return result;
44
	};
45
46
	{
47
		// create pool
48
		FilePoolCore pool(tmp + "/cache",
49
				  getDirectories,
50
				  [](std::string_view, float) { /* report progress: nothing */});
51
52
		// lookup, success
53
		{
54
			auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("7e240de74fb1ed08fa08d38063f6a6a91462a815"));
55
			CHECK(file.is_open());
56
			CHECK(fname == one_of(tmp + "/a", tmp + "/a2"));
57
		}
58
		// lookup, not (yet) present
59
		{
60
			auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("f36b4825e5db2cf7dd2d2593b3f5c24c0311d8b2"));
61
			CHECK(!file.is_open());
62
		}
63
		// lookup, success
64
		{
65
			auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("5cb138284d431abd6a053a56625ec088bfb88912"));
66
			CHECK(file.is_open());
67
			CHECK(fname == tmp + "/b");
68
		}
69
		// create new file, and lookup
70
		createFile(tmp + "/c",  "ccc"); // f36b4825e5db2cf7dd2d2593b3f5c24c0311d8b2
71
		{
72
			auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("f36b4825e5db2cf7dd2d2593b3f5c24c0311d8b2"));
73
			CHECK(file.is_open());
74
			CHECK(fname == tmp + "/c");
75
		}
76
		// modify file, old no longer present, new is present
77
		FileOperations::unlink(tmp + "/b");
78
		Timer::sleep(1'000'000); // sleep because timestamps are only accurate to 1 second
79
		createFile(tmp + "/b",  "BBB"); // aa6878b1c31a9420245df1daffb7b223338737a3
80
		{
81
			auto [file1, fname1] = pool.getFile(FileType::ROM, Sha1Sum("5cb138284d431abd6a053a56625ec088bfb88912"));
82
			CHECK(!file1.is_open());
83
			auto [file2, fname2] = pool.getFile(FileType::ROM, Sha1Sum("aa6878b1c31a9420245df1daffb7b223338737a3"));
84
			CHECK(file2.is_open());
85
			CHECK(fname2 == tmp + "/b");
86
		}
87
		// modify file, but keep same content, IOW only update timestamp
88
		FileOperations::unlink(tmp + "/b");
89
		Timer::sleep(1'000'000); // sleep because timestamps are only accurate to 1 second
90
		createFile(tmp + "/b",  "BBB"); // aa6878b1c31a9420245df1daffb7b223338737a3
91
		{
92
			auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("aa6878b1c31a9420245df1daffb7b223338737a3"));
93
			CHECK(file.is_open());
94
			CHECK(fname == tmp + "/b");
95
		}
96
		// remove file
97
		FileOperations::unlink(tmp + "/b");
98
		{
99
			auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("aa6878b1c31a9420245df1daffb7b223338737a3"));
100
			CHECK(!file.is_open());
101
		}
102
103
		// calc sha1 of cached file
104
		{
105
			auto fname = tmp + "/a2";
106
			File file(fname);
107
			CHECK(file.is_open());
108
			auto sum = pool.getSha1Sum(file, fname);
109
			CHECK(sum == Sha1Sum("7e240de74fb1ed08fa08d38063f6a6a91462a815"));
110
		}
111
		// calc sha1 of new file
112
		createFile(tmp + "/e",  "eee");
113
		{
114
			auto fname = tmp + "/e";
115
			File file(fname);
116
			CHECK(file.is_open());
117
			auto sum = pool.getSha1Sum(file, fname);
118
			CHECK(sum == Sha1Sum("637a81ed8e8217bb01c15c67c39b43b0ab4e20f1"));
119
		}
120
	}
121
122
	// write 'filecache' to disk
123
	auto lines = readLines(tmp + "/cache");
124
	CHECK(lines.size() == 4);
125
	CHECK(lines[0].starts_with("637a81ed8e8217bb01c15c67c39b43b0ab4e20f1"));
126
	CHECK(lines[0].ends_with(tmp + "/e"));
127
	CHECK(lines[1].starts_with("7e240de74fb1ed08fa08d38063f6a6a91462a815"));
128
	CHECK((lines[1].ends_with(tmp + "/a") ||
129
	       lines[1].ends_with(tmp + "/a2")));
130
	CHECK(lines[2].starts_with("7e240de74fb1ed08fa08d38063f6a6a91462a815"));
131
	CHECK((lines[2].ends_with(tmp + "/a") ||
132
	       lines[2].ends_with(tmp + "/a2")));
133
	CHECK(lines[3].starts_with("f36b4825e5db2cf7dd2d2593b3f5c24c0311d8b2"));
134
	CHECK(lines[3].ends_with(tmp + "/c"));
135
136
	FileOperations::deleteRecursive(tmp);
137
}