cache_util_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <stdio.h>
  5. #include <map>
  6. #include "base/files/file_enumerator.h"
  7. #include "base/files/file_util.h"
  8. #include "base/files/safe_base_name.h"
  9. #include "base/files/scoped_temp_dir.h"
  10. #include "base/run_loop.h"
  11. #include "base/strings/string_number_conversions.h"
  12. #include "base/test/bind.h"
  13. #include "base/test/scoped_feature_list.h"
  14. #include "base/test/task_environment.h"
  15. #include "base/threading/platform_thread.h"
  16. #include "build/chromeos_buildflags.h"
  17. #include "net/disk_cache/cache_util.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. #include "testing/platform_test.h"
  20. namespace disk_cache {
  21. class CacheUtilTest : public PlatformTest {
  22. public:
  23. void SetUp() override {
  24. PlatformTest::SetUp();
  25. ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
  26. cache_dir_ = tmp_dir_.GetPath().Append(FILE_PATH_LITERAL("Cache"));
  27. file1_ = base::FilePath(cache_dir_.Append(FILE_PATH_LITERAL("file01")));
  28. file2_ = base::FilePath(cache_dir_.Append(FILE_PATH_LITERAL(".file02")));
  29. dir1_ = base::FilePath(cache_dir_.Append(FILE_PATH_LITERAL("dir01")));
  30. file3_ = base::FilePath(dir1_.Append(FILE_PATH_LITERAL("file03")));
  31. ASSERT_TRUE(base::CreateDirectory(cache_dir_));
  32. FILE *fp = base::OpenFile(file1_, "w");
  33. ASSERT_TRUE(fp != nullptr);
  34. base::CloseFile(fp);
  35. fp = base::OpenFile(file2_, "w");
  36. ASSERT_TRUE(fp != nullptr);
  37. base::CloseFile(fp);
  38. ASSERT_TRUE(base::CreateDirectory(dir1_));
  39. fp = base::OpenFile(file3_, "w");
  40. ASSERT_TRUE(fp != nullptr);
  41. base::CloseFile(fp);
  42. dest_dir_ = tmp_dir_.GetPath().Append(FILE_PATH_LITERAL("old_Cache_001"));
  43. dest_file1_ = base::FilePath(dest_dir_.Append(FILE_PATH_LITERAL("file01")));
  44. dest_file2_ =
  45. base::FilePath(dest_dir_.Append(FILE_PATH_LITERAL(".file02")));
  46. dest_dir1_ = base::FilePath(dest_dir_.Append(FILE_PATH_LITERAL("dir01")));
  47. }
  48. protected:
  49. base::ScopedTempDir tmp_dir_;
  50. base::FilePath cache_dir_;
  51. base::FilePath file1_;
  52. base::FilePath file2_;
  53. base::FilePath dir1_;
  54. base::FilePath file3_;
  55. base::FilePath dest_dir_;
  56. base::FilePath dest_file1_;
  57. base::FilePath dest_file2_;
  58. base::FilePath dest_dir1_;
  59. base::test::TaskEnvironment task_environment_;
  60. };
  61. TEST_F(CacheUtilTest, MoveCache) {
  62. EXPECT_TRUE(disk_cache::MoveCache(cache_dir_, dest_dir_));
  63. EXPECT_TRUE(base::PathExists(dest_dir_));
  64. EXPECT_TRUE(base::PathExists(dest_file1_));
  65. EXPECT_TRUE(base::PathExists(dest_file2_));
  66. EXPECT_TRUE(base::PathExists(dest_dir1_));
  67. #if BUILDFLAG(IS_CHROMEOS_ASH)
  68. EXPECT_TRUE(base::PathExists(cache_dir_)); // old cache dir stays
  69. #else
  70. EXPECT_FALSE(base::PathExists(cache_dir_)); // old cache is gone
  71. #endif
  72. EXPECT_FALSE(base::PathExists(file1_));
  73. EXPECT_FALSE(base::PathExists(file2_));
  74. EXPECT_FALSE(base::PathExists(dir1_));
  75. }
  76. TEST_F(CacheUtilTest, DeleteCache) {
  77. disk_cache::DeleteCache(cache_dir_, false);
  78. EXPECT_TRUE(base::PathExists(cache_dir_)); // cache dir stays
  79. EXPECT_FALSE(base::PathExists(dir1_));
  80. EXPECT_FALSE(base::PathExists(file1_));
  81. EXPECT_FALSE(base::PathExists(file2_));
  82. EXPECT_FALSE(base::PathExists(file3_));
  83. }
  84. TEST_F(CacheUtilTest, DeleteCacheAndDir) {
  85. disk_cache::DeleteCache(cache_dir_, true);
  86. EXPECT_FALSE(base::PathExists(cache_dir_)); // cache dir is gone
  87. EXPECT_FALSE(base::PathExists(dir1_));
  88. EXPECT_FALSE(base::PathExists(file1_));
  89. EXPECT_FALSE(base::PathExists(file2_));
  90. EXPECT_FALSE(base::PathExists(file3_));
  91. }
  92. TEST_F(CacheUtilTest, CleanupDirectory) {
  93. base::RunLoop run_loop;
  94. disk_cache::CleanupDirectory(cache_dir_,
  95. base::BindLambdaForTesting([&](bool result) {
  96. EXPECT_TRUE(result);
  97. run_loop.Quit();
  98. }));
  99. run_loop.Run();
  100. while (true) {
  101. base::FileEnumerator enumerator(tmp_dir_.GetPath(), /*recursive=*/false,
  102. /*file_type=*/base::FileEnumerator::FILES |
  103. base::FileEnumerator::DIRECTORIES);
  104. bool found = false;
  105. while (true) {
  106. base::FilePath path = enumerator.Next();
  107. if (path.empty()) {
  108. break;
  109. }
  110. // We're not sure if we see an entry in the directory because it depends
  111. // on timing, but if we do, it must be "old_Cache_000".
  112. // Caveat: On ChromeOS, we leave the top-level directory ("Cache") so
  113. // it must be "Cache" or "old_Cache_000".
  114. const base::FilePath dirname = path.DirName();
  115. absl::optional<base::SafeBaseName> basename =
  116. base::SafeBaseName::Create(path);
  117. ASSERT_EQ(dirname, tmp_dir_.GetPath());
  118. ASSERT_TRUE(basename.has_value());
  119. #if BUILDFLAG(IS_CHROMEOS_ASH)
  120. if (basename->path().value() == FILE_PATH_LITERAL("Cache")) {
  121. // See the comment above.
  122. ASSERT_TRUE(base::IsDirectoryEmpty(dirname.Append(*basename)));
  123. continue;
  124. }
  125. #endif
  126. ASSERT_EQ(basename->path().value(), FILE_PATH_LITERAL("old_Cache_000"));
  127. found = true;
  128. }
  129. if (!found) {
  130. break;
  131. }
  132. base::PlatformThread::Sleep(base::Milliseconds(10));
  133. }
  134. }
  135. #if BUILDFLAG(IS_POSIX)
  136. TEST_F(CacheUtilTest, CleanupDirectoryFailsWhenParentDirectoryIsInaccessible) {
  137. base::RunLoop run_loop;
  138. ASSERT_TRUE(base::SetPosixFilePermissions(tmp_dir_.GetPath(), /*mode=*/0));
  139. disk_cache::CleanupDirectory(cache_dir_,
  140. base::BindLambdaForTesting([&](bool result) {
  141. EXPECT_FALSE(result);
  142. run_loop.Quit();
  143. }));
  144. run_loop.Run();
  145. }
  146. TEST_F(CacheUtilTest,
  147. CleanupDirectorySucceedsWhenTargetDirectoryIsInaccessible) {
  148. base::RunLoop run_loop;
  149. ASSERT_TRUE(base::SetPosixFilePermissions(cache_dir_, /*mode=*/0));
  150. disk_cache::CleanupDirectory(cache_dir_,
  151. base::BindLambdaForTesting([&](bool result) {
  152. EXPECT_TRUE(result);
  153. run_loop.Quit();
  154. }));
  155. run_loop.Run();
  156. }
  157. #endif
  158. TEST_F(CacheUtilTest, PreferredCacheSize) {
  159. const struct TestCase {
  160. int64_t available;
  161. int expected_without_trial;
  162. int expected_with_200_trial;
  163. int expected_with_250_trial;
  164. int expected_with_300_trial;
  165. } kTestCases[] = {
  166. // Weird negative value for available --- return the "default"
  167. {-1000LL, 80 * 1024 * 1024, 160 * 1024 * 1024, 200 * 1024 * 1024,
  168. 240 * 1024 * 1024},
  169. {-1LL, 80 * 1024 * 1024, 160 * 1024 * 1024, 200 * 1024 * 1024,
  170. 240 * 1024 * 1024},
  171. // 0 produces 0.
  172. {0LL, 0, 0, 0, 0},
  173. // Cache is 80% of available space, when default cache size is larger than
  174. // 80% of available space..
  175. {50 * 1024 * 1024LL, 40 * 1024 * 1024, 40 * 1024 * 1024, 40 * 1024 * 1024,
  176. 40 * 1024 * 1024},
  177. // Cache is default size, when default size is 10% to 80% of available
  178. // space.
  179. {100 * 1024 * 1024LL, 80 * 1024 * 1024, 80 * 1024 * 1024,
  180. 80 * 1024 * 1024, 80 * 1024 * 1024},
  181. {200 * 1024 * 1024LL, 80 * 1024 * 1024, 80 * 1024 * 1024,
  182. 80 * 1024 * 1024, 80 * 1024 * 1024},
  183. // Cache is 10% of available space if 2.5 * default size is more than 10%
  184. // of available space.
  185. {1000 * 1024 * 1024LL, 100 * 1024 * 1024, 200 * 1024 * 1024,
  186. 200 * 1024 * 1024, 200 * 1024 * 1024},
  187. {2000 * 1024 * 1024LL, 200 * 1024 * 1024, 400 * 1024 * 1024,
  188. 400 * 1024 * 1024, 400 * 1024 * 1024},
  189. // Cache is 2.5 * kDefaultCacheSize if 2.5 * kDefaultCacheSize uses from
  190. // 1% to 10% of available space.
  191. {10000 * 1024 * 1024LL, 200 * 1024 * 1024, 400 * 1024 * 1024,
  192. 500 * 1024 * 1024, 600 * 1024 * 1024},
  193. // Otherwise, cache is 1% of available space.
  194. {20000 * 1024 * 1024LL, 200 * 1024 * 1024, 400 * 1024 * 1024,
  195. 500 * 1024 * 1024, 600 * 1024 * 1024},
  196. // Until it runs into the cache size cap.
  197. {32000 * 1024 * 1024LL, 320 * 1024 * 1024, 640 * 1024 * 1024,
  198. 800 * 1024 * 1024, 960 * 1024 * 1024},
  199. {50000 * 1024 * 1024LL, 320 * 1024 * 1024, 640 * 1024 * 1024,
  200. 800 * 1024 * 1024, 960 * 1024 * 1024},
  201. };
  202. for (const auto& test_case : kTestCases) {
  203. EXPECT_EQ(test_case.expected_without_trial,
  204. PreferredCacheSize(test_case.available))
  205. << test_case.available;
  206. // Preferred size for WebUI code cache matches expected_without_trial but
  207. // should never be more than 5 MB.
  208. int expected_webui_code_cache_size =
  209. std::min(5 * 1024 * 1024, test_case.expected_without_trial);
  210. EXPECT_EQ(expected_webui_code_cache_size,
  211. PreferredCacheSize(test_case.available,
  212. net::GENERATED_WEBUI_BYTE_CODE_CACHE))
  213. << test_case.available;
  214. }
  215. // Check that the cache size cap is 50% higher for native code caches.
  216. EXPECT_EQ(((320 * 1024 * 1024) / 2) * 3,
  217. PreferredCacheSize(50000 * 1024 * 1024LL,
  218. net::GENERATED_NATIVE_CODE_CACHE));
  219. for (int cache_size_exeriment : {100, 200, 250, 300}) {
  220. base::test::ScopedFeatureList scoped_feature_list;
  221. std::map<std::string, std::string> field_trial_params;
  222. field_trial_params["percent_relative_size"] =
  223. base::NumberToString(cache_size_exeriment);
  224. scoped_feature_list.InitAndEnableFeatureWithParameters(
  225. disk_cache::kChangeDiskCacheSizeExperiment, field_trial_params);
  226. for (const auto& test_case : kTestCases) {
  227. int expected = 0;
  228. switch (cache_size_exeriment) {
  229. case 100:
  230. expected = test_case.expected_without_trial;
  231. break;
  232. case 200:
  233. expected = test_case.expected_with_200_trial;
  234. break;
  235. case 250:
  236. expected = test_case.expected_with_250_trial;
  237. break;
  238. case 300:
  239. expected = test_case.expected_with_300_trial;
  240. break;
  241. }
  242. EXPECT_EQ(expected, PreferredCacheSize(test_case.available));
  243. // For caches other than disk cache, the size is not scaled.
  244. EXPECT_EQ(test_case.expected_without_trial,
  245. PreferredCacheSize(test_case.available,
  246. net::GENERATED_BYTE_CODE_CACHE));
  247. // Preferred size for WebUI code cache is not scaled by the trial, and
  248. // should never be more than 5 MB.
  249. int expected_webui_code_cache_size =
  250. std::min(5 * 1024 * 1024, test_case.expected_without_trial);
  251. EXPECT_EQ(expected_webui_code_cache_size,
  252. PreferredCacheSize(test_case.available,
  253. net::GENERATED_WEBUI_BYTE_CODE_CACHE))
  254. << test_case.available;
  255. }
  256. // Check that the cache size cap is 50% higher for native code caches but is
  257. // not scaled for the experiment.
  258. EXPECT_EQ(((320 * 1024 * 1024) / 2) * 3,
  259. PreferredCacheSize(50000 * 1024 * 1024LL,
  260. net::GENERATED_NATIVE_CODE_CACHE));
  261. }
  262. // Check no "percent_relative_size" matches default behavior.
  263. {
  264. base::test::ScopedFeatureList scoped_feature_list;
  265. scoped_feature_list.InitAndEnableFeature(
  266. disk_cache::kChangeDiskCacheSizeExperiment);
  267. for (const auto& test_case : kTestCases) {
  268. EXPECT_EQ(test_case.expected_without_trial,
  269. PreferredCacheSize(test_case.available));
  270. }
  271. // Check that the cache size cap is 50% higher for native code caches.
  272. EXPECT_EQ(((320 * 1024 * 1024) / 2) * 3,
  273. PreferredCacheSize(50000 * 1024 * 1024LL,
  274. net::GENERATED_NATIVE_CODE_CACHE));
  275. }
  276. }
  277. } // namespace disk_cache