FileSystemParentTestHelpers.cpp (5589B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "FileSystemParentTestHelpers.h" 8 9 #include <algorithm> 10 11 #include "FileSystemParentTypes.h" 12 #include "TestHelpers.h" 13 #include "datamodel/FileSystemDataManager.h" 14 #include "datamodel/FileSystemDatabaseManager.h" 15 #include "gtest/gtest.h" 16 #include "mozilla/Result.h" 17 #include "mozilla/SpinEventLoopUntil.h" 18 #include "mozilla/dom/QMResult.h" 19 #include "mozilla/dom/quota/Client.h" 20 #include "mozilla/dom/quota/FileStreams.h" 21 #include "mozilla/dom/quota/ResultExtensions.h" 22 #include "mozilla/dom/quota/UsageInfo.h" 23 #include "nsIFile.h" 24 #include "nsString.h" 25 26 namespace mozilla::dom::fs::test { 27 28 namespace { 29 30 const int sPage = 64 * 512; 31 32 // ExceedsPreallocation value may depend on platform and sqlite version! 33 const int sExceedsPreallocation = sPage; 34 35 } // namespace 36 37 int GetPageSize() { return sPage; } 38 39 const Name& GetTestFileName() { 40 static Name testFileName = []() { 41 nsCString testCFileName; 42 testCFileName.SetLength(sExceedsPreallocation); 43 std::fill(testCFileName.BeginWriting(), testCFileName.EndWriting(), 'x'); 44 return NS_ConvertASCIItoUTF16(testCFileName.BeginReading(), 45 sExceedsPreallocation); 46 }(); 47 48 return testFileName; 49 } 50 51 uint64_t BytesOfName(const Name& aName) { 52 return static_cast<uint64_t>(aName.Length() * sizeof(Name::char_type)); 53 } 54 55 const nsCString& GetTestData() { 56 static const nsCString sTestData = "There is a way out of every box"_ns; 57 return sTestData; 58 } 59 60 void CreateNewEmptyFile(data::FileSystemDatabaseManager* const aDatabaseManager, 61 const FileSystemChildMetadata& aFileSlot, 62 EntryId& aEntryId) { 63 // The file should not exist yet 64 Result<EntryId, QMResult> existingTestFile = 65 aDatabaseManager->GetOrCreateFile(aFileSlot, /* create */ false); 66 ASSERT_TRUE(existingTestFile.isErr()); 67 ASSERT_NSEQ(NS_ERROR_DOM_NOT_FOUND_ERR, 68 ToNSResult(existingTestFile.unwrapErr())); 69 70 // Create a new file 71 TEST_TRY_UNWRAP(aEntryId, aDatabaseManager->GetOrCreateFile( 72 aFileSlot, /* create */ true)); 73 } 74 75 void WriteDataToFile(const quota::OriginMetadata& aOriginMetadata, 76 data::FileSystemDatabaseManager* const aDatabaseManager, 77 const EntryId& aEntryId, const nsCString& aData) { 78 TEST_TRY_UNWRAP(FileId fileId, aDatabaseManager->EnsureFileId(aEntryId)); 79 ASSERT_FALSE(fileId.IsEmpty()); 80 81 ContentType type; 82 TimeStamp lastModMilliS = 0; 83 Path path; 84 nsCOMPtr<nsIFile> fileObj; 85 ASSERT_NSEQ(NS_OK, 86 aDatabaseManager->GetFile(aEntryId, fileId, FileMode::EXCLUSIVE, 87 type, lastModMilliS, path, fileObj)); 88 89 uint32_t written = 0; 90 ASSERT_NE(written, aData.Length()); 91 92 TEST_TRY_UNWRAP(nsCOMPtr<nsIOutputStream> fileStream, 93 quota::CreateFileOutputStream( 94 quota::PERSISTENCE_TYPE_DEFAULT, aOriginMetadata, 95 quota::Client::FILESYSTEM, fileObj)); 96 97 auto finallyClose = MakeScopeExit( 98 [&fileStream]() { ASSERT_NSEQ(NS_OK, fileStream->Close()); }); 99 ASSERT_NSEQ(NS_OK, fileStream->Write(aData.get(), aData.Length(), &written)); 100 101 ASSERT_EQ(aData.Length(), written); 102 } 103 104 void CreateRegisteredDataManager( 105 const quota::OriginMetadata& aOriginMetadata, 106 Registered<data::FileSystemDataManager>& aRegisteredDataManager) { 107 bool done = false; 108 109 data::FileSystemDataManager::GetOrCreateFileSystemDataManager(aOriginMetadata) 110 ->Then( 111 GetCurrentSerialEventTarget(), __func__, 112 [&aRegisteredDataManager, 113 &done](Registered<data::FileSystemDataManager> 114 registeredDataManager) mutable { 115 auto doneOnReturn = MakeScopeExit([&done]() { done = true; }); 116 117 ASSERT_TRUE(registeredDataManager->IsOpen()); 118 aRegisteredDataManager = std::move(registeredDataManager); 119 }, 120 [&done](nsresult rejectValue) { 121 auto doneOnReturn = MakeScopeExit([&done]() { done = true; }); 122 123 ASSERT_NSEQ(NS_OK, rejectValue); 124 }); 125 126 SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; }); 127 128 ASSERT_TRUE(aRegisteredDataManager); 129 ASSERT_TRUE(aRegisteredDataManager->IsOpen()); 130 ASSERT_TRUE(aRegisteredDataManager->MutableDatabaseManagerPtr()); 131 } 132 133 void GetUsageValue(const quota::UsageInfo& aUsage, uint64_t& aValue) { 134 auto dbUsage = aUsage.DatabaseUsage(); 135 ASSERT_TRUE(dbUsage.isSome()); 136 aValue = dbUsage.value(); 137 } 138 139 void CheckUsageIsNothing(const quota::UsageInfo& aUsage) { 140 EXPECT_TRUE(aUsage.FileUsage().isNothing()); 141 auto dbUsage = aUsage.DatabaseUsage(); 142 ASSERT_TRUE(dbUsage.isNothing()); 143 } 144 145 void CheckUsageEqualTo(const quota::UsageInfo& aUsage, uint64_t aExpected) { 146 EXPECT_TRUE(aUsage.FileUsage().isNothing()); 147 auto dbUsage = aUsage.DatabaseUsage(); 148 ASSERT_TRUE(dbUsage.isSome()); 149 const auto actual = dbUsage.value(); 150 ASSERT_EQ(actual, aExpected); 151 } 152 153 void CheckUsageGreaterThan(const quota::UsageInfo& aUsage, uint64_t aExpected) { 154 EXPECT_TRUE(aUsage.FileUsage().isNothing()); 155 auto dbUsage = aUsage.DatabaseUsage(); 156 ASSERT_TRUE(dbUsage.isSome()); 157 const auto actual = dbUsage.value(); 158 ASSERT_GT(actual, aExpected); 159 } 160 161 } // namespace mozilla::dom::fs::test