blob: c5a771c9fa3af290d524937b64008128d4fd3de8 [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.
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/fd.h>
#include <lib/procfs/cpp/process.h>
#include <lib/zx/channel.h>
#include <memory>
#include <utility>
#include <fbl/unique_fd.h>
#include <gtest/gtest.h>
#include "src/lib/files/file.h"
namespace {
class ProcessHost {
public:
ProcessHost()
: loop_(&kAsyncLoopConfigNeverAttachToThread),
process_dir_(procfs::CreateProcessDir(loop_.dispatcher())) {
loop_.StartThread("procfs test thread");
}
~ProcessHost() {
loop_.Shutdown();
}
// The returned file descriptor must be closed before the |ProcessHost| is destructed.
fbl::unique_fd Open(uint32_t flags = fuchsia::io::OPEN_RIGHT_READABLE) {
zx::channel client_end, server_end;
zx_status_t status = zx::channel::create(0, &client_end, &server_end);
if (status != ZX_OK) {
return fbl::unique_fd();
}
status = process_dir_->Serve(flags, std::move(server_end), loop_.dispatcher());
if (status != ZX_OK) {
return fbl::unique_fd();
}
fbl::unique_fd fd;
status = fdio_fd_create(client_end.release(), fd.reset_and_get_address());
if (status != ZX_OK) {
return fbl::unique_fd();
}
return fd;
}
private:
async::Loop loop_;
std::unique_ptr<vfs::PseudoDir> process_dir_;
};
TEST(ProcessDir, ReadEnviron) {
ProcessHost host;
auto fd = host.Open();
ASSERT_TRUE(fd.is_valid());
std::string content;
ASSERT_TRUE(files::ReadFileToStringAt(fd.get(), "environ", &content));
EXPECT_EQ(std::string::npos, content.find("THE_TEXT_WE_EXPECT"));
setenv("PROCFS_TEST_VAR", "THE_TEXT_WE_EXPECT", 1);
ASSERT_TRUE(files::ReadFileToStringAt(fd.get(), "environ", &content));
EXPECT_NE(std::string::npos, content.find("THE_TEXT_WE_EXPECT"));
unsetenv("PROCFS_TEST_VAR");
ASSERT_TRUE(files::ReadFileToStringAt(fd.get(), "environ", &content));
EXPECT_EQ(std::string::npos, content.find("THE_TEXT_WE_EXPECT"));
}
TEST(ProcessDir, CurrentWorkingDirectory) {
ProcessHost host;
auto fd = host.Open();
ASSERT_TRUE(fd.is_valid());
char buffer[PATH_MAX];
getcwd(buffer, sizeof(buffer));
ASSERT_EQ(0, chdir("/pkg/test"));
fbl::unique_fd cwd(openat(fd.get(), "cwd", O_DIRECTORY | O_RDONLY));
ASSERT_TRUE(cwd.is_valid());
fbl::unique_fd probe(openat(cwd.get(), "procfs_cpp_unittests", O_RDONLY));
ASSERT_TRUE(probe.is_valid());
ASSERT_EQ(0, chdir("/pkg/lib"));
probe.reset(openat(cwd.get(), "procfs_cpp_unittests", O_DIRECTORY | O_RDONLY));
ASSERT_FALSE(probe.is_valid());
ASSERT_EQ(0, chdir(buffer));
}
} // namespace