blob: b6da892d2bd130f6a416d5877650b787b0b8edd0 [file] [log] [blame]
// 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_