| 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"); |
| 37 |
createFile(tmp + "/a2", "aaa"); |
| 38 |
createFile(tmp + "/b", "bbb"); |
| 39 |
|
| 40 |
auto getDirectories = [&] { |
| 41 |
FilePoolCore::Directories result; |
| 42 |
result.emplace_back(tmp, FileType::ROM); |
| 43 |
return result; |
| 44 |
}; |
| 45 |
|
| 46 |
{ |
| 47 |
|
| 48 |
FilePoolCore pool(tmp + "/cache", |
| 49 |
getDirectories, |
| 50 |
[](std::string_view, float) { }); |
| 51 |
|
| 52 |
|
| 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 |
|
| 59 |
{ |
| 60 |
auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("f36b4825e5db2cf7dd2d2593b3f5c24c0311d8b2")); |
| 61 |
CHECK(!file.is_open()); |
| 62 |
} |
| 63 |
|
| 64 |
{ |
| 65 |
auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("5cb138284d431abd6a053a56625ec088bfb88912")); |
| 66 |
CHECK(file.is_open()); |
| 67 |
CHECK(fname == tmp + "/b"); |
| 68 |
} |
| 69 |
|
| 70 |
createFile(tmp + "/c", "ccc"); |
| 71 |
{ |
| 72 |
auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("f36b4825e5db2cf7dd2d2593b3f5c24c0311d8b2")); |
| 73 |
CHECK(file.is_open()); |
| 74 |
CHECK(fname == tmp + "/c"); |
| 75 |
} |
| 76 |
|
| 77 |
FileOperations::unlink(tmp + "/b"); |
| 78 |
Timer::sleep(1'000'000); |
| 79 |
createFile(tmp + "/b", "BBB"); |
| 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 |
|
| 88 |
FileOperations::unlink(tmp + "/b"); |
| 89 |
Timer::sleep(1'000'000); |
| 90 |
createFile(tmp + "/b", "BBB"); |
| 91 |
{ |
| 92 |
auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("aa6878b1c31a9420245df1daffb7b223338737a3")); |
| 93 |
CHECK(file.is_open()); |
| 94 |
CHECK(fname == tmp + "/b"); |
| 95 |
} |
| 96 |
|
| 97 |
FileOperations::unlink(tmp + "/b"); |
| 98 |
{ |
| 99 |
auto [file, fname] = pool.getFile(FileType::ROM, Sha1Sum("aa6878b1c31a9420245df1daffb7b223338737a3")); |
| 100 |
CHECK(!file.is_open()); |
| 101 |
} |
| 102 |
|
| 103 |
|
| 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 |
|
| 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 |
|
| 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 |
} |