FilePoolCore_test.cc 4.4 KB

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