diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /dom/fs/test/gtest/child/TestFileSystemRequestHandler.cpp | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/fs/test/gtest/child/TestFileSystemRequestHandler.cpp')
-rw-r--r-- | dom/fs/test/gtest/child/TestFileSystemRequestHandler.cpp | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/dom/fs/test/gtest/child/TestFileSystemRequestHandler.cpp b/dom/fs/test/gtest/child/TestFileSystemRequestHandler.cpp new file mode 100644 index 0000000000..c2832103af --- /dev/null +++ b/dom/fs/test/gtest/child/TestFileSystemRequestHandler.cpp @@ -0,0 +1,352 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "FileSystemBackgroundRequestHandler.h" +#include "FileSystemEntryMetadataArray.h" +#include "FileSystemMocks.h" +#include "fs/FileSystemRequestHandler.h" +#include "gtest/gtest.h" +#include "mozilla/SpinEventLoopUntil.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/dom/FileBlobImpl.h" +#include "mozilla/dom/FileSystemManager.h" +#include "mozilla/dom/FileSystemManagerChild.h" +#include "mozilla/dom/IPCBlob.h" +#include "mozilla/dom/IPCBlobUtils.h" +#include "mozilla/dom/PFileSystemManager.h" +#include "mozilla/dom/StorageManager.h" +#include "mozilla/ipc/FileDescriptorUtils.h" +#include "mozilla/ipc/IPCCore.h" +#include "nsDirectoryServiceDefs.h" +#include "nsIFile.h" + +using ::testing::_; +using ::testing::ByRef; +using ::testing::Invoke; +using ::testing::Return; + +namespace mozilla::dom::fs::test { + +class TestFileSystemRequestHandler : public ::testing::Test { + protected: + void SetUp() override { + mListener = MakeAndAddRef<ExpectResolveCalled>(); + + mChild = FileSystemChildMetadata("parent"_ns, u"ChildName"_ns); + mEntry = FileSystemEntryMetadata("myid"_ns, u"EntryName"_ns, + /* directory */ false); + mName = u"testDir"_ns; + mFileSystemManagerChild = MakeAndAddRef<TestFileSystemManagerChild>(); + mManager = MakeAndAddRef<FileSystemManager>( + mGlobal, nullptr, + MakeRefPtr<FileSystemBackgroundRequestHandler>( + mFileSystemManagerChild)); + } + + void TearDown() override { + if (!mManager->IsShutdown()) { + EXPECT_NO_FATAL_FAILURE(ShutdownFileSystemManager()); + } + } + + already_AddRefed<Promise> GetDefaultPromise() { + IgnoredErrorResult rv; + RefPtr<Promise> result = Promise::Create(mGlobal, rv); + mListener->ClearDone(); + result->AppendNativeHandler(mListener->AsHandler()); + + return result.forget(); + } + + already_AddRefed<Promise> GetSimplePromise() { + IgnoredErrorResult rv; + RefPtr<Promise> result = Promise::Create(mGlobal, rv); + + return result.forget(); + } + + already_AddRefed<Promise> GetShutdownPromise() { + RefPtr<Promise> promise = GetDefaultPromise(); + EXPECT_CALL(*mFileSystemManagerChild, Shutdown()) + .WillOnce(Invoke([promise]() { promise->MaybeResolveWithUndefined(); })) + .WillOnce(Return()); + EXPECT_CALL(mListener->GetSuccessHandler(), InvokeMe()); + + return promise.forget(); + } + + UniquePtr<FileSystemRequestHandler> GetFileSystemRequestHandler() { + return MakeUnique<FileSystemRequestHandler>(); + } + + void ShutdownFileSystemManager() { + RefPtr<Promise> promise = GetShutdownPromise(); + + mManager->Shutdown(); + + SpinEventLoopUntil("Promise is fulfilled or timeout"_ns, + [this]() { return mListener->IsDone(); }); + ASSERT_TRUE(mManager->IsShutdown()); + } + + nsIGlobalObject* mGlobal = GetGlobal(); + RefPtr<ExpectResolveCalled> mListener; + + FileSystemChildMetadata mChild; + FileSystemEntryMetadata mEntry; + nsString mName; + RefPtr<TestFileSystemManagerChild> mFileSystemManagerChild; + RefPtr<FileSystemManager> mManager; +}; + +TEST_F(TestFileSystemRequestHandler, isGetRootHandleSuccessful) { + auto fakeResponse = [](auto&& aResolve, auto&& /* aReject */) { + EntryId expected = "expected"_ns; + FileSystemGetHandleResponse response(expected); + aResolve(std::move(response)); + }; + + EXPECT_CALL(mListener->GetSuccessHandler(), InvokeMe()); + EXPECT_CALL(*mFileSystemManagerChild, SendGetRootHandle(_, _)) + .WillOnce(Invoke(fakeResponse)); + + RefPtr<Promise> promise = GetDefaultPromise(); + auto testable = GetFileSystemRequestHandler(); + testable->GetRootHandle(mManager, promise, IgnoredErrorResult()); + SpinEventLoopUntil("Promise is fulfilled or timeout"_ns, + [this]() { return mListener->IsDone(); }); +} + +TEST_F(TestFileSystemRequestHandler, isGetRootHandleBlockedAfterShutdown) { + ASSERT_NO_FATAL_FAILURE(ShutdownFileSystemManager()); + + IgnoredErrorResult error; + GetFileSystemRequestHandler()->GetRootHandle(mManager, GetSimplePromise(), + error); + + ASSERT_TRUE(error.Failed()); + ASSERT_TRUE(error.ErrorCodeIs(NS_ERROR_ILLEGAL_DURING_SHUTDOWN)); +} + +TEST_F(TestFileSystemRequestHandler, isGetDirectoryHandleSuccessful) { + auto fakeResponse = [](const auto& /* aRequest */, auto&& aResolve, + auto&& /* aReject */) { + EntryId expected = "expected"_ns; + FileSystemGetHandleResponse response(expected); + aResolve(std::move(response)); + }; + + EXPECT_CALL(mListener->GetSuccessHandler(), InvokeMe()); + EXPECT_CALL(*mFileSystemManagerChild, SendGetDirectoryHandle(_, _, _)) + .WillOnce(Invoke(fakeResponse)); + + RefPtr<Promise> promise = GetDefaultPromise(); + auto testable = GetFileSystemRequestHandler(); + testable->GetDirectoryHandle(mManager, mChild, + /* create */ true, promise, + IgnoredErrorResult()); + SpinEventLoopUntil("Promise is fulfilled or timeout"_ns, + [this]() { return mListener->IsDone(); }); +} + +TEST_F(TestFileSystemRequestHandler, isGetDirectoryHandleBlockedAfterShutdown) { + ASSERT_NO_FATAL_FAILURE(ShutdownFileSystemManager()); + + IgnoredErrorResult error; + GetFileSystemRequestHandler()->GetDirectoryHandle( + mManager, mChild, /* aCreate */ true, GetSimplePromise(), error); + + ASSERT_TRUE(error.Failed()); + ASSERT_TRUE(error.ErrorCodeIs(NS_ERROR_ILLEGAL_DURING_SHUTDOWN)); +} + +TEST_F(TestFileSystemRequestHandler, isGetFileHandleSuccessful) { + auto fakeResponse = [](const auto& /* aRequest */, auto&& aResolve, + auto&& /* aReject */) { + EntryId expected = "expected"_ns; + FileSystemGetHandleResponse response(expected); + aResolve(std::move(response)); + }; + + EXPECT_CALL(mListener->GetSuccessHandler(), InvokeMe()); + EXPECT_CALL(*mFileSystemManagerChild, SendGetFileHandle(_, _, _)) + .WillOnce(Invoke(fakeResponse)); + + RefPtr<Promise> promise = GetDefaultPromise(); + auto testable = GetFileSystemRequestHandler(); + testable->GetFileHandle(mManager, mChild, /* create */ true, promise, + IgnoredErrorResult()); + SpinEventLoopUntil("Promise is fulfilled or timeout"_ns, + [this]() { return mListener->IsDone(); }); +} + +TEST_F(TestFileSystemRequestHandler, isGetFileHandleBlockedAfterShutdown) { + ASSERT_NO_FATAL_FAILURE(ShutdownFileSystemManager()); + + IgnoredErrorResult error; + GetFileSystemRequestHandler()->GetFileHandle( + mManager, mChild, /* aCreate */ true, GetSimplePromise(), error); + + ASSERT_TRUE(error.Failed()); + ASSERT_TRUE(error.ErrorCodeIs(NS_ERROR_ILLEGAL_DURING_SHUTDOWN)); +} + +TEST_F(TestFileSystemRequestHandler, isGetFileSuccessful) { + auto fakeResponse = [](const auto& /* aRequest */, auto&& aResolve, + auto&& /* aReject */) { + // We have to create a temporary file + nsCOMPtr<nsIFile> tmpfile; + nsresult rv = + NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpfile)); + ASSERT_EQ(NS_SUCCEEDED(rv), true); + + rv = tmpfile->AppendNative("GetFileTestBlob"_ns); + ASSERT_EQ(NS_SUCCEEDED(rv), true); + + rv = tmpfile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0666); + ASSERT_EQ(NS_SUCCEEDED(rv), true); + + auto blob = MakeRefPtr<FileBlobImpl>(tmpfile); + + TimeStamp last_modified_ms = 0; + ContentType type = "txt"_ns; + IPCBlob file; + IPCBlobUtils::Serialize(blob, file); + + nsTArray<Name> path; + path.AppendElement(u"root"_ns); + path.AppendElement(u"Trash"_ns); + + FileSystemFileProperties properties(last_modified_ms, file, type, path); + FileSystemGetFileResponse response(properties); + aResolve(std::move(response)); + }; + + EXPECT_CALL(mListener->GetSuccessHandler(), InvokeMe()); + EXPECT_CALL(*mFileSystemManagerChild, SendGetFile(_, _, _)) + .WillOnce(Invoke(fakeResponse)); + + RefPtr<Promise> promise = GetDefaultPromise(); + auto testable = GetFileSystemRequestHandler(); + testable->GetFile(mManager, mEntry, promise, IgnoredErrorResult()); + SpinEventLoopUntil("Promise is fulfilled or timeout"_ns, + [this]() { return mListener->IsDone(); }); +} + +TEST_F(TestFileSystemRequestHandler, isGetFileBlockedAfterShutdown) { + ASSERT_NO_FATAL_FAILURE(ShutdownFileSystemManager()); + + IgnoredErrorResult error; + GetFileSystemRequestHandler()->GetFile(mManager, mEntry, GetSimplePromise(), + error); + + ASSERT_TRUE(error.Failed()); + ASSERT_TRUE(error.ErrorCodeIs(NS_ERROR_ILLEGAL_DURING_SHUTDOWN)); +} + +TEST_F(TestFileSystemRequestHandler, isGetAccessHandleBlockedAfterShutdown) { + RefPtr<Promise> promise = GetShutdownPromise(); + + mManager->Shutdown(); + + SpinEventLoopUntil("Promise is fulfilled or timeout"_ns, + [this]() { return mListener->IsDone(); }); + ASSERT_TRUE(mManager->IsShutdown()); + + IgnoredErrorResult error; + GetFileSystemRequestHandler()->GetAccessHandle(mManager, mEntry, + GetSimplePromise(), error); + + ASSERT_TRUE(error.Failed()); + ASSERT_TRUE(error.ErrorCodeIs(NS_ERROR_ILLEGAL_DURING_SHUTDOWN)); +} + +TEST_F(TestFileSystemRequestHandler, isGetWritableBlockedAfterShutdown) { + ASSERT_NO_FATAL_FAILURE(ShutdownFileSystemManager()); + + IgnoredErrorResult error; + GetFileSystemRequestHandler()->GetWritable( + mManager, mEntry, /* aKeepData */ false, GetSimplePromise(), error); + + ASSERT_TRUE(error.Failed()); + ASSERT_TRUE(error.ErrorCodeIs(NS_ERROR_ILLEGAL_DURING_SHUTDOWN)); +} + +TEST_F(TestFileSystemRequestHandler, isGetEntriesSuccessful) { + auto fakeResponse = [](const auto& /* aRequest */, auto&& aResolve, + auto&& /* aReject */) { + nsTArray<FileSystemEntryMetadata> files; + nsTArray<FileSystemEntryMetadata> directories; + FileSystemDirectoryListing listing(files, directories); + FileSystemGetEntriesResponse response(listing); + aResolve(std::move(response)); + }; + + RefPtr<ExpectResolveCalled> listener = MakeAndAddRef<ExpectResolveCalled>(); + IgnoredErrorResult rv; + listener->ClearDone(); + EXPECT_CALL(listener->GetSuccessHandler(), InvokeMe()); + + RefPtr<Promise> promise = Promise::Create(mGlobal, rv); + promise->AppendNativeHandler(listener); + + EXPECT_CALL(*mFileSystemManagerChild, SendGetEntries(_, _, _)) + .WillOnce(Invoke(fakeResponse)); + + auto testable = GetFileSystemRequestHandler(); + RefPtr<FileSystemEntryMetadataArray> sink; + + testable->GetEntries(mManager, mEntry.entryId(), /* page */ 0, promise, sink, + IgnoredErrorResult()); + SpinEventLoopUntil("Promise is fulfilled or timeout"_ns, + [listener]() { return listener->IsDone(); }); +} + +TEST_F(TestFileSystemRequestHandler, isGetEntriesBlockedAfterShutdown) { + ASSERT_NO_FATAL_FAILURE(ShutdownFileSystemManager()); + + RefPtr<FileSystemEntryMetadataArray> sink; + + IgnoredErrorResult error; + GetFileSystemRequestHandler()->GetEntries(mManager, mEntry.entryId(), + /* aPage */ 0, GetSimplePromise(), + sink, error); + + ASSERT_TRUE(error.Failed()); + ASSERT_TRUE(error.ErrorCodeIs(NS_ERROR_ILLEGAL_DURING_SHUTDOWN)); +} + +TEST_F(TestFileSystemRequestHandler, isRemoveEntrySuccessful) { + auto fakeResponse = [](const auto& /* aRequest */, auto&& aResolve, + auto&& /* aReject */) { + FileSystemRemoveEntryResponse response(mozilla::void_t{}); + aResolve(std::move(response)); + }; + + EXPECT_CALL(mListener->GetSuccessHandler(), InvokeMe()); + EXPECT_CALL(*mFileSystemManagerChild, SendRemoveEntry(_, _, _)) + .WillOnce(Invoke(fakeResponse)); + + auto testable = GetFileSystemRequestHandler(); + RefPtr<Promise> promise = GetDefaultPromise(); + testable->RemoveEntry(mManager, mChild, /* recursive */ true, promise, + IgnoredErrorResult()); + SpinEventLoopUntil("Promise is fulfilled or timeout"_ns, + [this]() { return mListener->IsDone(); }); +} + +TEST_F(TestFileSystemRequestHandler, isRemoveEntryBlockedAfterShutdown) { + ASSERT_NO_FATAL_FAILURE(ShutdownFileSystemManager()); + + IgnoredErrorResult error; + GetFileSystemRequestHandler()->RemoveEntry( + mManager, mChild, /* aRecursive */ true, GetSimplePromise(), error); + + ASSERT_TRUE(error.Failed()); + ASSERT_TRUE(error.ErrorCodeIs(NS_ERROR_ILLEGAL_DURING_SHUTDOWN)); +} + +} // namespace mozilla::dom::fs::test |