1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "storage/browser/file_system/obfuscated_file_util.h"
- #include <stddef.h>
- #include <stdint.h>
- #include <limits>
- #include <memory>
- #include <set>
- #include <string>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/files/file.h"
- #include "base/files/file_path.h"
- #include "base/files/file_util.h"
- #include "base/files/scoped_temp_dir.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/run_loop.h"
- #include "base/task/thread_pool.h"
- #include "base/test/bind.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/task_environment.h"
- #include "base/test/test_future.h"
- #include "base/threading/thread_restrictions.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "build/build_config.h"
- #include "components/services/filesystem/public/mojom/types.mojom.h"
- #include "net/base/features.h"
- #include "net/base/io_buffer.h"
- #include "storage/browser/file_system/external_mount_points.h"
- #include "storage/browser/file_system/file_system_backend.h"
- #include "storage/browser/file_system/file_system_context.h"
- #include "storage/browser/file_system/file_system_operation_context.h"
- #include "storage/browser/file_system/file_system_url.h"
- #include "storage/browser/file_system/file_system_usage_cache.h"
- #include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h"
- #include "storage/browser/file_system/sandbox_directory_database.h"
- #include "storage/browser/file_system/sandbox_file_system_backend_delegate.h"
- #include "storage/browser/file_system/sandbox_origin_database.h"
- #include "storage/browser/quota/quota_manager.h"
- #include "storage/browser/quota/quota_manager_proxy.h"
- #include "storage/browser/test/async_file_test_helper.h"
- #include "storage/browser/test/file_system_test_file_set.h"
- #include "storage/browser/test/mock_file_change_observer.h"
- #include "storage/browser/test/mock_special_storage_policy.h"
- #include "storage/browser/test/sandbox_file_system_test_helper.h"
- #include "storage/browser/test/test_file_system_context.h"
- #include "storage/common/database/database_identifier.h"
- #include "storage/common/file_system/file_system_types.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/blink/public/common/storage_key/storage_key.h"
- #include "third_party/leveldatabase/leveldb_chrome.h"
- #include "url/gurl.h"
- using url::Origin;
- namespace storage {
- namespace {
- enum TestMode {
- kRegularFirstParty,
- kRegularFirstPartyNonDefaultBucket,
- kRegularThirdParty,
- kRegularThirdPartyNonDefaultBucket,
- kIncognitoFirstParty,
- kIncognitoFirstPartyNonDefaultBucket,
- kIncognitoThirdParty,
- kIncognitoThirdPartyNonDefaultBucket
- };
- bool FileExists(const base::FilePath& path) {
- return base::PathExists(path) && !base::DirectoryExists(path);
- }
- int64_t GetLocalFileSize(const base::FilePath& path) {
- int64_t size;
- EXPECT_TRUE(base::GetFileSize(path, &size));
- return size;
- }
- // After a move, the dest exists and the source doesn't.
- // After a copy, both source and dest exist.
- struct CopyMoveTestCaseRecord {
- bool is_copy_not_move;
- const char source_path[64];
- const char dest_path[64];
- bool cause_overwrite;
- };
- const CopyMoveTestCaseRecord kCopyMoveTestCases[] = {
- // This is the combinatoric set of:
- // rename vs. same-name
- // different directory vs. same directory
- // overwrite vs. no-overwrite
- // copy vs. move
- // We can never be called with source and destination paths identical, so
- // those cases are omitted.
- {true, "dir0/file0", "dir0/file1", false},
- {false, "dir0/file0", "dir0/file1", false},
- {true, "dir0/file0", "dir0/file1", true},
- {false, "dir0/file0", "dir0/file1", true},
- {true, "dir0/file0", "dir1/file0", false},
- {false, "dir0/file0", "dir1/file0", false},
- {true, "dir0/file0", "dir1/file0", true},
- {false, "dir0/file0", "dir1/file0", true},
- {true, "dir0/file0", "dir1/file1", false},
- {false, "dir0/file0", "dir1/file1", false},
- {true, "dir0/file0", "dir1/file1", true},
- {false, "dir0/file0", "dir1/file1", true},
- };
- struct OriginEnumerationTestRecord {
- std::string origin_url;
- bool has_temporary;
- bool has_persistent;
- };
- const OriginEnumerationTestRecord kOriginEnumerationTestRecords[] = {
- {"http://example.com/", false, true},
- {"http://example1.com/", true, false},
- {"https://example1.com/", true, true},
- {"file:///", false, true},
- {"http://example.com:8000/", false, true},
- };
- FileSystemURL FileSystemURLAppend(const FileSystemURL& url,
- const base::FilePath::StringType& child) {
- FileSystemURL new_url = FileSystemURL::CreateForTest(
- url.storage_key(), url.mount_type(), url.virtual_path().Append(child));
- if (url.bucket().has_value())
- new_url.SetBucket(url.bucket().value());
- return new_url;
- }
- FileSystemURL FileSystemURLAppendUTF8(const FileSystemURL& url,
- const std::string& child) {
- FileSystemURL new_url = FileSystemURL::CreateForTest(
- url.storage_key(), url.mount_type(),
- url.virtual_path().Append(base::FilePath::FromUTF8Unsafe(child)));
- if (url.bucket().has_value())
- new_url.SetBucket(url.bucket().value());
- return new_url;
- }
- FileSystemURL FileSystemURLDirName(const FileSystemURL& url) {
- FileSystemURL new_url =
- FileSystemURL::CreateForTest(url.storage_key(), url.mount_type(),
- VirtualPath::DirName(url.virtual_path()));
- if (url.bucket().has_value())
- new_url.SetBucket(url.bucket().value());
- return new_url;
- }
- std::string GetTypeString(FileSystemType type) {
- return SandboxFileSystemBackendDelegate::GetTypeString(type);
- }
- bool HasFileSystemType(
- ObfuscatedFileUtil::AbstractStorageKeyEnumerator* enumerator,
- FileSystemType type) {
- return enumerator->HasTypeDirectory(GetTypeString(type));
- }
- } // namespace
- // TODO(ericu): The vast majority of this and the other FSFU subclass tests
- // could theoretically be shared. It would basically be a FSFU interface
- // compliance test, and only the subclass-specific bits that look into the
- // implementation would need to be written per-subclass.
- class ObfuscatedFileUtilTest : public testing::Test,
- public ::testing::WithParamInterface<TestMode> {
- public:
- ObfuscatedFileUtilTest()
- : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
- storage_key_(blink::StorageKey::CreateFromStringForTesting(
- "http://www.example.com")),
- type_(kFileSystemTypeTemporary),
- sandbox_file_system_(storage_key_, type_),
- quota_status_(blink::mojom::QuotaStatusCode::kUnknown),
- usage_(-1) {
- if (is_third_party_context()) {
- scoped_feature_list_.InitAndEnableFeature(
- net::features::kThirdPartyStoragePartitioning);
- // Once we enable third-party storage partitioning, we can create a
- // third-party StorageKey and re-assign the StorageKey value in the
- // SandboxFileSystem with this value in SetUp for default buckets.
- storage_key_ = blink::StorageKey::CreateWithOptionalNonce(
- storage_key_.origin(), storage_key_.top_level_site(), nullptr,
- blink::mojom::AncestorChainBit::kCrossSite);
- }
- }
- ObfuscatedFileUtilTest(const ObfuscatedFileUtilTest&) = delete;
- ObfuscatedFileUtilTest& operator=(const ObfuscatedFileUtilTest&) = delete;
- ~ObfuscatedFileUtilTest() override = default;
- bool is_incognito() {
- return GetParam() == TestMode::kIncognitoFirstParty ||
- (GetParam() == TestMode::kIncognitoFirstPartyNonDefaultBucket) ||
- (GetParam() == TestMode::kIncognitoThirdParty) ||
- (GetParam() == TestMode::kIncognitoThirdPartyNonDefaultBucket);
- }
- bool is_third_party_context() {
- return GetParam() == TestMode::kRegularThirdParty ||
- (GetParam() == TestMode::kRegularThirdPartyNonDefaultBucket) ||
- (GetParam() == TestMode::kIncognitoThirdParty) ||
- (GetParam() == TestMode::kIncognitoThirdPartyNonDefaultBucket);
- }
- bool is_non_default_bucket() {
- return GetParam() == TestMode::kRegularFirstPartyNonDefaultBucket ||
- (GetParam() == TestMode::kRegularThirdPartyNonDefaultBucket) ||
- (GetParam() == TestMode::kIncognitoFirstPartyNonDefaultBucket) ||
- (GetParam() == TestMode::kIncognitoThirdPartyNonDefaultBucket);
- }
- void SetUp() override {
- ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
- storage_policy_ = base::MakeRefCounted<MockSpecialStoragePolicy>();
- quota_manager_task_runner_ =
- base::ThreadPool::CreateSingleThreadTaskRunner({base::MayBlock()});
- quota_manager_ = base::MakeRefCounted<QuotaManager>(
- is_incognito(), data_dir_.GetPath(), quota_manager_task_runner_,
- /*quota_change_callback=*/base::DoNothing(), storage_policy_,
- GetQuotaSettingsFunc());
- quota_manager_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(
- [](const scoped_refptr<QuotaManager>& quota_manager) {
- QuotaSettings settings;
- settings.per_host_quota = 25 * 1024 * 1024;
- settings.pool_size = settings.per_host_quota * 5;
- settings.must_remain_available = 10 * 1024 * 1024;
- settings.refresh_interval = base::TimeDelta::Max();
- quota_manager->SetQuotaSettings(settings);
- },
- quota_manager_));
- // Every time we create a new sandbox_file_system helper,
- // it creates another context, which creates another path manager,
- // another sandbox_backend, and another OFU.
- // We need to pass in the context to skip all that.
- file_system_context_ =
- is_incognito() ? CreateIncognitoFileSystemContextForTesting(
- base::ThreadTaskRunnerHandle::Get(),
- base::ThreadTaskRunnerHandle::Get(),
- quota_manager_->proxy(), data_dir_.GetPath())
- : CreateFileSystemContextForTesting(
- quota_manager_->proxy(), data_dir_.GetPath());
- // Create the default bucket member corresponding to the StorageKey member
- // we created.
- base::test::TestFuture<QuotaErrorOr<BucketInfo>> default_future;
- quota_manager_->proxy()->UpdateOrCreateBucket(
- BucketInitParams::ForDefaultBucket(storage_key()),
- base::SequencedTaskRunnerHandle::Get(), default_future.GetCallback());
- QuotaErrorOr<BucketInfo> default_bucket = default_future.Take();
- CHECK(default_bucket.ok());
- default_bucket_ = default_bucket.value().ToBucketLocator();
- // Create a non-default bucket member corresponding to the StorageKey
- // member we created.
- base::test::TestFuture<QuotaErrorOr<BucketInfo>> custom_future;
- BucketInitParams params = BucketInitParams::ForDefaultBucket(storage_key());
- params.name = "non-default bucket";
- quota_manager_->proxy()->UpdateOrCreateBucket(
- params, base::SequencedTaskRunnerHandle::Get(),
- custom_future.GetCallback());
- QuotaErrorOr<BucketInfo> custom_bucket = custom_future.Take();
- CHECK(custom_bucket.ok());
- custom_bucket_ = custom_bucket.value().ToBucketLocator();
- // Create an alternate non-default bucket member corresponding to the
- // StorageKey member we created.
- base::test::TestFuture<QuotaErrorOr<BucketInfo>> alternate_future;
- params.name = "alternate non-default bucket";
- quota_manager_->proxy()->UpdateOrCreateBucket(
- params, base::SequencedTaskRunnerHandle::Get(),
- alternate_future.GetCallback());
- QuotaErrorOr<BucketInfo> alternate_bucket = alternate_future.Take();
- CHECK(alternate_bucket.ok());
- alternate_custom_bucket_ = alternate_bucket.value().ToBucketLocator();
- is_non_default_bucket()
- ? sandbox_file_system_.SetUp(file_system_context_, custom_bucket_)
- : sandbox_file_system_.SetUp(file_system_context_, storage_key_);
- change_observers_ = MockFileChangeObserver::CreateList(&change_observer_);
- if (is_incognito())
- incognito_leveldb_environment_ = leveldb_chrome::NewMemEnv("FileSystem");
- }
- void TearDown() override {
- if (is_incognito())
- ASSERT_TRUE(IsDirectoryEmpty(data_dir_.GetPath()));
- quota_manager_ = nullptr;
- task_environment_.RunUntilIdle();
- sandbox_file_system_.TearDown();
- }
- std::unique_ptr<FileSystemOperationContext> LimitedContext(
- int64_t allowed_bytes_growth) {
- std::unique_ptr<FileSystemOperationContext> context(
- sandbox_file_system_.NewOperationContext());
- context->set_allowed_bytes_growth(allowed_bytes_growth);
- return context;
- }
- std::unique_ptr<FileSystemOperationContext> UnlimitedContext() {
- return LimitedContext(std::numeric_limits<int64_t>::max());
- }
- std::unique_ptr<FileSystemOperationContext> NewContext(
- SandboxFileSystemTestHelper* file_system) {
- change_observer()->ResetCount();
- std::unique_ptr<FileSystemOperationContext> context;
- if (file_system)
- context = file_system->NewOperationContext();
- else
- context = sandbox_file_system_.NewOperationContext();
- // Setting allowed_bytes_growth big enough for all tests.
- context->set_allowed_bytes_growth(1024 * 1024);
- context->set_change_observers(change_observers());
- return context;
- }
- const ChangeObserverList& change_observers() const {
- return change_observers_;
- }
- MockFileChangeObserver* change_observer() { return &change_observer_; }
- // This can only be used after SetUp has run and created file_system_context_
- // and obfuscated_file_util_.
- // Use this for tests which need to run in multiple StorageKeys; we need a
- // test helper per StorageKey.
- std::unique_ptr<SandboxFileSystemTestHelper> NewFileSystem(
- const blink::StorageKey& storage_key,
- FileSystemType type) {
- auto file_system =
- std::make_unique<SandboxFileSystemTestHelper>(storage_key, type);
- file_system->SetUp(file_system_context_);
- return file_system;
- }
- // This can only be used after SetUp has run and created file_system_context_
- // and obfuscated_file_util_.
- // Use this for tests which need to run in multiple BucketLocators; we need a
- // test helper per BucketLocator.
- std::unique_ptr<SandboxFileSystemTestHelper> NewFileSystem(
- const BucketLocator& bucket_locator,
- FileSystemType type) {
- auto file_system = std::make_unique<SandboxFileSystemTestHelper>(
- bucket_locator.storage_key, type);
- file_system->SetUp(file_system_context_, bucket_locator);
- return file_system;
- }
- std::unique_ptr<ObfuscatedFileUtil> CreateObfuscatedFileUtil(
- scoped_refptr<SpecialStoragePolicy> storage_policy) {
- return ObfuscatedFileUtil::CreateForTesting(
- std::move(storage_policy), data_dir_path(),
- is_incognito() ? incognito_leveldb_environment_.get() : nullptr,
- is_incognito());
- }
- ObfuscatedFileUtil* ofu() {
- return static_cast<ObfuscatedFileUtil*>(sandbox_file_system_.file_util());
- }
- const base::FilePath& test_directory() const { return data_dir_.GetPath(); }
- const blink::StorageKey& storage_key() const { return storage_key_; }
- const Origin& origin() const { return storage_key_.origin(); }
- FileSystemType type() const { return type_; }
- std::string type_string() const { return GetTypeString(type_); }
- int64_t ComputeTotalFileSize() {
- return sandbox_file_system_.ComputeCurrentStorageKeyUsage() -
- sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage();
- }
- void GetUsageFromQuotaManager() {
- int64_t quota = -1;
- quota_status_ = AsyncFileTestHelper::GetUsageAndQuota(
- quota_manager_->proxy(), storage_key(), sandbox_file_system_.type(),
- &usage_, "a);
- EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, quota_status_);
- }
- void RevokeUsageCache() {
- quota_manager_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(
- [](const scoped_refptr<QuotaManager>& quota_manager,
- SandboxFileSystemTestHelper* sandbox_file_system) {
- quota_manager->ResetUsageTracker(
- sandbox_file_system->storage_type());
- },
- quota_manager_, &sandbox_file_system_));
- base::FileErrorOr<base::FilePath> path =
- sandbox_file_system_.GetUsageCachePath();
- if (!path.is_error())
- usage_cache()->Delete(path.value());
- }
- int64_t SizeByQuotaUtil() { return sandbox_file_system_.GetCachedUsage(); }
- int64_t SizeInUsageFile() {
- task_environment_.RunUntilIdle();
- int64_t usage = 0;
- base::FileErrorOr<base::FilePath> path =
- sandbox_file_system_.GetUsageCachePath();
- if (path.is_error())
- return -1;
- return usage_cache()->GetUsage(path.value(), &usage) ? usage : -1;
- }
- bool PathExists(const FileSystemURL& url) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- base::File::Info file_info;
- base::FilePath platform_path;
- base::File::Error error =
- ofu()->GetFileInfo(context.get(), url, &file_info, &platform_path);
- return error == base::File::FILE_OK;
- }
- int64_t GetPathSize(const FileSystemURL& url) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- base::File::Info file_info;
- base::FilePath platform_path;
- EXPECT_EQ(
- base::File::FILE_OK,
- ofu()->GetFileInfo(context.get(), url, &file_info, &platform_path));
- return file_info.size;
- }
- bool DirectoryExists(const FileSystemURL& url) {
- return AsyncFileTestHelper::DirectoryExists(file_system_context(), url);
- }
- int64_t usage() const { return usage_; }
- FileSystemUsageCache* usage_cache() {
- return sandbox_file_system_.usage_cache();
- }
- FileSystemURL CreateURL(const base::FilePath& path) {
- FileSystemURL test_url = sandbox_file_system_.CreateURL(path);
- if (is_non_default_bucket())
- test_url.SetBucket(custom_bucket_);
- return test_url;
- }
- FileSystemURL CreateURLFromUTF8(const std::string& path) {
- FileSystemURL test_url = sandbox_file_system_.CreateURLFromUTF8(path);
- if (is_non_default_bucket())
- test_url.SetBucket(custom_bucket_);
- return test_url;
- }
- int64_t PathCost(const FileSystemURL& url) {
- return ObfuscatedFileUtil::ComputeFilePathCost(url.path());
- }
- void CheckFile(const FileSystemURL& url) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- base::FilePath local_path;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetLocalFilePath(context.get(), url, &local_path));
- EXPECT_EQ(0, GetPathSize(url));
- base::File::Info file_info0;
- base::FilePath data_path;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetFileInfo(context.get(), url, &file_info0, &data_path));
- EXPECT_EQ(data_path, local_path);
- EXPECT_EQ(!is_incognito(), FileExists(data_path));
- const char data[] = "test data";
- const int length = std::size(data) - 1;
- base::File file = ofu()->CreateOrOpen(
- context.get(), url, base::File::FLAG_WRITE | base::File::FLAG_OPEN);
- if (is_incognito()) {
- ASSERT_FALSE(file.IsValid());
- auto* memory_delegate =
- static_cast<ObfuscatedFileUtilMemoryDelegate*>(ofu()->delegate());
- ASSERT_EQ(
- length,
- memory_delegate->WriteFile(
- local_path, 0,
- base::MakeRefCounted<net::StringIOBuffer>(data).get(), length));
- } else {
- ASSERT_TRUE(file.IsValid());
- ASSERT_EQ(length, file.Write(0, data, length));
- file.Close();
- }
- base::File::Info file_info1;
- if (!is_incognito())
- EXPECT_EQ(length, GetLocalFileSize(data_path));
- EXPECT_EQ(length, GetPathSize(url));
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetFileInfo(context.get(), url, &file_info1, &data_path));
- EXPECT_EQ(data_path, local_path);
- EXPECT_FALSE(file_info0.is_directory);
- EXPECT_FALSE(file_info1.is_directory);
- EXPECT_FALSE(file_info0.is_symbolic_link);
- EXPECT_FALSE(file_info1.is_symbolic_link);
- EXPECT_EQ(0, file_info0.size);
- EXPECT_EQ(length, file_info1.size);
- EXPECT_LE(file_info0.last_modified, file_info1.last_modified);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->Truncate(context.get(), url, length * 2));
- EXPECT_EQ(length * 2, GetPathSize(url));
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK, ofu()->Truncate(context.get(), url, 0));
- EXPECT_EQ(0, GetPathSize(url));
- }
- void ValidateTestDirectory(
- const FileSystemURL& root_url,
- const std::set<base::FilePath::StringType>& files,
- const std::set<base::FilePath::StringType>& directories) {
- std::unique_ptr<FileSystemOperationContext> context;
- for (const auto& file : files) {
- bool created = true;
- context = NewContext(nullptr);
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->EnsureFileExists(
- context.get(), FileSystemURLAppend(root_url, file), &created));
- ASSERT_FALSE(created);
- }
- for (const auto& directory : directories) {
- context = NewContext(nullptr);
- EXPECT_TRUE(DirectoryExists(FileSystemURLAppend(root_url, directory)));
- }
- }
- class UsageVerifyHelper {
- public:
- UsageVerifyHelper(std::unique_ptr<FileSystemOperationContext> context,
- SandboxFileSystemTestHelper* file_system,
- int64_t expected_usage,
- ObfuscatedFileUtilTest* test)
- : context_(std::move(context)),
- sandbox_file_system_(file_system),
- expected_usage_(expected_usage),
- test_(test) {}
- ~UsageVerifyHelper() {
- test_->task_environment_.RunUntilIdle();
- Check();
- }
- FileSystemOperationContext* context() { return context_.get(); }
- private:
- void Check() {
- ASSERT_EQ(expected_usage_, sandbox_file_system_->GetCachedUsage());
- }
- std::unique_ptr<FileSystemOperationContext> context_;
- raw_ptr<SandboxFileSystemTestHelper> sandbox_file_system_;
- int64_t expected_usage_;
- const raw_ptr<ObfuscatedFileUtilTest> test_;
- };
- std::unique_ptr<UsageVerifyHelper> AllowUsageIncrease(
- int64_t requested_growth) {
- int64_t usage = sandbox_file_system_.GetCachedUsage();
- return std::make_unique<UsageVerifyHelper>(LimitedContext(requested_growth),
- &sandbox_file_system_,
- usage + requested_growth, this);
- }
- std::unique_ptr<UsageVerifyHelper> DisallowUsageIncrease(
- int64_t requested_growth) {
- int64_t usage = sandbox_file_system_.GetCachedUsage();
- return std::make_unique<UsageVerifyHelper>(
- LimitedContext(requested_growth - 1), &sandbox_file_system_, usage,
- this);
- }
- void FillTestDirectory(const FileSystemURL& root_url,
- std::set<base::FilePath::StringType>* files,
- std::set<base::FilePath::StringType>* directories) {
- std::unique_ptr<FileSystemOperationContext> context;
- std::vector<filesystem::mojom::DirectoryEntry> entries;
- EXPECT_EQ(base::File::FILE_OK,
- AsyncFileTestHelper::ReadDirectory(file_system_context(),
- root_url, &entries));
- EXPECT_EQ(0UL, entries.size());
- files->clear();
- files->insert(FILE_PATH_LITERAL("first"));
- files->insert(FILE_PATH_LITERAL("second"));
- files->insert(FILE_PATH_LITERAL("third"));
- directories->clear();
- directories->insert(FILE_PATH_LITERAL("fourth"));
- directories->insert(FILE_PATH_LITERAL("fifth"));
- directories->insert(FILE_PATH_LITERAL("sixth"));
- for (const auto& file : *files) {
- bool created = false;
- context = NewContext(nullptr);
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->EnsureFileExists(
- context.get(), FileSystemURLAppend(root_url, file), &created));
- ASSERT_TRUE(created);
- }
- for (const auto& directory : *directories) {
- bool exclusive = true;
- bool recursive = false;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(),
- FileSystemURLAppend(root_url, directory),
- exclusive, recursive));
- }
- ValidateTestDirectory(root_url, *files, *directories);
- }
- void TestReadDirectoryHelper(const FileSystemURL& root_url) {
- std::set<base::FilePath::StringType> files;
- std::set<base::FilePath::StringType> directories;
- FillTestDirectory(root_url, &files, &directories);
- std::unique_ptr<FileSystemOperationContext> context;
- std::vector<filesystem::mojom::DirectoryEntry> entries;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- AsyncFileTestHelper::ReadDirectory(file_system_context(),
- root_url, &entries));
- EXPECT_EQ(files.size() + directories.size(), entries.size());
- EXPECT_TRUE(change_observer()->HasNoChange());
- for (const filesystem::mojom::DirectoryEntry& entry : entries) {
- auto iter = files.find(entry.name.value());
- if (iter != files.end()) {
- EXPECT_EQ(entry.type, filesystem::mojom::FsFileType::REGULAR_FILE);
- files.erase(iter);
- continue;
- }
- iter = directories.find(entry.name.value());
- EXPECT_FALSE(directories.end() == iter);
- EXPECT_EQ(entry.type, filesystem::mojom::FsFileType::DIRECTORY);
- directories.erase(iter);
- }
- }
- void TestTouchHelper(const FileSystemURL& url, bool is_file) {
- base::Time last_access_time = base::Time::Now();
- base::Time last_modified_time = base::Time::Now();
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- EXPECT_EQ(
- base::File::FILE_OK,
- ofu()->Touch(context.get(), url, last_access_time, last_modified_time));
- // Currently we fire no change notifications for Touch.
- EXPECT_TRUE(change_observer()->HasNoChange());
- base::FilePath local_path;
- base::File::Info file_info;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetFileInfo(context.get(), url, &file_info, &local_path));
- // We compare as time_t here to lower our resolution, to avoid false
- // negatives caused by conversion to the local filesystem's native
- // representation and back.
- EXPECT_EQ(file_info.last_modified.ToTimeT(), last_modified_time.ToTimeT());
- context = NewContext(nullptr);
- last_modified_time += base::Hours(1);
- last_access_time += base::Hours(14);
- EXPECT_EQ(
- base::File::FILE_OK,
- ofu()->Touch(context.get(), url, last_access_time, last_modified_time));
- EXPECT_TRUE(change_observer()->HasNoChange());
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetFileInfo(context.get(), url, &file_info, &local_path));
- EXPECT_EQ(file_info.last_modified.ToTimeT(), last_modified_time.ToTimeT());
- if (is_file) // Directories in OFU don't support atime.
- EXPECT_EQ(file_info.last_accessed.ToTimeT(), last_access_time.ToTimeT());
- }
- void TestCopyInForeignFileHelper(bool overwrite) {
- base::ScopedTempDir source_dir;
- ASSERT_TRUE(source_dir.CreateUniqueTempDir());
- base::FilePath root_file_path = source_dir.GetPath();
- base::FilePath src_file_path = root_file_path.AppendASCII("file_name");
- FileSystemURL dest_url = CreateURLFromUTF8("new file");
- int64_t src_file_length = 87;
- base::File file(src_file_path,
- base::File::FLAG_CREATE | base::File::FLAG_WRITE);
- ASSERT_TRUE(file.IsValid());
- EXPECT_TRUE(file.created());
- ASSERT_TRUE(file.SetLength(src_file_length));
- file.Close();
- std::unique_ptr<FileSystemOperationContext> context;
- if (overwrite) {
- context = NewContext(nullptr);
- bool created = false;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), dest_url, &created));
- EXPECT_TRUE(created);
- // We must have observed one (and only one) create_file_count.
- EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
- EXPECT_TRUE(change_observer()->HasNoChange());
- }
- const int64_t path_cost =
- ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path());
- if (!overwrite) {
- // Verify that file creation requires sufficient quota for the path.
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(path_cost + src_file_length - 1);
- EXPECT_EQ(
- base::File::FILE_ERROR_NO_SPACE,
- ofu()->CopyInForeignFile(context.get(), src_file_path, dest_url));
- }
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(path_cost + src_file_length);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CopyInForeignFile(context.get(), src_file_path, dest_url));
- EXPECT_TRUE(PathExists(dest_url));
- EXPECT_FALSE(DirectoryExists(dest_url));
- context = NewContext(nullptr);
- base::File::Info file_info;
- base::FilePath data_path;
- EXPECT_EQ(base::File::FILE_OK, ofu()->GetFileInfo(context.get(), dest_url,
- &file_info, &data_path));
- EXPECT_NE(data_path, src_file_path);
- EXPECT_TRUE(PathExists(dest_url));
- EXPECT_EQ(src_file_length, GetPathSize(dest_url));
- EXPECT_EQ(base::File::FILE_OK, ofu()->DeleteFile(context.get(), dest_url));
- }
- void ClearTimestamp(const FileSystemURL& url) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->Touch(context.get(), url, base::Time(), base::Time()));
- EXPECT_EQ(base::Time(), GetModifiedTime(url));
- }
- base::Time GetModifiedTime(const FileSystemURL& url) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- base::FilePath data_path;
- base::File::Info file_info;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetFileInfo(context.get(), url, &file_info, &data_path));
- EXPECT_TRUE(change_observer()->HasNoChange());
- return file_info.last_modified;
- }
- void TestDirectoryTimestampHelper(const FileSystemURL& base_dir,
- bool copy,
- bool overwrite) {
- std::unique_ptr<FileSystemOperationContext> context;
- const FileSystemURL src_dir_url(
- FileSystemURLAppendUTF8(base_dir, "foo_dir"));
- const FileSystemURL dest_dir_url(
- FileSystemURLAppendUTF8(base_dir, "bar_dir"));
- const FileSystemURL src_file_url(
- FileSystemURLAppendUTF8(src_dir_url, "hoge"));
- const FileSystemURL dest_file_url(
- FileSystemURLAppendUTF8(dest_dir_url, "fuga"));
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), src_dir_url, true, true));
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), dest_dir_url, true, true));
- bool created = false;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), src_file_url, &created));
- if (overwrite) {
- context = NewContext(nullptr);
- EXPECT_EQ(
- base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), dest_file_url, &created));
- }
- ClearTimestamp(src_dir_url);
- ClearTimestamp(dest_dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(context.get(), src_file_url, dest_file_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- copy));
- if (copy)
- EXPECT_EQ(base::Time(), GetModifiedTime(src_dir_url));
- else
- EXPECT_NE(base::Time(), GetModifiedTime(src_dir_url));
- EXPECT_NE(base::Time(), GetModifiedTime(dest_dir_url));
- }
- void MaybeDropDatabasesAliveCaseTestBody() {
- std::unique_ptr<ObfuscatedFileUtil> file_util =
- CreateObfuscatedFileUtil(/*storage_policy=*/nullptr);
- file_util->InitOriginDatabase(url::Origin(), true /*create*/);
- ASSERT_TRUE(file_util->origin_database_ != nullptr);
- // Callback to Drop DB is called while ObfuscatedFileUtilTest is
- // still alive.
- file_util->db_flush_delay_seconds_ = 0;
- file_util->MarkUsed();
- task_environment_.RunUntilIdle();
- ASSERT_TRUE(file_util->origin_database_ == nullptr);
- }
- void MaybeDropDatabasesAlreadyDeletedCaseTestBody() {
- // Run message loop after OFU is already deleted to make sure callback
- // doesn't cause a crash for use after free.
- {
- std::unique_ptr<ObfuscatedFileUtil> file_util =
- CreateObfuscatedFileUtil(/*storage_policy=*/nullptr);
- file_util->InitOriginDatabase(url::Origin(), true /*create*/);
- file_util->db_flush_delay_seconds_ = 0;
- file_util->MarkUsed();
- }
- // At this point the callback is still in the message queue but OFU is gone.
- task_environment_.RunUntilIdle();
- }
- void DestroyDirectoryDatabase_IsolatedTestBody() {
- storage_policy_->AddIsolated(origin().GetURL());
- FileSystemURL url = FileSystemURL::CreateForTest(
- storage_key(), kFileSystemTypePersistent, base::FilePath());
- if (is_non_default_bucket())
- url.SetBucket(custom_bucket_);
- // Create DirectoryDatabase for isolated origin.
- SandboxDirectoryDatabase* db =
- ofu()->GetDirectoryDatabase(url, true /* create */);
- ASSERT_TRUE(db != nullptr);
- // Destroy it.
- (is_non_default_bucket()) ? ofu()->DestroyDirectoryDatabaseForBucket(
- url.bucket().value(), url.type())
- : ofu()->DestroyDirectoryDatabaseForStorageKey(
- url.storage_key(), url.type());
- ASSERT_TRUE(ofu()->directories_.empty());
- }
- void GetDirectoryDatabase_IsolatedTestBody() {
- storage_policy_->AddIsolated(origin().GetURL());
- FileSystemURL url = FileSystemURL::CreateForTest(
- blink::StorageKey(origin()), kFileSystemTypePersistent,
- base::FilePath());
- if (is_non_default_bucket())
- url.SetBucket(custom_bucket_);
- // Create DirectoryDatabase for isolated origin.
- SandboxDirectoryDatabase* db =
- ofu()->GetDirectoryDatabase(url, true /* create */);
- ASSERT_TRUE(db != nullptr);
- ASSERT_EQ(1U, ofu()->directories_.size());
- // Remove isolated.
- storage_policy_->RemoveIsolated(url.origin().GetURL());
- // This should still get the same database.
- SandboxDirectoryDatabase* db2 =
- ofu()->GetDirectoryDatabase(url, false /* create */);
- ASSERT_EQ(db, db2);
- }
- int64_t ComputeCurrentUsage() {
- return sandbox_file_system_.ComputeCurrentStorageKeyUsage() -
- sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage();
- }
- FileSystemContext* file_system_context() {
- return sandbox_file_system_.file_system_context();
- }
- const base::FilePath& data_dir_path() const { return data_dir_.GetPath(); }
- void CheckFileSize(FileSystemURL& url,
- base::FilePath& local_path,
- int64_t expected_size) {
- if (!is_incognito())
- EXPECT_EQ(expected_size, GetLocalFileSize(local_path));
- EXPECT_EQ(expected_size, GetPathSize(url));
- }
- protected:
- base::test::ScopedFeatureList scoped_feature_list_;
- std::unique_ptr<leveldb::Env> incognito_leveldb_environment_;
- base::test::TaskEnvironment task_environment_;
- base::ScopedTempDir data_dir_;
- scoped_refptr<MockSpecialStoragePolicy> storage_policy_;
- scoped_refptr<QuotaManager> quota_manager_;
- scoped_refptr<base::SingleThreadTaskRunner> quota_manager_task_runner_;
- scoped_refptr<FileSystemContext> file_system_context_;
- blink::StorageKey storage_key_;
- BucketLocator default_bucket_;
- BucketLocator custom_bucket_;
- BucketLocator alternate_custom_bucket_;
- FileSystemType type_;
- SandboxFileSystemTestHelper sandbox_file_system_;
- blink::mojom::QuotaStatusCode quota_status_;
- int64_t usage_;
- MockFileChangeObserver change_observer_;
- ChangeObserverList change_observers_;
- base::WeakPtrFactory<ObfuscatedFileUtilTest> weak_factory_{this};
- };
- INSTANTIATE_TEST_SUITE_P(
- All,
- ObfuscatedFileUtilTest,
- testing::Values(TestMode::kRegularFirstParty,
- TestMode::kRegularFirstPartyNonDefaultBucket,
- TestMode::kRegularThirdParty,
- TestMode::kRegularThirdPartyNonDefaultBucket,
- TestMode::kIncognitoFirstParty,
- TestMode::kIncognitoFirstPartyNonDefaultBucket,
- TestMode::kIncognitoThirdParty,
- TestMode::kIncognitoThirdPartyNonDefaultBucket));
- TEST_P(ObfuscatedFileUtilTest, TestCreateAndDeleteFile) {
- FileSystemURL url = CreateURLFromUTF8("fake/file");
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- bool created;
- base::File::Error result =
- ofu()->EnsureFileExists(context.get(), url, &created);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, result);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->DeleteFile(context.get(), url));
- url = CreateURLFromUTF8("test file");
- EXPECT_TRUE(change_observer()->HasNoChange());
- // Verify that file creation requires sufficient quota for the path.
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(
- ObfuscatedFileUtil::ComputeFilePathCost(url.path()) - 1);
- result = ofu()->EnsureFileExists(context.get(), url, &created);
- ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE, result);
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(
- ObfuscatedFileUtil::ComputeFilePathCost(url.path()));
- created = false;
- result = ofu()->EnsureFileExists(context.get(), url, &created);
- ASSERT_EQ(base::File::FILE_OK, result);
- ASSERT_TRUE(created);
- EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
- CheckFile(url);
- context = NewContext(nullptr);
- base::FilePath local_path;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetLocalFilePath(context.get(), url, &local_path));
- EXPECT_NE(is_incognito(), base::PathExists(local_path));
- EXPECT_TRUE(PathExists(url));
- // Verify that deleting a file isn't stopped by zero quota, and that it frees
- // up quote from its path.
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(0);
- EXPECT_EQ(base::File::FILE_OK, ofu()->DeleteFile(context.get(), url));
- EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
- EXPECT_FALSE(PathExists(url));
- EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url.path()),
- context->allowed_bytes_growth());
- context = NewContext(nullptr);
- bool exclusive = true;
- bool recursive = true;
- FileSystemURL directory_url = CreateURLFromUTF8("series/of/directories");
- url = FileSystemURLAppendUTF8(directory_url, "file name");
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), directory_url, exclusive,
- recursive));
- // The oepration created 3 directories recursively.
- EXPECT_EQ(3, change_observer()->get_and_reset_create_directory_count());
- context = NewContext(nullptr);
- created = false;
- result = ofu()->EnsureFileExists(context.get(), url, &created);
- ASSERT_TRUE(created);
- ASSERT_EQ(base::File::FILE_OK, result);
- EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
- CheckFile(url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetLocalFilePath(context.get(), url, &local_path));
- EXPECT_NE(is_incognito(), base::PathExists(local_path));
- EXPECT_TRUE(PathExists(url));
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK, ofu()->DeleteFile(context.get(), url));
- EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
- EXPECT_FALSE(PathExists(url));
- // Make sure we have no unexpected changes.
- EXPECT_TRUE(change_observer()->HasNoChange());
- }
- TEST_P(ObfuscatedFileUtilTest, TestTruncate) {
- bool created = false;
- FileSystemURL url = CreateURLFromUTF8("file");
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->Truncate(context.get(), url, 4));
- context = NewContext(nullptr);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- ASSERT_TRUE(created);
- EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
- context = NewContext(nullptr);
- base::FilePath local_path;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetLocalFilePath(context.get(), url, &local_path));
- CheckFileSize(url, local_path, 0);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK, ofu()->Truncate(context.get(), url, 10));
- EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
- CheckFileSize(url, local_path, 10);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK, ofu()->Truncate(context.get(), url, 1));
- EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
- CheckFileSize(url, local_path, 1);
- EXPECT_FALSE(DirectoryExists(url));
- EXPECT_TRUE(PathExists(url));
- // Make sure we have no unexpected changes.
- EXPECT_TRUE(change_observer()->HasNoChange());
- }
- TEST_P(ObfuscatedFileUtilTest, TestQuotaOnTruncation) {
- bool created = false;
- FileSystemURL url = CreateURLFromUTF8("file");
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(
- AllowUsageIncrease(PathCost(url))->context(), url, &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(0, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(1020)->context(), url, 1020));
- ASSERT_EQ(1020, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(-1020)->context(), url, 0));
- ASSERT_EQ(0, ComputeTotalFileSize());
- EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE,
- ofu()->Truncate(DisallowUsageIncrease(1021)->context(), url, 1021));
- ASSERT_EQ(0, ComputeTotalFileSize());
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(1020)->context(), url, 1020));
- ASSERT_EQ(1020, ComputeTotalFileSize());
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(0)->context(), url, 1020));
- ASSERT_EQ(1020, ComputeTotalFileSize());
- // quota exceeded
- {
- std::unique_ptr<UsageVerifyHelper> helper = AllowUsageIncrease(-1);
- helper->context()->set_allowed_bytes_growth(
- helper->context()->allowed_bytes_growth() - 1);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->Truncate(helper->context(), url, 1019));
- ASSERT_EQ(1019, ComputeTotalFileSize());
- }
- if (!is_incognito()) {
- // Delete backing file to make following truncation fail.
- base::FilePath local_path;
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->GetLocalFilePath(UnlimitedContext().get(), url, &local_path));
- ASSERT_FALSE(local_path.empty());
- ASSERT_TRUE(base::DeleteFile(local_path));
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->Truncate(LimitedContext(1234).get(), url, 1234));
- } else {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK, ofu()->DeleteFile(context.get(), url));
- }
- ASSERT_EQ(0, ComputeTotalFileSize());
- }
- TEST_P(ObfuscatedFileUtilTest, TestEnsureFileExists) {
- FileSystemURL url = CreateURLFromUTF8("fake/file");
- bool created = false;
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->EnsureFileExists(context.get(), url, &created));
- EXPECT_TRUE(change_observer()->HasNoChange());
- // Verify that file creation requires sufficient quota for the path.
- context = NewContext(nullptr);
- url = CreateURLFromUTF8("test file");
- created = false;
- context->set_allowed_bytes_growth(
- ObfuscatedFileUtil::ComputeFilePathCost(url.path()) - 1);
- ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE,
- ofu()->EnsureFileExists(context.get(), url, &created));
- ASSERT_FALSE(created);
- EXPECT_TRUE(change_observer()->HasNoChange());
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(
- ObfuscatedFileUtil::ComputeFilePathCost(url.path()));
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- ASSERT_TRUE(created);
- EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
- CheckFile(url);
- context = NewContext(nullptr);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- ASSERT_FALSE(created);
- EXPECT_TRUE(change_observer()->HasNoChange());
- // Also test in a subdirectory.
- url = CreateURLFromUTF8("path/to/file.txt");
- context = NewContext(nullptr);
- bool exclusive = true;
- bool recursive = true;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), FileSystemURLDirName(url),
- exclusive, recursive));
- // 2 directories: path/ and path/to.
- EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
- context = NewContext(nullptr);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- ASSERT_TRUE(created);
- EXPECT_FALSE(DirectoryExists(url));
- EXPECT_TRUE(PathExists(url));
- EXPECT_TRUE(change_observer()->HasNoChange());
- }
- TEST_P(ObfuscatedFileUtilTest, TestDirectoryOps) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- bool exclusive = false;
- bool recursive = false;
- FileSystemURL url = CreateURLFromUTF8("foo/bar");
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->DeleteDirectory(context.get(), url));
- FileSystemURL root = CreateURLFromUTF8(std::string());
- EXPECT_FALSE(DirectoryExists(url));
- EXPECT_FALSE(PathExists(url));
- context = NewContext(nullptr);
- EXPECT_TRUE(ofu()->IsDirectoryEmpty(context.get(), root));
- context = NewContext(nullptr);
- exclusive = false;
- recursive = true;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
- EXPECT_TRUE(DirectoryExists(url));
- EXPECT_TRUE(PathExists(url));
- context = NewContext(nullptr);
- EXPECT_FALSE(ofu()->IsDirectoryEmpty(context.get(), root));
- EXPECT_TRUE(DirectoryExists(FileSystemURLDirName(url)));
- context = NewContext(nullptr);
- EXPECT_FALSE(
- ofu()->IsDirectoryEmpty(context.get(), FileSystemURLDirName(url)));
- // Can't remove a non-empty directory.
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY,
- ofu()->DeleteDirectory(context.get(), FileSystemURLDirName(url)));
- EXPECT_TRUE(change_observer()->HasNoChange());
- base::File::Info file_info;
- base::FilePath local_path;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetFileInfo(context.get(), url, &file_info, &local_path));
- EXPECT_TRUE(local_path.empty());
- EXPECT_TRUE(file_info.is_directory);
- EXPECT_FALSE(file_info.is_symbolic_link);
- // Same create again should succeed, since exclusive is false.
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- EXPECT_TRUE(change_observer()->HasNoChange());
- exclusive = true;
- recursive = true;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_EXISTS,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- EXPECT_TRUE(change_observer()->HasNoChange());
- // Verify that deleting a directory isn't stopped by zero quota, and that it
- // frees up quota from its path.
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(0);
- EXPECT_EQ(base::File::FILE_OK, ofu()->DeleteDirectory(context.get(), url));
- EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
- EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url.path()),
- context->allowed_bytes_growth());
- url = CreateURLFromUTF8("foo/bop");
- EXPECT_FALSE(DirectoryExists(url));
- EXPECT_FALSE(PathExists(url));
- context = NewContext(nullptr);
- EXPECT_TRUE(ofu()->IsDirectoryEmpty(context.get(), url));
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->GetFileInfo(context.get(), url, &file_info, &local_path));
- // Verify that file creation requires sufficient quota for the path.
- exclusive = true;
- recursive = false;
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(
- ObfuscatedFileUtil::ComputeFilePathCost(url.path()) - 1);
- EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- EXPECT_TRUE(change_observer()->HasNoChange());
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(
- ObfuscatedFileUtil::ComputeFilePathCost(url.path()));
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
- EXPECT_TRUE(DirectoryExists(url));
- EXPECT_TRUE(PathExists(url));
- exclusive = true;
- recursive = false;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_EXISTS,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- EXPECT_TRUE(change_observer()->HasNoChange());
- exclusive = true;
- recursive = false;
- url = CreateURLFromUTF8("foo");
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_EXISTS,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- EXPECT_TRUE(change_observer()->HasNoChange());
- url = CreateURLFromUTF8("blah");
- EXPECT_FALSE(DirectoryExists(url));
- EXPECT_FALSE(PathExists(url));
- exclusive = true;
- recursive = false;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
- EXPECT_TRUE(DirectoryExists(url));
- EXPECT_TRUE(PathExists(url));
- exclusive = true;
- recursive = false;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_EXISTS,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- EXPECT_TRUE(change_observer()->HasNoChange());
- }
- TEST_P(ObfuscatedFileUtilTest, TestReadDirectory) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- bool exclusive = true;
- bool recursive = true;
- FileSystemURL url = CreateURLFromUTF8("directory/to/use");
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- TestReadDirectoryHelper(url);
- }
- TEST_P(ObfuscatedFileUtilTest, TestReadRootWithSlash) {
- TestReadDirectoryHelper(CreateURLFromUTF8(std::string()));
- }
- TEST_P(ObfuscatedFileUtilTest, TestReadRootWithEmptyString) {
- TestReadDirectoryHelper(CreateURLFromUTF8("/"));
- }
- TEST_P(ObfuscatedFileUtilTest, TestReadDirectoryOnFile) {
- FileSystemURL url = CreateURLFromUTF8("file");
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- bool created = false;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- ASSERT_TRUE(created);
- std::vector<filesystem::mojom::DirectoryEntry> entries;
- EXPECT_EQ(
- base::File::FILE_ERROR_NOT_A_DIRECTORY,
- AsyncFileTestHelper::ReadDirectory(file_system_context(), url, &entries));
- EXPECT_TRUE(ofu()->IsDirectoryEmpty(context.get(), url));
- }
- // TODO(https://crbug.com/702990): Remove this test once last_access_time has
- // been removed after PPAPI has been deprecated. Fuchsia does not support touch,
- // which breaks this test that relies on it. Since PPAPI is being deprecated,
- // this test is excluded from the Fuchsia build.
- // See https://crbug.com/1077456 for details.
- #if !BUILDFLAG(IS_FUCHSIA)
- TEST_P(ObfuscatedFileUtilTest, TestTouch) {
- FileSystemURL url = CreateURLFromUTF8("file");
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- base::Time last_access_time = base::Time::Now();
- base::Time last_modified_time = base::Time::Now();
- // It's not there yet.
- EXPECT_EQ(
- base::File::FILE_ERROR_NOT_FOUND,
- ofu()->Touch(context.get(), url, last_access_time, last_modified_time));
- // OK, now create it.
- context = NewContext(nullptr);
- bool created = false;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- ASSERT_TRUE(created);
- TestTouchHelper(url, true);
- // Now test a directory:
- context = NewContext(nullptr);
- bool exclusive = true;
- bool recursive = false;
- url = CreateURLFromUTF8("dir");
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- TestTouchHelper(url, false);
- }
- #endif // !BUILDFLAG(IS_FUCHSIA)
- TEST_P(ObfuscatedFileUtilTest, TestPathQuotas) {
- FileSystemURL url = CreateURLFromUTF8("fake/file");
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- url = CreateURLFromUTF8("file name");
- context->set_allowed_bytes_growth(5);
- bool created = false;
- EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE,
- ofu()->EnsureFileExists(context.get(), url, &created));
- EXPECT_FALSE(created);
- context->set_allowed_bytes_growth(1024);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- EXPECT_TRUE(created);
- int64_t path_cost = ObfuscatedFileUtil::ComputeFilePathCost(url.path());
- EXPECT_EQ(1024 - path_cost, context->allowed_bytes_growth());
- context->set_allowed_bytes_growth(1024);
- bool exclusive = true;
- bool recursive = true;
- url = CreateURLFromUTF8("directory/to/use");
- path_cost = 0;
- for (const auto& component : url.path().GetComponents()) {
- path_cost +=
- ObfuscatedFileUtil::ComputeFilePathCost(base::FilePath(component));
- }
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(1024);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), url, exclusive, recursive));
- EXPECT_EQ(1024 - path_cost, context->allowed_bytes_growth());
- }
- TEST_P(ObfuscatedFileUtilTest, TestCopyOrMoveFileNotFound) {
- FileSystemURL source_url = CreateURLFromUTF8("path0.txt");
- FileSystemURL dest_url = CreateURLFromUTF8("path1.txt");
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- bool is_copy_not_move = false;
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->CopyOrMoveFile(context.get(), source_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy_not_move));
- EXPECT_TRUE(change_observer()->HasNoChange());
- context = NewContext(nullptr);
- is_copy_not_move = true;
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->CopyOrMoveFile(context.get(), source_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy_not_move));
- EXPECT_TRUE(change_observer()->HasNoChange());
- source_url = CreateURLFromUTF8("dir/dir/file");
- bool exclusive = true;
- bool recursive = true;
- context = NewContext(nullptr);
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), FileSystemURLDirName(source_url),
- exclusive, recursive));
- EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
- is_copy_not_move = false;
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->CopyOrMoveFile(context.get(), source_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy_not_move));
- EXPECT_TRUE(change_observer()->HasNoChange());
- context = NewContext(nullptr);
- is_copy_not_move = true;
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->CopyOrMoveFile(context.get(), source_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy_not_move));
- EXPECT_TRUE(change_observer()->HasNoChange());
- }
- TEST_P(ObfuscatedFileUtilTest, TestCopyOrMoveFileSuccess) {
- const int64_t kSourceLength = 5;
- const int64_t kDestLength = 50;
- for (size_t i = 0; i < std::size(kCopyMoveTestCases); ++i) {
- SCOPED_TRACE(testing::Message() << "kCopyMoveTestCase " << i);
- const CopyMoveTestCaseRecord& test_case = kCopyMoveTestCases[i];
- SCOPED_TRACE(testing::Message()
- << "\t is_copy_not_move " << test_case.is_copy_not_move);
- SCOPED_TRACE(testing::Message()
- << "\t source_path " << test_case.source_path);
- SCOPED_TRACE(testing::Message() << "\t dest_path " << test_case.dest_path);
- SCOPED_TRACE(testing::Message()
- << "\t cause_overwrite " << test_case.cause_overwrite);
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- bool exclusive = false;
- bool recursive = true;
- FileSystemURL source_url = CreateURLFromUTF8(test_case.source_path);
- FileSystemURL dest_url = CreateURLFromUTF8(test_case.dest_path);
- context = NewContext(nullptr);
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), FileSystemURLDirName(source_url),
- exclusive, recursive));
- context = NewContext(nullptr);
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), FileSystemURLDirName(dest_url),
- exclusive, recursive));
- bool created = false;
- context = NewContext(nullptr);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), source_url, &created));
- ASSERT_TRUE(created);
- context = NewContext(nullptr);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(context.get(), source_url, kSourceLength));
- if (test_case.cause_overwrite) {
- context = NewContext(nullptr);
- created = false;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), dest_url, &created));
- ASSERT_TRUE(created);
- context = NewContext(nullptr);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(context.get(), dest_url, kDestLength));
- }
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(context.get(), source_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- test_case.is_copy_not_move));
- if (test_case.is_copy_not_move) {
- base::File::Info file_info;
- base::FilePath local_path;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetFileInfo(context.get(), source_url, &file_info,
- &local_path));
- EXPECT_EQ(kSourceLength, file_info.size);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->DeleteFile(context.get(), source_url));
- } else {
- base::File::Info file_info;
- base::FilePath local_path;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->GetFileInfo(context.get(), source_url, &file_info,
- &local_path));
- }
- base::File::Info file_info;
- base::FilePath local_path;
- EXPECT_EQ(base::File::FILE_OK, ofu()->GetFileInfo(context.get(), dest_url,
- &file_info, &local_path));
- EXPECT_EQ(kSourceLength, file_info.size);
- EXPECT_EQ(base::File::FILE_OK, ofu()->DeleteFile(context.get(), dest_url));
- }
- }
- TEST_P(ObfuscatedFileUtilTest, TestCopyPathQuotas) {
- FileSystemURL src_url = CreateURLFromUTF8("src path");
- FileSystemURL dest_url = CreateURLFromUTF8("destination path");
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- bool created = false;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), src_url, &created));
- bool is_copy = true;
- // Copy, no overwrite.
- context->set_allowed_bytes_growth(
- ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()) - 1);
- EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE,
- ofu()->CopyOrMoveFile(context.get(), src_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy));
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(
- ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()));
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(context.get(), src_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy));
- // Copy, with overwrite.
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(0);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(context.get(), src_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy));
- }
- TEST_P(ObfuscatedFileUtilTest, TestMovePathQuotasWithRename) {
- FileSystemURL src_url = CreateURLFromUTF8("src path");
- FileSystemURL dest_url = CreateURLFromUTF8("destination path");
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- bool created = false;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), src_url, &created));
- bool is_copy = false;
- // Move, rename, no overwrite.
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(
- ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()) -
- ObfuscatedFileUtil::ComputeFilePathCost(src_url.path()) - 1);
- EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE,
- ofu()->CopyOrMoveFile(context.get(), src_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy));
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(
- ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()) -
- ObfuscatedFileUtil::ComputeFilePathCost(src_url.path()));
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(context.get(), src_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy));
- context = NewContext(nullptr);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), src_url, &created));
- // Move, rename, with overwrite.
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(0);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(context.get(), src_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy));
- }
- TEST_P(ObfuscatedFileUtilTest, TestMovePathQuotasWithoutRename) {
- FileSystemURL src_url = CreateURLFromUTF8("src path");
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- bool created = false;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), src_url, &created));
- bool exclusive = true;
- bool recursive = false;
- FileSystemURL dir_url = CreateURLFromUTF8("directory path");
- context = NewContext(nullptr);
- ASSERT_EQ(base::File::FILE_OK, ofu()->CreateDirectory(context.get(), dir_url,
- exclusive, recursive));
- FileSystemURL dest_url = FileSystemURLAppend(dir_url, src_url.path().value());
- bool is_copy = false;
- int64_t allowed_bytes_growth = -1000; // Over quota, this should still work.
- // Move, no rename, no overwrite.
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(allowed_bytes_growth);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(context.get(), src_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy));
- EXPECT_EQ(allowed_bytes_growth, context->allowed_bytes_growth());
- // Move, no rename, with overwrite.
- context = NewContext(nullptr);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), src_url, &created));
- context = NewContext(nullptr);
- context->set_allowed_bytes_growth(allowed_bytes_growth);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(context.get(), src_url, dest_url,
- FileSystemOperation::CopyOrMoveOptionSet(),
- is_copy));
- EXPECT_EQ(allowed_bytes_growth +
- ObfuscatedFileUtil::ComputeFilePathCost(src_url.path()),
- context->allowed_bytes_growth());
- }
- TEST_P(ObfuscatedFileUtilTest, TestCopyInForeignFile) {
- TestCopyInForeignFileHelper(false /* overwrite */);
- TestCopyInForeignFileHelper(true /* overwrite */);
- }
- TEST_P(ObfuscatedFileUtilTest, TestEnumerator) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- FileSystemURL src_url = CreateURLFromUTF8("source dir");
- bool exclusive = true;
- bool recursive = false;
- ASSERT_EQ(base::File::FILE_OK, ofu()->CreateDirectory(context.get(), src_url,
- exclusive, recursive));
- std::set<base::FilePath::StringType> files;
- std::set<base::FilePath::StringType> directories;
- FillTestDirectory(src_url, &files, &directories);
- FileSystemURL dest_url = CreateURLFromUTF8("destination dir");
- EXPECT_FALSE(DirectoryExists(dest_url));
- ASSERT_EQ(base::File::FILE_OK, AsyncFileTestHelper::Copy(
- file_system_context(), src_url, dest_url));
- ValidateTestDirectory(dest_url, files, directories);
- EXPECT_TRUE(DirectoryExists(src_url));
- EXPECT_TRUE(DirectoryExists(dest_url));
- recursive = true;
- ASSERT_EQ(
- base::File::FILE_OK,
- AsyncFileTestHelper::Remove(file_system_context(), dest_url, recursive));
- EXPECT_FALSE(DirectoryExists(dest_url));
- }
- TEST_P(ObfuscatedFileUtilTest, TestStorageKeyEnumerator) {
- std::unique_ptr<ObfuscatedFileUtil::AbstractStorageKeyEnumerator> enumerator =
- ofu()->CreateStorageKeyEnumerator();
- // The test helper starts out with a single filesystem.
- EXPECT_TRUE(enumerator.get());
- // This test is not relevant for third-party or non-default buckets code paths
- // because these paths do not add to the OriginDatabase, the structure that
- // populates the enumerator being tested. So in a test environment, this
- // enumerator should not have any additional StorageKeys to access via Next().
- if (is_third_party_context() || is_non_default_bucket()) {
- EXPECT_EQ(absl::nullopt, enumerator->Next());
- return;
- }
- EXPECT_EQ(storage_key(), enumerator->Next());
- ASSERT_TRUE(type() == kFileSystemTypeTemporary);
- EXPECT_TRUE(HasFileSystemType(enumerator.get(), kFileSystemTypeTemporary));
- EXPECT_FALSE(HasFileSystemType(enumerator.get(), kFileSystemTypePersistent));
- EXPECT_FALSE(enumerator->Next());
- EXPECT_FALSE(HasFileSystemType(enumerator.get(), kFileSystemTypeTemporary));
- EXPECT_FALSE(HasFileSystemType(enumerator.get(), kFileSystemTypePersistent));
- std::set<blink::StorageKey> storage_keys_expected;
- storage_keys_expected.insert(storage_key());
- for (size_t i = 0; i < std::size(kOriginEnumerationTestRecords); ++i) {
- SCOPED_TRACE(testing::Message()
- << "Validating kOriginEnumerationTestRecords " << i);
- const OriginEnumerationTestRecord& record =
- kOriginEnumerationTestRecords[i];
- blink::StorageKey storage_key =
- blink::StorageKey::CreateFromStringForTesting(record.origin_url);
- storage_keys_expected.insert(storage_key);
- if (record.has_temporary) {
- std::unique_ptr<SandboxFileSystemTestHelper> file_system =
- NewFileSystem(storage_key, kFileSystemTypeTemporary);
- std::unique_ptr<FileSystemOperationContext> context(
- NewContext(file_system.get()));
- bool created = false;
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->EnsureFileExists(
- context.get(), file_system->CreateURLFromUTF8("file"), &created));
- EXPECT_TRUE(created);
- }
- if (record.has_persistent) {
- std::unique_ptr<SandboxFileSystemTestHelper> file_system =
- NewFileSystem(storage_key, kFileSystemTypePersistent);
- std::unique_ptr<FileSystemOperationContext> context(
- NewContext(file_system.get()));
- bool created = false;
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->EnsureFileExists(
- context.get(), file_system->CreateURLFromUTF8("file"), &created));
- EXPECT_TRUE(created);
- }
- }
- enumerator = ofu()->CreateStorageKeyEnumerator();
- EXPECT_TRUE(enumerator.get());
- std::set<blink::StorageKey> storage_keys_found;
- absl::optional<blink::StorageKey> enumerator_storage_key;
- while ((enumerator_storage_key = enumerator->Next()).has_value()) {
- storage_keys_found.insert(enumerator_storage_key.value());
- SCOPED_TRACE(testing::Message()
- << "Handling "
- << enumerator_storage_key->origin().Serialize());
- bool found = false;
- for (const auto& record : kOriginEnumerationTestRecords) {
- if (enumerator_storage_key->origin().GetURL() != record.origin_url)
- continue;
- found = true;
- EXPECT_EQ(record.has_temporary,
- HasFileSystemType(enumerator.get(), kFileSystemTypeTemporary));
- EXPECT_EQ(record.has_persistent,
- HasFileSystemType(enumerator.get(), kFileSystemTypePersistent));
- }
- // Deal with the default filesystem created by the test helper.
- if (!found && enumerator_storage_key == storage_key()) {
- ASSERT_TRUE(type() == kFileSystemTypeTemporary);
- EXPECT_TRUE(
- HasFileSystemType(enumerator.get(), kFileSystemTypeTemporary));
- EXPECT_FALSE(
- HasFileSystemType(enumerator.get(), kFileSystemTypePersistent));
- found = true;
- }
- EXPECT_TRUE(found);
- }
- std::set<blink::StorageKey> diff;
- std::set_symmetric_difference(
- storage_keys_expected.begin(), storage_keys_expected.end(),
- storage_keys_found.begin(), storage_keys_found.end(),
- inserter(diff, diff.begin()));
- EXPECT_TRUE(diff.empty());
- }
- TEST_P(ObfuscatedFileUtilTest, TestRevokeUsageCache) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- int64_t expected_quota = 0;
- for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) {
- SCOPED_TRACE(testing::Message() << "Creating kRegularTestCase " << i);
- const FileSystemTestCaseRecord& test_case = kRegularFileSystemTestCases[i];
- base::FilePath file_path(test_case.path);
- expected_quota += ObfuscatedFileUtil::ComputeFilePathCost(file_path);
- if (test_case.is_directory) {
- bool exclusive = true;
- bool recursive = false;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), CreateURL(file_path),
- exclusive, recursive));
- } else {
- bool created = false;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), CreateURL(file_path),
- &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(context.get(), CreateURL(file_path),
- test_case.data_file_size));
- expected_quota += test_case.data_file_size;
- }
- }
- // Usually raw size in usage cache and the usage returned by QuotaUtil
- // should be same.
- EXPECT_EQ(expected_quota, SizeInUsageFile());
- EXPECT_EQ(expected_quota, SizeByQuotaUtil());
- RevokeUsageCache();
- EXPECT_EQ(-1, SizeInUsageFile());
- EXPECT_EQ(expected_quota, SizeByQuotaUtil());
- // This should reconstruct the cache.
- GetUsageFromQuotaManager();
- EXPECT_EQ(expected_quota, SizeInUsageFile());
- EXPECT_EQ(expected_quota, SizeByQuotaUtil());
- EXPECT_EQ(expected_quota, usage());
- }
- TEST_P(ObfuscatedFileUtilTest, TestInconsistency) {
- const FileSystemURL kPath1 = CreateURLFromUTF8("hoge");
- const FileSystemURL kPath2 = CreateURLFromUTF8("fuga");
- std::unique_ptr<FileSystemOperationContext> context;
- base::File::Info file_info;
- base::FilePath data_path;
- bool created = false;
- // Create a non-empty file.
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), kPath1, &created));
- EXPECT_TRUE(created);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK, ofu()->Truncate(context.get(), kPath1, 10));
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetFileInfo(context.get(), kPath1, &file_info, &data_path));
- EXPECT_EQ(10, file_info.size);
- // Destroy database to make inconsistency between database and filesystem.
- (is_non_default_bucket())
- ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type())
- : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(), type());
- // Try to get file info of broken file.
- EXPECT_FALSE(PathExists(kPath1));
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), kPath1, &created));
- EXPECT_TRUE(created);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetFileInfo(context.get(), kPath1, &file_info, &data_path));
- EXPECT_EQ(0, file_info.size);
- // Make another broken file to `kPath2`.
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), kPath2, &created));
- EXPECT_TRUE(created);
- // Destroy again.
- (is_non_default_bucket())
- ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type())
- : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(), type());
- // Repair broken `kPath1`.
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->Touch(context.get(), kPath1, base::Time::Now(),
- base::Time::Now()));
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), kPath1, &created));
- EXPECT_TRUE(created);
- // Copy from sound `kPath1` to broken `kPath2`.
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(context.get(), kPath1, kPath2,
- FileSystemOperation::CopyOrMoveOptionSet(),
- true /* copy */));
- (is_non_default_bucket())
- ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type())
- : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(), type());
- context = NewContext(nullptr);
- created = false;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), kPath1, &created));
- EXPECT_TRUE(created);
- EXPECT_EQ(0, GetPathSize(kPath1));
- }
- TEST_P(ObfuscatedFileUtilTest, TestIncompleteDirectoryReading) {
- const FileSystemURL kPath[] = {CreateURLFromUTF8("foo"),
- CreateURLFromUTF8("bar"),
- CreateURLFromUTF8("baz")};
- const FileSystemURL empty_path = CreateURL(base::FilePath());
- std::unique_ptr<FileSystemOperationContext> context;
- for (const auto& path : kPath) {
- bool created = false;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), path, &created));
- EXPECT_TRUE(created);
- }
- std::vector<filesystem::mojom::DirectoryEntry> entries;
- EXPECT_EQ(base::File::FILE_OK,
- AsyncFileTestHelper::ReadDirectory(file_system_context(),
- empty_path, &entries));
- EXPECT_EQ(3u, entries.size());
- EXPECT_EQ(base::File::FILE_OK, ofu()->DeleteFile(context.get(), kPath[0]));
- entries.clear();
- EXPECT_EQ(base::File::FILE_OK,
- AsyncFileTestHelper::ReadDirectory(file_system_context(),
- empty_path, &entries));
- EXPECT_EQ(std::size(kPath) - 1, entries.size());
- }
- TEST_P(ObfuscatedFileUtilTest, TestDirectoryTimestampForCreation) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- const FileSystemURL dir_url = CreateURLFromUTF8("foo_dir");
- // Create working directory.
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), dir_url, false, false));
- // EnsureFileExists, create case.
- FileSystemURL url(FileSystemURLAppendUTF8(dir_url, "EnsureFileExists_file"));
- bool created = false;
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- EXPECT_TRUE(created);
- EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
- // non create case.
- created = true;
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- EXPECT_FALSE(created);
- EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
- // fail case.
- url = FileSystemURLAppendUTF8(dir_url, "EnsureFileExists_dir");
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), url, false, false));
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE,
- ofu()->EnsureFileExists(context.get(), url, &created));
- EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
- // CreateOrOpen, create case.
- url = FileSystemURLAppendUTF8(dir_url, "CreateOrOpen_file");
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- created = false;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- EXPECT_TRUE(created);
- EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
- // open case.
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- EXPECT_FALSE(created);
- EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
- // fail case
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- EXPECT_FALSE(created);
- EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
- // CreateDirectory, create case.
- // Creating CreateDirectory_dir and CreateDirectory_dir/subdir.
- url = FileSystemURLAppendUTF8(dir_url, "CreateDirectory_dir");
- FileSystemURL subdir_url(FileSystemURLAppendUTF8(url, "subdir"));
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), subdir_url,
- true /* exclusive */, true /* recursive */));
- EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
- // create subdir case.
- // Creating CreateDirectory_dir/subdir2.
- subdir_url = FileSystemURLAppendUTF8(url, "subdir2");
- ClearTimestamp(dir_url);
- ClearTimestamp(url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), subdir_url,
- true /* exclusive */, true /* recursive */));
- EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
- EXPECT_NE(base::Time(), GetModifiedTime(url));
- // fail case.
- url = FileSystemURLAppendUTF8(dir_url, "CreateDirectory_dir");
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_EXISTS,
- ofu()->CreateDirectory(context.get(), url, true /* exclusive */,
- true /* recursive */));
- EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
- // CopyInForeignFile, create case.
- url = FileSystemURLAppendUTF8(dir_url, "CopyInForeignFile_file");
- base::ScopedTempDir foreign_source_dir;
- ASSERT_TRUE(foreign_source_dir.CreateUniqueTempDir());
- base::FilePath foreign_src_file_path =
- foreign_source_dir.GetPath().AppendASCII("file_name");
- EXPECT_EQ(base::File::FILE_OK,
- NativeFileUtil::EnsureFileExists(foreign_src_file_path, &created));
- EXPECT_TRUE(created);
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(
- base::File::FILE_OK,
- ofu()->CopyInForeignFile(context.get(), foreign_src_file_path, url));
- EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
- }
- TEST_P(ObfuscatedFileUtilTest, TestDirectoryTimestampForDeletion) {
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- const FileSystemURL dir_url = CreateURLFromUTF8("foo_dir");
- // Create working directory.
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), dir_url, false, false));
- // DeleteFile, delete case.
- FileSystemURL url = FileSystemURLAppendUTF8(dir_url, "DeleteFile_file");
- bool created = false;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url, &created));
- EXPECT_TRUE(created);
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK, ofu()->DeleteFile(context.get(), url));
- EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
- // fail case.
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- ofu()->DeleteFile(context.get(), url));
- EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
- // DeleteDirectory, fail case.
- url = FileSystemURLAppendUTF8(dir_url, "DeleteDirectory_dir");
- FileSystemURL file_path(FileSystemURLAppendUTF8(url, "pakeratta"));
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), url, true, true));
- created = false;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), file_path, &created));
- EXPECT_TRUE(created);
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY,
- ofu()->DeleteDirectory(context.get(), url));
- EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
- // delete case.
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK, ofu()->DeleteFile(context.get(), file_path));
- ClearTimestamp(dir_url);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK, ofu()->DeleteDirectory(context.get(), url));
- EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
- }
- TEST_P(ObfuscatedFileUtilTest, TestDirectoryTimestampForCopyAndMove) {
- TestDirectoryTimestampHelper(CreateURLFromUTF8("copy overwrite"), true, true);
- TestDirectoryTimestampHelper(CreateURLFromUTF8("copy non-overwrite"), true,
- false);
- TestDirectoryTimestampHelper(CreateURLFromUTF8("move overwrite"), false,
- true);
- TestDirectoryTimestampHelper(CreateURLFromUTF8("move non-overwrite"), false,
- false);
- }
- TEST_P(ObfuscatedFileUtilTest, TestFileEnumeratorTimestamp) {
- FileSystemURL dir = CreateURLFromUTF8("foo");
- FileSystemURL url1 = FileSystemURLAppendUTF8(dir, "bar");
- FileSystemURL url2 = FileSystemURLAppendUTF8(dir, "baz");
- std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), dir, false, false));
- bool created = false;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(context.get(), url1, &created));
- EXPECT_TRUE(created);
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(context.get(), url2, false, false));
- base::FilePath file_path;
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetLocalFilePath(context.get(), url1, &file_path));
- EXPECT_FALSE(file_path.empty());
- context = NewContext(nullptr);
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->Touch(context.get(), url1,
- base::Time::Now() + base::Hours(1), base::Time()));
- context = NewContext(nullptr);
- std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum =
- ofu()->CreateFileEnumerator(context.get(), dir, false);
- int count = 0;
- base::FilePath file_path_each;
- while (!(file_path_each = file_enum->Next()).empty()) {
- context = NewContext(nullptr);
- base::File::Info file_info;
- FileSystemURL new_url = FileSystemURL::CreateForTest(
- dir.storage_key(), dir.mount_type(), file_path_each);
- if (dir.bucket().has_value())
- new_url.SetBucket(dir.bucket().value());
- EXPECT_EQ(base::File::FILE_OK, ofu()->GetFileInfo(context.get(), new_url,
- &file_info, &file_path));
- EXPECT_EQ(file_info.is_directory, file_enum->IsDirectory());
- EXPECT_EQ(file_info.last_modified, file_enum->LastModifiedTime());
- EXPECT_EQ(file_info.size, file_enum->Size());
- ++count;
- }
- EXPECT_EQ(2, count);
- }
- TEST_P(ObfuscatedFileUtilTest, TestQuotaOnCopyFile) {
- FileSystemURL from_file(CreateURLFromUTF8("fromfile"));
- FileSystemURL obstacle_file(CreateURLFromUTF8("obstaclefile"));
- FileSystemURL to_file1(CreateURLFromUTF8("tofile1"));
- FileSystemURL to_file2(CreateURLFromUTF8("tofile2"));
- bool created;
- int64_t expected_total_file_size = 0;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(
- AllowUsageIncrease(PathCost(from_file))->context(), from_file,
- &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(
- AllowUsageIncrease(PathCost(obstacle_file))->context(),
- obstacle_file, &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64_t from_file_size = 1020;
- expected_total_file_size += from_file_size;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(from_file_size)->context(),
- from_file, from_file_size));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64_t obstacle_file_size = 1;
- expected_total_file_size += obstacle_file_size;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(obstacle_file_size)->context(),
- obstacle_file, obstacle_file_size));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64_t to_file1_size = from_file_size;
- expected_total_file_size += to_file1_size;
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->CopyOrMoveFile(
- AllowUsageIncrease(PathCost(to_file1) + to_file1_size)->context(),
- from_file, to_file1, FileSystemOperation::CopyOrMoveOptionSet(),
- true /* copy */));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- ASSERT_EQ(
- base::File::FILE_ERROR_NO_SPACE,
- ofu()->CopyOrMoveFile(
- DisallowUsageIncrease(PathCost(to_file2) + from_file_size)->context(),
- from_file, to_file2, FileSystemOperation::CopyOrMoveOptionSet(),
- true /* copy */));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64_t old_obstacle_file_size = obstacle_file_size;
- obstacle_file_size = from_file_size;
- expected_total_file_size += obstacle_file_size - old_obstacle_file_size;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(
- AllowUsageIncrease(obstacle_file_size - old_obstacle_file_size)
- ->context(),
- from_file, obstacle_file,
- FileSystemOperation::CopyOrMoveOptionSet(), true /* copy */));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64_t old_from_file_size = from_file_size;
- from_file_size = old_from_file_size - 1;
- expected_total_file_size += from_file_size - old_from_file_size;
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->Truncate(
- AllowUsageIncrease(from_file_size - old_from_file_size)->context(),
- from_file, from_file_size));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- // quota exceeded
- {
- old_obstacle_file_size = obstacle_file_size;
- obstacle_file_size = from_file_size;
- expected_total_file_size += obstacle_file_size - old_obstacle_file_size;
- std::unique_ptr<UsageVerifyHelper> helper =
- AllowUsageIncrease(obstacle_file_size - old_obstacle_file_size);
- helper->context()->set_allowed_bytes_growth(
- helper->context()->allowed_bytes_growth() - 1);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(helper->context(), from_file, obstacle_file,
- FileSystemOperation::CopyOrMoveOptionSet(),
- true /* copy */));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- }
- }
- TEST_P(ObfuscatedFileUtilTest, TestQuotaOnMoveFile) {
- FileSystemURL from_file(CreateURLFromUTF8("fromfile"));
- FileSystemURL obstacle_file(CreateURLFromUTF8("obstaclefile"));
- FileSystemURL to_file(CreateURLFromUTF8("tofile"));
- bool created;
- int64_t expected_total_file_size = 0;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(
- AllowUsageIncrease(PathCost(from_file))->context(), from_file,
- &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64_t from_file_size = 1020;
- expected_total_file_size += from_file_size;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(from_file_size)->context(),
- from_file, from_file_size));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- from_file_size = 0;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(
- AllowUsageIncrease(-PathCost(from_file) + PathCost(to_file))
- ->context(),
- from_file, to_file, FileSystemOperation::CopyOrMoveOptionSet(),
- false /* move */));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(
- AllowUsageIncrease(PathCost(from_file))->context(), from_file,
- &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(
- AllowUsageIncrease(PathCost(obstacle_file))->context(),
- obstacle_file, &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- from_file_size = 1020;
- expected_total_file_size += from_file_size;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(from_file_size)->context(),
- from_file, from_file_size));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64_t obstacle_file_size = 1;
- expected_total_file_size += obstacle_file_size;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(1)->context(), obstacle_file,
- obstacle_file_size));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64_t old_obstacle_file_size = obstacle_file_size;
- obstacle_file_size = from_file_size;
- from_file_size = 0;
- expected_total_file_size -= old_obstacle_file_size;
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->CopyOrMoveFile(
- AllowUsageIncrease(-old_obstacle_file_size - PathCost(from_file))
- ->context(),
- from_file, obstacle_file, FileSystemOperation::CopyOrMoveOptionSet(),
- false /* move */));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(
- AllowUsageIncrease(PathCost(from_file))->context(), from_file,
- &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- from_file_size = 10;
- expected_total_file_size += from_file_size;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(from_file_size)->context(),
- from_file, from_file_size));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- // quota exceeded even after operation
- old_obstacle_file_size = obstacle_file_size;
- obstacle_file_size = from_file_size;
- from_file_size = 0;
- expected_total_file_size -= old_obstacle_file_size;
- std::unique_ptr<FileSystemOperationContext> context =
- LimitedContext(-old_obstacle_file_size - PathCost(from_file) - 1);
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->CopyOrMoveFile(context.get(), from_file, obstacle_file,
- FileSystemOperation::CopyOrMoveOptionSet(),
- false /* move */));
- ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- context.reset();
- }
- TEST_P(ObfuscatedFileUtilTest, TestQuotaOnRemove) {
- FileSystemURL dir(CreateURLFromUTF8("dir"));
- FileSystemURL file(CreateURLFromUTF8("file"));
- FileSystemURL dfile1(CreateURLFromUTF8("dir/dfile1"));
- FileSystemURL dfile2(CreateURLFromUTF8("dir/dfile2"));
- bool created;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(
- AllowUsageIncrease(PathCost(file))->context(), file, &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(0, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->CreateDirectory(AllowUsageIncrease(PathCost(dir))->context(),
- dir, false, false));
- ASSERT_EQ(0, ComputeTotalFileSize());
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->EnsureFileExists(AllowUsageIncrease(PathCost(dfile1))->context(),
- dfile1, &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(0, ComputeTotalFileSize());
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->EnsureFileExists(AllowUsageIncrease(PathCost(dfile2))->context(),
- dfile2, &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(0, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(340)->context(), file, 340));
- ASSERT_EQ(340, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(1020)->context(), dfile1, 1020));
- ASSERT_EQ(1360, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(120)->context(), dfile2, 120));
- ASSERT_EQ(1480, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->DeleteFile(
- AllowUsageIncrease(-PathCost(file) - 340)->context(), file));
- ASSERT_EQ(1140, ComputeTotalFileSize());
- ASSERT_EQ(base::File::FILE_OK,
- AsyncFileTestHelper::Remove(file_system_context(), dir,
- true /* recursive */));
- ASSERT_EQ(0, ComputeTotalFileSize());
- }
- TEST_P(ObfuscatedFileUtilTest, TestQuotaOnOpen) {
- FileSystemURL url(CreateURLFromUTF8("file"));
- bool created;
- // Creating a file.
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(
- AllowUsageIncrease(PathCost(url))->context(), url, &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(0, ComputeTotalFileSize());
- // Opening it, which shouldn't change the usage.
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->EnsureFileExists(AllowUsageIncrease(0)->context(), url, &created));
- ASSERT_EQ(0, ComputeTotalFileSize());
- const int length = 33;
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(length)->context(), url, length));
- ASSERT_EQ(length, ComputeTotalFileSize());
- // TODO(https://crbug.com/936722): After CreateOrOpen is modified to return
- // file error instead of file, the in-memory test can proceed through the next
- // steps.
- if (is_incognito())
- return;
- // Opening it with CREATE_ALWAYS flag, which should truncate the file size.
- base::File file = ofu()->CreateOrOpen(
- AllowUsageIncrease(-length)->context(), url,
- base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
- ASSERT_TRUE(file.IsValid());
- ASSERT_EQ(0, ComputeTotalFileSize());
- file.Close();
- // Extending the file again.
- ASSERT_EQ(
- base::File::FILE_OK,
- ofu()->Truncate(AllowUsageIncrease(length)->context(), url, length));
- ASSERT_EQ(length, ComputeTotalFileSize());
- // Opening it with TRUNCATED flag, which should truncate the file size.
- file = ofu()->CreateOrOpen(
- AllowUsageIncrease(-length)->context(), url,
- base::File::FLAG_OPEN_TRUNCATED | base::File::FLAG_WRITE);
- ASSERT_TRUE(file.IsValid());
- ASSERT_EQ(0, ComputeTotalFileSize());
- file.Close();
- }
- TEST_P(ObfuscatedFileUtilTest, MaybeDropDatabasesAliveCase) {
- MaybeDropDatabasesAliveCaseTestBody();
- }
- TEST_P(ObfuscatedFileUtilTest, MaybeDropDatabasesAlreadyDeletedCase) {
- MaybeDropDatabasesAlreadyDeletedCaseTestBody();
- }
- TEST_P(ObfuscatedFileUtilTest, DestroyDirectoryDatabase_Isolated) {
- DestroyDirectoryDatabase_IsolatedTestBody();
- }
- TEST_P(ObfuscatedFileUtilTest, GetDirectoryDatabase_Isolated) {
- GetDirectoryDatabase_IsolatedTestBody();
- }
- TEST_P(ObfuscatedFileUtilTest, OpenPathInNonDirectory) {
- FileSystemURL url(CreateURLFromUTF8("file"));
- FileSystemURL path_in_file(CreateURLFromUTF8("file/file"));
- bool created;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(UnlimitedContext().get(), url, &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY,
- ofu()->EnsureFileExists(UnlimitedContext().get(), path_in_file,
- &created));
- ASSERT_EQ(
- base::File::FILE_ERROR_NOT_A_DIRECTORY,
- ofu()->CreateDirectory(UnlimitedContext().get(), path_in_file,
- false /* exclusive */, false /* recursive */));
- }
- TEST_P(ObfuscatedFileUtilTest, CreateDirectory_NotADirectoryInRecursive) {
- FileSystemURL file(CreateURLFromUTF8("file"));
- FileSystemURL path_in_file(CreateURLFromUTF8("file/child"));
- FileSystemURL path_in_file_in_file(
- CreateURLFromUTF8("file/child/grandchild"));
- bool created;
- ASSERT_EQ(base::File::FILE_OK,
- ofu()->EnsureFileExists(UnlimitedContext().get(), file, &created));
- ASSERT_TRUE(created);
- ASSERT_EQ(
- base::File::FILE_ERROR_NOT_A_DIRECTORY,
- ofu()->CreateDirectory(UnlimitedContext().get(), path_in_file,
- false /* exclusive */, true /* recursive */));
- ASSERT_EQ(
- base::File::FILE_ERROR_NOT_A_DIRECTORY,
- ofu()->CreateDirectory(UnlimitedContext().get(), path_in_file_in_file,
- false /* exclusive */, true /* recursive */));
- }
- TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForBucketAndType) {
- // Create directories.
- std::unique_ptr<SandboxFileSystemTestHelper> fs1 =
- NewFileSystem(default_bucket_, kFileSystemTypeTemporary);
- std::unique_ptr<SandboxFileSystemTestHelper> fs2 =
- NewFileSystem(default_bucket_, kFileSystemTypePersistent);
- std::unique_ptr<SandboxFileSystemTestHelper> fs3 =
- NewFileSystem(custom_bucket_, kFileSystemTypeTemporary);
- std::unique_ptr<SandboxFileSystemTestHelper> fs4 =
- NewFileSystem(custom_bucket_, kFileSystemTypePersistent);
- // Make sure directories for default_bucket_ exist.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(default_bucket_,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(default_bucket_,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- // Make sure directories for custom_bucket_ exist.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(custom_bucket_,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(custom_bucket_,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- // Delete a directory for default_bucket_'s persistent filesystem.
- ASSERT_TRUE(ofu()->DeleteDirectoryForBucketAndType(
- default_bucket_, kFileSystemTypePersistent));
- // The directory for default_bucket_'s temporary filesystem should not be
- // removed.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(default_bucket_,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- // The directory for default_bucket_'s persistent filesystem should be
- // removed.
- ASSERT_EQ(ofu()
- ->GetDirectoryForBucketAndType(default_bucket_,
- kFileSystemTypePersistent,
- /*create=*/false)
- .error(),
- base::File::FILE_ERROR_NOT_FOUND);
- // The directories for custom_bucket_ should not be removed.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(custom_bucket_,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(custom_bucket_,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- // Deleting directories which don't exist is not an error.
- ASSERT_TRUE(ofu()->DeleteDirectoryForBucketAndType(
- alternate_custom_bucket_, kFileSystemTypePersistent));
- }
- TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForStorageKeyAndType) {
- const blink::StorageKey storage_key1 =
- blink::StorageKey::CreateFromStringForTesting(
- "http://www.example.com:12");
- const blink::StorageKey storage_key2 =
- blink::StorageKey::CreateFromStringForTesting(
- "http://www.example.com:1234");
- const blink::StorageKey storage_key3 =
- blink::StorageKey::CreateFromStringForTesting("http://nope.example.com");
- // Create origin directories.
- std::unique_ptr<SandboxFileSystemTestHelper> fs1 =
- NewFileSystem(storage_key1, kFileSystemTypeTemporary);
- std::unique_ptr<SandboxFileSystemTestHelper> fs2 =
- NewFileSystem(storage_key1, kFileSystemTypePersistent);
- std::unique_ptr<SandboxFileSystemTestHelper> fs3 =
- NewFileSystem(storage_key2, kFileSystemTypeTemporary);
- std::unique_ptr<SandboxFileSystemTestHelper> fs4 =
- NewFileSystem(storage_key2, kFileSystemTypePersistent);
- // Make sure directories for storage_key1 exist.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key1,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key1,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- // Make sure directories for storage_key2 exist.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key2,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key2,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- // Delete a directory for storage_key1's persistent filesystem.
- ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType(
- storage_key1, kFileSystemTypePersistent));
- // The directory for storage_key1's temporary filesystem should not be
- // removed.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key1,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- // The directory for storage_key1's persistent filesystem should be removed.
- ASSERT_EQ(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key1,
- kFileSystemTypePersistent,
- /*create=*/false)
- .error(),
- base::File::FILE_ERROR_NOT_FOUND);
- // The directories for storage_key2 should not be removed.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key2,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key2,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- // Make sure storage_key3's directories don't exist.
- ASSERT_EQ(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key3,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .error(),
- base::File::FILE_ERROR_NOT_FOUND);
- ASSERT_EQ(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key3,
- kFileSystemTypePersistent,
- /*create=*/false)
- .error(),
- base::File::FILE_ERROR_NOT_FOUND);
- // Deleting directories which don't exist is not an error.
- ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType(
- storage_key3, kFileSystemTypeTemporary));
- ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType(
- storage_key3, kFileSystemTypePersistent));
- }
- TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForBucketAndType_DeleteAll) {
- // Create origin directories.
- std::unique_ptr<SandboxFileSystemTestHelper> fs1 =
- NewFileSystem(default_bucket_, kFileSystemTypeTemporary);
- std::unique_ptr<SandboxFileSystemTestHelper> fs2 =
- NewFileSystem(default_bucket_, kFileSystemTypePersistent);
- std::unique_ptr<SandboxFileSystemTestHelper> fs3 =
- NewFileSystem(custom_bucket_, kFileSystemTypeTemporary);
- std::unique_ptr<SandboxFileSystemTestHelper> fs4 =
- NewFileSystem(custom_bucket_, kFileSystemTypePersistent);
- // Make sure directories for default_bucket_ exist.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(default_bucket_,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(default_bucket_,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- // Make sure directories for custom_bucket_ exist.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(custom_bucket_,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(custom_bucket_,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- // Delete all directories for default_bucket_.
- ofu()->DeleteDirectoryForBucketAndType(default_bucket_, absl::nullopt);
- // The directories for default_bucket_ should be removed.
- ASSERT_EQ(ofu()
- ->GetDirectoryForBucketAndType(default_bucket_,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .error(),
- base::File::FILE_ERROR_NOT_FOUND);
- ASSERT_EQ(ofu()
- ->GetDirectoryForBucketAndType(default_bucket_,
- kFileSystemTypePersistent,
- /*create=*/false)
- .error(),
- base::File::FILE_ERROR_NOT_FOUND);
- // The directories for custom_bucket_ should not be removed.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(custom_bucket_,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForBucketAndType(custom_bucket_,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- }
- TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForStorageKeyAndType_DeleteAll) {
- const blink::StorageKey storage_key1 =
- blink::StorageKey::CreateFromStringForTesting(
- "http://www.example.com:12");
- const blink::StorageKey storage_key2 =
- blink::StorageKey::CreateFromStringForTesting(
- "http://www.example.com:1234");
- // Create origin directories.
- std::unique_ptr<SandboxFileSystemTestHelper> fs1 =
- NewFileSystem(storage_key1, kFileSystemTypeTemporary);
- std::unique_ptr<SandboxFileSystemTestHelper> fs2 =
- NewFileSystem(storage_key1, kFileSystemTypePersistent);
- std::unique_ptr<SandboxFileSystemTestHelper> fs3 =
- NewFileSystem(storage_key2, kFileSystemTypeTemporary);
- std::unique_ptr<SandboxFileSystemTestHelper> fs4 =
- NewFileSystem(storage_key2, kFileSystemTypePersistent);
- // Make sure directories for storage_key1 exist.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key1,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key1,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- // Make sure directories for storage_key2 exist.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key2,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key2,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- // Delete all directories for storage_key1.
- ofu()->DeleteDirectoryForStorageKeyAndType(storage_key1, absl::nullopt);
- // The directories for storage_key1 should be removed.
- ASSERT_EQ(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key1,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .error(),
- base::File::FILE_ERROR_NOT_FOUND);
- ASSERT_EQ(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key1,
- kFileSystemTypePersistent,
- /*create=*/false)
- .error(),
- base::File::FILE_ERROR_NOT_FOUND);
- // The directories for storage_key2 should not be removed.
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key2,
- kFileSystemTypeTemporary,
- /*create=*/false)
- .is_error());
- ASSERT_FALSE(ofu()
- ->GetDirectoryForStorageKeyAndType(storage_key2,
- kFileSystemTypePersistent,
- /*create=*/false)
- .is_error());
- }
- } // namespace storage
|