file_system_quota_client_unittest.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. // Copyright 2013 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 <stdint.h>
  5. #include <memory>
  6. #include <vector>
  7. #include "base/bind.h"
  8. #include "base/cxx17_backports.h"
  9. #include "base/files/file_util.h"
  10. #include "base/files/scoped_temp_dir.h"
  11. #include "base/run_loop.h"
  12. #include "base/test/scoped_feature_list.h"
  13. #include "base/test/task_environment.h"
  14. #include "base/test/test_future.h"
  15. #include "base/threading/sequenced_task_runner_handle.h"
  16. #include "components/services/storage/public/cpp/buckets/bucket_locator.h"
  17. #include "components/services/storage/public/mojom/quota_client.mojom.h"
  18. #include "storage/browser/file_system/file_system_context.h"
  19. #include "storage/browser/file_system/file_system_quota_client.h"
  20. #include "storage/browser/file_system/file_system_usage_cache.h"
  21. #include "storage/browser/file_system/file_system_util.h"
  22. #include "storage/browser/file_system/obfuscated_file_util.h"
  23. #include "storage/browser/quota/quota_manager.h"
  24. #include "storage/browser/quota/quota_manager_proxy.h"
  25. #include "storage/browser/test/async_file_test_helper.h"
  26. #include "storage/browser/test/mock_quota_manager.h"
  27. #include "storage/browser/test/mock_quota_manager_proxy.h"
  28. #include "storage/browser/test/mock_special_storage_policy.h"
  29. #include "storage/browser/test/test_file_system_context.h"
  30. #include "storage/common/file_system/file_system_types.h"
  31. #include "storage/common/file_system/file_system_util.h"
  32. #include "testing/gmock/include/gmock/gmock-matchers.h"
  33. #include "testing/gtest/include/gtest/gtest.h"
  34. #include "third_party/blink/public/common/features.h"
  35. #include "third_party/blink/public/common/storage_key/storage_key.h"
  36. #include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
  37. #include "url/gurl.h"
  38. #include "url/origin.h"
  39. using ::blink::StorageKey;
  40. using ::blink::mojom::StorageType;
  41. namespace storage {
  42. namespace {
  43. const char kDummyURL1[] = "http://www.dummy.org";
  44. const char kDummyURL2[] = "http://www.example.com";
  45. const char kDummyURL3[] = "http://www.bleh";
  46. // Declared to shorten the variable names.
  47. const StorageType kTemporary = StorageType::kTemporary;
  48. const StorageType kPersistent = StorageType::kPersistent;
  49. } // namespace
  50. class FileSystemQuotaClientTest : public testing::TestWithParam<bool> {
  51. public:
  52. FileSystemQuotaClientTest()
  53. : special_storage_policy_(
  54. base::MakeRefCounted<MockSpecialStoragePolicy>()),
  55. task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
  56. ~FileSystemQuotaClientTest() override = default;
  57. void SetUp() override {
  58. if (persistent_quota_is_temporary_quota()) {
  59. feature_list_.InitAndEnableFeature(
  60. blink::features::kPersistentQuotaIsTemporaryQuota);
  61. } else {
  62. feature_list_.InitAndDisableFeature(
  63. blink::features::kPersistentQuotaIsTemporaryQuota);
  64. }
  65. ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
  66. quota_manager_ = base::MakeRefCounted<MockQuotaManager>(
  67. /*is_incognito_=*/false, data_dir_.GetPath(),
  68. base::ThreadTaskRunnerHandle::Get(), special_storage_policy_);
  69. quota_manager_proxy_ = base::MakeRefCounted<storage::MockQuotaManagerProxy>(
  70. quota_manager_.get(), base::ThreadTaskRunnerHandle::Get());
  71. file_system_context_ = CreateFileSystemContextForTesting(
  72. quota_manager_proxy_, data_dir_.GetPath());
  73. }
  74. bool persistent_quota_is_temporary_quota() const { return GetParam(); }
  75. struct TestFile {
  76. bool isDirectory;
  77. const char* name;
  78. int64_t size;
  79. const char* origin_url;
  80. FileSystemType type;
  81. };
  82. storage::FileSystemContext* GetFileSystemContext() {
  83. return file_system_context_.get();
  84. }
  85. void GetBucketUsageAsync(storage::mojom::QuotaClient& quota_client,
  86. const BucketLocator& bucket) {
  87. quota_client.GetBucketUsage(
  88. bucket, base::BindOnce(&FileSystemQuotaClientTest::OnGetUsage,
  89. weak_factory_.GetWeakPtr()));
  90. }
  91. int64_t GetBucketUsage(storage::mojom::QuotaClient& quota_client,
  92. const BucketLocator& bucket) {
  93. GetBucketUsageAsync(quota_client, bucket);
  94. base::RunLoop().RunUntilIdle();
  95. return usage_;
  96. }
  97. const std::vector<StorageKey>& GetStorageKeysForType(
  98. storage::mojom::QuotaClient& quota_client,
  99. StorageType type) {
  100. storage_keys_.clear();
  101. quota_client.GetStorageKeysForType(
  102. type, base::BindOnce(&FileSystemQuotaClientTest::OnGetStorageKeys,
  103. weak_factory_.GetWeakPtr()));
  104. base::RunLoop().RunUntilIdle();
  105. return storage_keys_;
  106. }
  107. void RunAdditionalBucketUsageTask(storage::mojom::QuotaClient& quota_client,
  108. const BucketLocator& bucket) {
  109. quota_client.GetBucketUsage(
  110. bucket, base::BindOnce(&FileSystemQuotaClientTest::OnGetAdditionalUsage,
  111. weak_factory_.GetWeakPtr()));
  112. }
  113. bool CreateFileSystemDirectory(const base::FilePath& file_path,
  114. const std::string& origin_url,
  115. FileSystemType type) {
  116. FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
  117. blink::StorageKey::CreateFromStringForTesting(origin_url), type,
  118. file_path);
  119. base::File::Error result =
  120. AsyncFileTestHelper::CreateDirectory(file_system_context_.get(), url);
  121. return result == base::File::FILE_OK;
  122. }
  123. bool CreateFileSystemFile(const base::FilePath& file_path,
  124. int64_t file_size,
  125. const std::string& origin_url,
  126. FileSystemType type) {
  127. if (file_path.empty())
  128. return false;
  129. FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
  130. blink::StorageKey::CreateFromStringForTesting(origin_url), type,
  131. file_path);
  132. base::File::Error result =
  133. AsyncFileTestHelper::CreateFile(file_system_context_.get(), url);
  134. if (result != base::File::FILE_OK)
  135. return false;
  136. result = AsyncFileTestHelper::TruncateFile(file_system_context_.get(), url,
  137. file_size);
  138. return result == base::File::FILE_OK;
  139. }
  140. void InitializeOriginFiles(storage::mojom::QuotaClient& quota_client,
  141. const std::vector<TestFile>& files) {
  142. for (const TestFile& file : files) {
  143. base::FilePath path = base::FilePath().AppendASCII(file.name);
  144. if (file.isDirectory) {
  145. auto bucket =
  146. GetOrCreateBucket(file.origin_url, kDefaultBucketName,
  147. FileSystemTypeToQuotaStorageType(file.type));
  148. quota_manager_->SetQuota(bucket.storage_key, bucket.type,
  149. 1024 * 1024 * 100);
  150. ASSERT_TRUE(
  151. CreateFileSystemDirectory(path, file.origin_url, file.type));
  152. if (path.empty()) {
  153. // Create the usage cache.
  154. // HACK--we always create the root [an empty path] first. If we
  155. // create it later, this will fail due to a quota mismatch. If we
  156. // call this before we create the root, it succeeds, but hasn't
  157. // actually created the cache.
  158. GetBucketUsage(quota_client, bucket);
  159. }
  160. } else {
  161. ASSERT_TRUE(
  162. CreateFileSystemFile(path, file.size, file.origin_url, file.type));
  163. }
  164. }
  165. }
  166. // This is a bit fragile--it depends on the test data always creating a
  167. // directory before adding a file or directory to it, so that we can just
  168. // count the basename of each addition. A recursive creation of a path, which
  169. // created more than one directory in a single shot, would break this.
  170. int64_t ComputeFilePathsCostForOriginAndType(
  171. const base::span<const TestFile> files,
  172. const std::string& origin_url,
  173. FileSystemType type) {
  174. int64_t file_paths_cost = 0;
  175. for (const TestFile& file : files) {
  176. if (file.type == type && GURL(file.origin_url) == GURL(origin_url)) {
  177. base::FilePath path = base::FilePath().AppendASCII(file.name);
  178. if (!path.empty()) {
  179. file_paths_cost += ObfuscatedFileUtil::ComputeFilePathCost(path);
  180. }
  181. }
  182. }
  183. return file_paths_cost;
  184. }
  185. void DeleteBucketData(FileSystemQuotaClient* quota_client,
  186. const BucketLocator& bucket) {
  187. base::test::TestFuture<blink::mojom::QuotaStatusCode> future;
  188. quota_client->DeleteBucketData(bucket, future.GetCallback());
  189. ASSERT_EQ(future.Get(), blink::mojom::QuotaStatusCode::kOk);
  190. }
  191. BucketLocator GetOrCreateBucket(const std::string& origin,
  192. const std::string& name,
  193. StorageType type) {
  194. base::test::TestFuture<storage::QuotaErrorOr<storage::BucketInfo>> future;
  195. quota_manager_->GetOrCreateBucketDeprecated(
  196. {blink::StorageKey::CreateFromStringForTesting(origin), name}, type,
  197. future.GetCallback());
  198. auto bucket = future.Take();
  199. EXPECT_TRUE(bucket.ok());
  200. return bucket->ToBucketLocator();
  201. }
  202. BucketLocator GetBucket(const std::string& origin,
  203. const std::string& name,
  204. StorageType type) {
  205. base::test::TestFuture<storage::QuotaErrorOr<storage::BucketInfo>> future;
  206. quota_manager_->GetBucket(
  207. blink::StorageKey::CreateFromStringForTesting(origin), name, type,
  208. future.GetCallback());
  209. auto bucket = future.Take();
  210. EXPECT_TRUE(bucket.ok());
  211. return bucket->ToBucketLocator();
  212. }
  213. int64_t usage() const { return usage_; }
  214. int additional_callback_count() const { return additional_callback_count_; }
  215. void set_additional_callback_count(int count) {
  216. additional_callback_count_ = count;
  217. }
  218. private:
  219. void OnGetUsage(int64_t usage) { usage_ = usage; }
  220. void OnGetStorageKeys(const std::vector<StorageKey>& storage_keys) {
  221. storage_keys_ = storage_keys;
  222. }
  223. void OnGetAdditionalUsage(int64_t usage_unused) {
  224. ++additional_callback_count_;
  225. }
  226. protected:
  227. scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
  228. base::test::ScopedFeatureList feature_list_;
  229. base::ScopedTempDir data_dir_;
  230. base::test::TaskEnvironment task_environment_;
  231. scoped_refptr<FileSystemContext> file_system_context_;
  232. scoped_refptr<MockQuotaManager> quota_manager_;
  233. scoped_refptr<storage::MockQuotaManagerProxy> quota_manager_proxy_;
  234. int64_t usage_ = 0;
  235. int additional_callback_count_ = 0;
  236. std::vector<StorageKey> storage_keys_;
  237. base::WeakPtrFactory<FileSystemQuotaClientTest> weak_factory_{this};
  238. };
  239. TEST_P(FileSystemQuotaClientTest, NoFileSystemTest) {
  240. FileSystemQuotaClient quota_client(GetFileSystemContext());
  241. auto bucket = GetOrCreateBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  242. EXPECT_EQ(0, GetBucketUsage(quota_client, bucket));
  243. }
  244. TEST_P(FileSystemQuotaClientTest, NoFileTest) {
  245. FileSystemQuotaClient quota_client(GetFileSystemContext());
  246. InitializeOriginFiles(quota_client,
  247. {{true, "", 0, kDummyURL1, kFileSystemTypeTemporary}});
  248. auto bucket = GetOrCreateBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  249. for (int i = 0; i < 2; i++) {
  250. EXPECT_EQ(0, GetBucketUsage(quota_client, bucket));
  251. }
  252. }
  253. TEST_P(FileSystemQuotaClientTest, NonDefaultBucket) {
  254. FileSystemQuotaClient quota_client(GetFileSystemContext());
  255. auto bucket = GetOrCreateBucket(kDummyURL1, "logs_bucket", kTemporary);
  256. ASSERT_FALSE(bucket.is_default);
  257. EXPECT_EQ(0, GetBucketUsage(quota_client, bucket));
  258. DeleteBucketData(&quota_client, bucket);
  259. }
  260. TEST_P(FileSystemQuotaClientTest, OneFileTest) {
  261. FileSystemQuotaClient quota_client(GetFileSystemContext());
  262. const std::vector<TestFile> kFiles = {
  263. {true, "", 0, kDummyURL1, kFileSystemTypeTemporary},
  264. {false, "foo", 4921, kDummyURL1, kFileSystemTypeTemporary},
  265. };
  266. InitializeOriginFiles(quota_client, kFiles);
  267. const int64_t file_paths_cost = ComputeFilePathsCostForOriginAndType(
  268. kFiles, kDummyURL1, kFileSystemTypeTemporary);
  269. auto bucket = GetBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  270. for (int i = 0; i < 2; i++) {
  271. EXPECT_EQ(4921 + file_paths_cost, GetBucketUsage(quota_client, bucket));
  272. }
  273. }
  274. TEST_P(FileSystemQuotaClientTest, TwoFilesTest) {
  275. FileSystemQuotaClient quota_client(GetFileSystemContext());
  276. const std::vector<TestFile> kFiles = {
  277. {true, "", 0, kDummyURL1, kFileSystemTypeTemporary},
  278. {false, "foo", 10310, kDummyURL1, kFileSystemTypeTemporary},
  279. {false, "bar", 41, kDummyURL1, kFileSystemTypeTemporary},
  280. };
  281. InitializeOriginFiles(quota_client, kFiles);
  282. const int64_t file_paths_cost = ComputeFilePathsCostForOriginAndType(
  283. kFiles, kDummyURL1, kFileSystemTypeTemporary);
  284. auto bucket = GetBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  285. for (int i = 0; i < 2; i++) {
  286. EXPECT_EQ(10310 + 41 + file_paths_cost,
  287. GetBucketUsage(quota_client, bucket));
  288. }
  289. }
  290. TEST_P(FileSystemQuotaClientTest, EmptyFilesTest) {
  291. FileSystemQuotaClient quota_client(GetFileSystemContext());
  292. const std::vector<TestFile> kFiles = {
  293. {true, "", 0, kDummyURL1, kFileSystemTypeTemporary},
  294. {false, "foo", 0, kDummyURL1, kFileSystemTypeTemporary},
  295. {false, "bar", 0, kDummyURL1, kFileSystemTypeTemporary},
  296. {false, "baz", 0, kDummyURL1, kFileSystemTypeTemporary},
  297. };
  298. InitializeOriginFiles(quota_client, kFiles);
  299. const int64_t file_paths_cost = ComputeFilePathsCostForOriginAndType(
  300. kFiles, kDummyURL1, kFileSystemTypeTemporary);
  301. auto bucket = GetBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  302. for (int i = 0; i < 2; i++) {
  303. EXPECT_EQ(file_paths_cost, GetBucketUsage(quota_client, bucket));
  304. }
  305. }
  306. TEST_P(FileSystemQuotaClientTest, SubDirectoryTest) {
  307. FileSystemQuotaClient quota_client(GetFileSystemContext());
  308. const std::vector<TestFile> kFiles = {
  309. {true, "", 0, kDummyURL1, kFileSystemTypeTemporary},
  310. {true, "dirtest", 0, kDummyURL1, kFileSystemTypeTemporary},
  311. {false, "dirtest/foo", 11921, kDummyURL1, kFileSystemTypeTemporary},
  312. {false, "bar", 4814, kDummyURL1, kFileSystemTypeTemporary},
  313. };
  314. InitializeOriginFiles(quota_client, kFiles);
  315. const int64_t file_paths_cost = ComputeFilePathsCostForOriginAndType(
  316. kFiles, kDummyURL1, kFileSystemTypeTemporary);
  317. auto bucket = GetBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  318. for (int i = 0; i < 2; i++) {
  319. EXPECT_EQ(11921 + 4814 + file_paths_cost,
  320. GetBucketUsage(quota_client, bucket));
  321. }
  322. }
  323. TEST_P(FileSystemQuotaClientTest, MultiTypeTest) {
  324. FileSystemQuotaClient quota_client(GetFileSystemContext());
  325. const std::vector<TestFile> kFiles = {
  326. {true, "", 0, kDummyURL1, kFileSystemTypeTemporary},
  327. {true, "dirtest", 0, kDummyURL1, kFileSystemTypeTemporary},
  328. {false, "dirtest/foo", 133, kDummyURL1, kFileSystemTypeTemporary},
  329. {false, "bar", 14, kDummyURL1, kFileSystemTypeTemporary},
  330. {true, "", 0, kDummyURL1, kFileSystemTypePersistent},
  331. {true, "dirtest", 0, kDummyURL1, kFileSystemTypePersistent},
  332. {false, "dirtest/foo", 193, kDummyURL1, kFileSystemTypePersistent},
  333. {false, "bar", 9, kDummyURL1, kFileSystemTypePersistent},
  334. };
  335. InitializeOriginFiles(quota_client, kFiles);
  336. const int64_t file_paths_cost_temporary =
  337. ComputeFilePathsCostForOriginAndType(kFiles, kDummyURL1,
  338. kFileSystemTypeTemporary);
  339. const int64_t file_paths_cost_persistent =
  340. ComputeFilePathsCostForOriginAndType(kFiles, kDummyURL1,
  341. kFileSystemTypePersistent);
  342. for (int i = 0; i < 2; i++) {
  343. if (persistent_quota_is_temporary_quota()) {
  344. auto bucket = GetBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  345. EXPECT_EQ(133 + 14 + file_paths_cost_temporary + 193 + 9 +
  346. file_paths_cost_persistent,
  347. GetBucketUsage(quota_client, bucket));
  348. } else {
  349. auto bucket_temp = GetBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  350. auto bucket_perm = GetBucket(kDummyURL1, kDefaultBucketName, kPersistent);
  351. EXPECT_EQ(133 + 14 + file_paths_cost_temporary,
  352. GetBucketUsage(quota_client, bucket_temp));
  353. EXPECT_EQ(193 + 9 + file_paths_cost_persistent,
  354. GetBucketUsage(quota_client, bucket_perm));
  355. }
  356. }
  357. }
  358. TEST_P(FileSystemQuotaClientTest, MultiDomainTest) {
  359. FileSystemQuotaClient quota_client(GetFileSystemContext());
  360. const std::vector<TestFile> kFiles = {
  361. {true, "", 0, kDummyURL1, kFileSystemTypeTemporary},
  362. {true, "dir1", 0, kDummyURL1, kFileSystemTypeTemporary},
  363. {false, "dir1/foo", 1331, kDummyURL1, kFileSystemTypeTemporary},
  364. {false, "bar", 134, kDummyURL1, kFileSystemTypeTemporary},
  365. {true, "", 0, kDummyURL1, kFileSystemTypePersistent},
  366. {true, "dir2", 0, kDummyURL1, kFileSystemTypePersistent},
  367. {false, "dir2/foo", 1903, kDummyURL1, kFileSystemTypePersistent},
  368. {false, "bar", 19, kDummyURL1, kFileSystemTypePersistent},
  369. {true, "", 0, kDummyURL2, kFileSystemTypeTemporary},
  370. {true, "dom", 0, kDummyURL2, kFileSystemTypeTemporary},
  371. {false, "dom/fan", 1319, kDummyURL2, kFileSystemTypeTemporary},
  372. {false, "bar", 113, kDummyURL2, kFileSystemTypeTemporary},
  373. {true, "", 0, kDummyURL2, kFileSystemTypePersistent},
  374. {true, "dom", 0, kDummyURL2, kFileSystemTypePersistent},
  375. {false, "dom/fan", 2013, kDummyURL2, kFileSystemTypePersistent},
  376. {false, "baz", 18, kDummyURL2, kFileSystemTypePersistent},
  377. };
  378. InitializeOriginFiles(quota_client, kFiles);
  379. const int64_t file_paths_cost_temporary1 =
  380. ComputeFilePathsCostForOriginAndType(kFiles, kDummyURL1,
  381. kFileSystemTypeTemporary);
  382. const int64_t file_paths_cost_persistent1 =
  383. ComputeFilePathsCostForOriginAndType(kFiles, kDummyURL1,
  384. kFileSystemTypePersistent);
  385. const int64_t file_paths_cost_temporary2 =
  386. ComputeFilePathsCostForOriginAndType(kFiles, kDummyURL2,
  387. kFileSystemTypeTemporary);
  388. const int64_t file_paths_cost_persistent2 =
  389. ComputeFilePathsCostForOriginAndType(kFiles, kDummyURL2,
  390. kFileSystemTypePersistent);
  391. for (int i = 0; i < 2; i++) {
  392. if (persistent_quota_is_temporary_quota()) {
  393. auto bucket1 = GetBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  394. auto bucket2 = GetBucket(kDummyURL2, kDefaultBucketName, kTemporary);
  395. EXPECT_EQ(1331 + 134 + file_paths_cost_temporary1 + 1903 + 19 +
  396. file_paths_cost_persistent1,
  397. GetBucketUsage(quota_client, bucket1));
  398. EXPECT_EQ(1319 + 113 + file_paths_cost_temporary2 + 2013 + 18 +
  399. file_paths_cost_persistent2,
  400. GetBucketUsage(quota_client, bucket2));
  401. } else {
  402. auto bucket1_temp = GetBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  403. auto bucket1_perm =
  404. GetBucket(kDummyURL1, kDefaultBucketName, kPersistent);
  405. auto bucket2_temp = GetBucket(kDummyURL2, kDefaultBucketName, kTemporary);
  406. auto bucket2_perm =
  407. GetBucket(kDummyURL2, kDefaultBucketName, kPersistent);
  408. EXPECT_EQ(1331 + 134 + file_paths_cost_temporary1,
  409. GetBucketUsage(quota_client, bucket1_temp));
  410. EXPECT_EQ(1903 + 19 + file_paths_cost_persistent1,
  411. GetBucketUsage(quota_client, bucket1_perm));
  412. EXPECT_EQ(1319 + 113 + file_paths_cost_temporary2,
  413. GetBucketUsage(quota_client, bucket2_temp));
  414. EXPECT_EQ(2013 + 18 + file_paths_cost_persistent2,
  415. GetBucketUsage(quota_client, bucket2_perm));
  416. }
  417. }
  418. }
  419. TEST_P(FileSystemQuotaClientTest, GetUsage_MultipleTasks) {
  420. FileSystemQuotaClient quota_client(GetFileSystemContext());
  421. const std::vector<TestFile> kFiles = {
  422. {true, "", 0, kDummyURL1, kFileSystemTypeTemporary},
  423. {false, "foo", 11, kDummyURL1, kFileSystemTypeTemporary},
  424. {false, "bar", 22, kDummyURL1, kFileSystemTypeTemporary},
  425. };
  426. InitializeOriginFiles(quota_client, kFiles);
  427. const int64_t file_paths_cost = ComputeFilePathsCostForOriginAndType(
  428. kFiles, kDummyURL1, kFileSystemTypeTemporary);
  429. // Dispatching three GetUsage tasks.
  430. set_additional_callback_count(0);
  431. auto bucket = GetBucket(kDummyURL1, kDefaultBucketName, kTemporary);
  432. GetBucketUsageAsync(quota_client, bucket);
  433. RunAdditionalBucketUsageTask(quota_client, bucket);
  434. RunAdditionalBucketUsageTask(quota_client, bucket);
  435. base::RunLoop().RunUntilIdle();
  436. EXPECT_EQ(11 + 22 + file_paths_cost, usage());
  437. EXPECT_EQ(2, additional_callback_count());
  438. // Once more, in a different order.
  439. set_additional_callback_count(0);
  440. RunAdditionalBucketUsageTask(quota_client, bucket);
  441. GetBucketUsageAsync(quota_client, bucket);
  442. RunAdditionalBucketUsageTask(quota_client, bucket);
  443. base::RunLoop().RunUntilIdle();
  444. EXPECT_EQ(11 + 22 + file_paths_cost, usage());
  445. EXPECT_EQ(2, additional_callback_count());
  446. }
  447. TEST_P(FileSystemQuotaClientTest, GetStorageKeysForType) {
  448. FileSystemQuotaClient quota_client(GetFileSystemContext());
  449. InitializeOriginFiles(
  450. quota_client, {
  451. {true, "", 0, kDummyURL1, kFileSystemTypeTemporary},
  452. {true, "", 0, kDummyURL2, kFileSystemTypeTemporary},
  453. {true, "", 0, kDummyURL3, kFileSystemTypePersistent},
  454. });
  455. if (persistent_quota_is_temporary_quota()) {
  456. EXPECT_THAT(GetStorageKeysForType(quota_client, kTemporary),
  457. testing::UnorderedElementsAre(
  458. StorageKey::CreateFromStringForTesting(kDummyURL1),
  459. StorageKey::CreateFromStringForTesting(kDummyURL2),
  460. StorageKey::CreateFromStringForTesting(kDummyURL3)));
  461. } else {
  462. EXPECT_THAT(GetStorageKeysForType(quota_client, kTemporary),
  463. testing::UnorderedElementsAre(
  464. StorageKey::CreateFromStringForTesting(kDummyURL1),
  465. StorageKey::CreateFromStringForTesting(kDummyURL2)));
  466. }
  467. }
  468. TEST_P(FileSystemQuotaClientTest, DeleteOriginTest) {
  469. FileSystemQuotaClient quota_client(GetFileSystemContext());
  470. const std::vector<TestFile> kFiles = {
  471. {true, "", 0, "http://foo.com/", kFileSystemTypeTemporary},
  472. {false, "a", 1, "http://foo.com/", kFileSystemTypeTemporary},
  473. {true, "", 0, "https://foo.com/", kFileSystemTypeTemporary},
  474. {false, "b", 2, "https://foo.com/", kFileSystemTypeTemporary},
  475. {true, "", 0, "http://foo.com/", kFileSystemTypePersistent},
  476. {false, "c", 4, "http://foo.com/", kFileSystemTypePersistent},
  477. {true, "", 0, "http://bar.com/", kFileSystemTypeTemporary},
  478. {false, "d", 8, "http://bar.com/", kFileSystemTypeTemporary},
  479. {true, "", 0, "http://bar.com/", kFileSystemTypePersistent},
  480. {false, "e", 16, "http://bar.com/", kFileSystemTypePersistent},
  481. {true, "", 0, "https://bar.com/", kFileSystemTypePersistent},
  482. {false, "f", 32, "https://bar.com/", kFileSystemTypePersistent},
  483. {true, "", 0, "https://bar.com/", kFileSystemTypeTemporary},
  484. {false, "g", 64, "https://bar.com/", kFileSystemTypeTemporary},
  485. };
  486. InitializeOriginFiles(quota_client, kFiles);
  487. const int64_t file_paths_cost_temporary_foo_https =
  488. ComputeFilePathsCostForOriginAndType(kFiles, "https://foo.com/",
  489. kFileSystemTypeTemporary);
  490. const int64_t file_paths_cost_temporary_bar =
  491. ComputeFilePathsCostForOriginAndType(kFiles, "http://bar.com/",
  492. kFileSystemTypeTemporary);
  493. const int64_t file_paths_cost_persistent_bar =
  494. ComputeFilePathsCostForOriginAndType(kFiles, "http://bar.com/",
  495. kFileSystemTypePersistent);
  496. const int64_t file_paths_cost_temporary_bar_https =
  497. ComputeFilePathsCostForOriginAndType(kFiles, "https://bar.com/",
  498. kFileSystemTypeTemporary);
  499. const int64_t file_paths_cost_persistent_bar_https =
  500. ComputeFilePathsCostForOriginAndType(kFiles, "https://bar.com/",
  501. kFileSystemTypePersistent);
  502. auto foo_temp_bucket =
  503. GetBucket("http://foo.com/", kDefaultBucketName, kTemporary);
  504. DeleteBucketData(&quota_client, foo_temp_bucket);
  505. if (!persistent_quota_is_temporary_quota()) {
  506. auto foo_perm_bucket =
  507. GetBucket("http://bar.com/", kDefaultBucketName, kPersistent);
  508. DeleteBucketData(&quota_client, foo_perm_bucket);
  509. }
  510. auto buz_temp_bucket =
  511. GetOrCreateBucket("http://buz.com/", kDefaultBucketName, kTemporary);
  512. DeleteBucketData(&quota_client, buz_temp_bucket);
  513. EXPECT_EQ(0, GetBucketUsage(quota_client, foo_temp_bucket));
  514. EXPECT_EQ(0, GetBucketUsage(quota_client, buz_temp_bucket));
  515. auto foo_https_temp_bucket =
  516. GetBucket("https://foo.com/", kDefaultBucketName, kTemporary);
  517. EXPECT_EQ(2 + file_paths_cost_temporary_foo_https,
  518. GetBucketUsage(quota_client, foo_https_temp_bucket));
  519. auto bar_temp_bucket =
  520. GetBucket("http://bar.com/", kDefaultBucketName, kTemporary);
  521. EXPECT_EQ(8 + file_paths_cost_temporary_bar +
  522. (persistent_quota_is_temporary_quota()
  523. ? 16 + file_paths_cost_persistent_bar
  524. : 0),
  525. GetBucketUsage(quota_client, bar_temp_bucket));
  526. auto bar_https_temp_bucket =
  527. GetBucket("https://bar.com/", kDefaultBucketName, kTemporary);
  528. EXPECT_EQ(64 + file_paths_cost_temporary_bar_https +
  529. (persistent_quota_is_temporary_quota()
  530. ? 32 + file_paths_cost_persistent_bar_https
  531. : 0),
  532. GetBucketUsage(quota_client, bar_https_temp_bucket));
  533. }
  534. INSTANTIATE_TEST_SUITE_P(FileSystemQuotaClientTests,
  535. FileSystemQuotaClientTest,
  536. testing::Bool());
  537. } // namespace storage