| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_LIB_LOADER_SERVICE_LOADER_SERVICE_TEST_FIXTURE_H_ |
| #define SRC_LIB_LOADER_SERVICE_LOADER_SERVICE_TEST_FIXTURE_H_ |
| |
| #include <fuchsia/ldsvc/llcpp/fidl.h> |
| #include <lib/async-loop/cpp/loop.h> |
| #include <lib/async-loop/default.h> |
| #include <lib/memfs/cpp/vnode.h> |
| #include <lib/zx/resource.h> |
| |
| #include <memory> |
| #include <vector> |
| |
| #include <fbl/ref_ptr.h> |
| #include <fbl/unique_fd.h> |
| #include <gtest/gtest.h> |
| |
| #include "src/lib/loader_service/loader_service.h" |
| #include "src/lib/testing/loop_fixture/real_loop_fixture.h" |
| |
| namespace loader { |
| namespace test { |
| |
| struct TestDirectoryEntry { |
| std::string path; |
| std::string file_contents; |
| bool executable; |
| |
| TestDirectoryEntry(std::string path, std::string file_contents, bool executable) |
| : path(std::move(path)), file_contents(std::move(file_contents)), executable(executable) {} |
| }; |
| |
| class LoaderServiceTest : public gtest::RealLoopFixture { |
| public: |
| LoaderServiceTest() |
| : fs_loop_(&kAsyncLoopConfigNoAttachToCurrentThread), |
| loader_loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {} |
| |
| virtual void TearDown() override; |
| |
| // Either this or CreateTestDirectory should only be called once per test case. This would be in |
| // SetUp but we want to allow test defined directory contents. |
| template <typename T> |
| void CreateTestLoader(std::vector<TestDirectoryEntry> config, std::shared_ptr<T>* loader) { |
| fbl::unique_fd root_fd; |
| ASSERT_NO_FATAL_FAILURE(CreateTestDirectory(std::move(config), &root_fd)); |
| const ::testing::TestInfo* const test_info = |
| ::testing::UnitTest::GetInstance()->current_test_info(); |
| *loader = T::Create(loader_loop_.dispatcher(), std::move(root_fd), test_info->name()); |
| } |
| |
| // Either this or CreateTestLoader should only be called once per test case. This would be in |
| // SetUp but we want to allow test defined directory contents. |
| void CreateTestDirectory(std::vector<TestDirectoryEntry> config, fbl::unique_fd* root_fd); |
| |
| // Add a directory entry to the given VnodeDir. Can be used to add entries mid-test case using |
| // root_dir() below. |
| void AddDirectoryEntry(const fbl::RefPtr<memfs::VnodeDir>& root, TestDirectoryEntry entry); |
| |
| // Exercise a LoadObject call and assert that the result matches `expected`. |
| // |
| // This takes a non-const reference because LLCPP SyncClient's generated methods are non-const. |
| void LoadObject(llcpp::fuchsia::ldsvc::Loader::SyncClient& client, std::string name, |
| zx::status<std::string> expected); |
| |
| // Exercise a Config call and assert that the result matches `expected`. |
| // |
| // This takes a non-const reference because LLCPP SyncClient's generated methods are non-const. |
| void Config(llcpp::fuchsia::ldsvc::Loader::SyncClient& client, std::string config, |
| zx::status<zx_status_t> expected); |
| |
| // Helper function to interact with fuchsia.kernel.VmexResource |
| static zx::status<zx::unowned_resource> GetVmexResource(); |
| |
| async::Loop& fs_loop() { return fs_loop_; } |
| async::Loop& loader_loop() { return loader_loop_; } |
| fbl::RefPtr<memfs::VnodeDir>& root_dir() { return root_dir_; } |
| |
| private: |
| async::Loop fs_loop_; |
| async::Loop loader_loop_; |
| std::unique_ptr<memfs::Vfs> vfs_; |
| fbl::RefPtr<memfs::VnodeDir> root_dir_; |
| }; |
| |
| } // namespace test |
| } // namespace loader |
| |
| #endif // SRC_LIB_LOADER_SERVICE_LOADER_SERVICE_TEST_FIXTURE_H_ |