blob: c5d0e2dc1ff55abfc3877fc309f676c242b80586 [file] [log] [blame]
// Copyright 2017 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.
#include "src/modular/lib/pseudo_dir/pseudo_dir_server.h"
#include <lib/fdio/directory.h>
#include <lib/gtest/real_loop_fixture.h>
#include <lib/vfs/cpp/pseudo_dir.h>
#include <lib/vfs/cpp/service.h>
#include <gtest/gtest.h>
#include <src/lib/files/directory.h>
#include <src/lib/files/file.h>
#include <src/modular/lib/pseudo_dir/pseudo_dir_utils.h>
namespace modular {
namespace {
class PseudoDirServerTest : public gtest::RealLoopFixture {};
// Test that |PseudoDirServer::OpenAt| gives you an FD can be used on the same
// thread as |PseudoDirServer|.
TEST_F(PseudoDirServerTest, OpenAt) {
constexpr char kContents[] = "file contents";
modular::PseudoDirServer server(MakeFilePathWithContents("a/b/c", kContents));
{
// Paths with leading '/' don't work.
fbl::unique_fd fd = server.OpenAt("/a");
EXPECT_FALSE(fd.is_valid());
}
{
// 'x' doesn't exist, so not valid.
fbl::unique_fd fd = server.OpenAt("x");
EXPECT_FALSE(fd.is_valid());
}
{
fbl::unique_fd fd = server.OpenAt("a");
EXPECT_TRUE(fd.is_valid());
}
{
fbl::unique_fd fd = server.OpenAt("a/b");
EXPECT_TRUE(fd.is_valid());
}
{
fbl::unique_fd fd = server.OpenAt("a/b/c");
EXPECT_TRUE(fd.is_valid());
std::string contents;
ASSERT_TRUE(files::ReadFileDescriptorToString(fd.get(), &contents));
EXPECT_EQ(kContents, contents);
}
}
// Test that |PseudoDirServer::Serve| serves a directory which doesn't block the
// current thread. Test this by using thread-blocking POSIX apis.
TEST_F(PseudoDirServerTest, Serve) {
constexpr char kFileName[] = "file_name";
constexpr char kContents[] = "file contents";
modular::PseudoDirServer server(MakeFilePathWithContents(kFileName, kContents));
auto dir_fd = fsl::OpenChannelAsFileDescriptor(server.Serve().Unbind().TakeChannel());
std::string contents;
ASSERT_TRUE(files::ReadFileToStringAt(dir_fd.get(), kFileName, &contents));
EXPECT_EQ(kContents, contents);
}
// Test that |PseudoDirServer::Serve| serves a directory that contains a service.
TEST_F(PseudoDirServerTest, ServeService) {
constexpr char kServiceName[] = "service_name";
bool svc_requested = false;
auto svc_dir = std::make_unique<vfs::PseudoDir>();
svc_dir->AddEntry(kServiceName,
std::make_unique<vfs::Service>(
[&svc_requested](zx::channel request, async_dispatcher_t* dispatcher) {
svc_requested = true;
}));
modular::PseudoDirServer server(std::move(svc_dir));
auto dir = server.Serve().Unbind().TakeChannel();
fuchsia::io::NodePtr node;
fdio_service_connect_at(dir.get(), kServiceName, node.NewRequest().TakeChannel().release());
RunLoopUntil([&] { return svc_requested; });
}
} // namespace
} // namespace modular