blob: c9cce2cb48d88831cd70b9dd6a6072a3c916c9de [file] [log] [blame]
// Copyright 2019 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 <fuchsia/io/cpp/fidl.h>
#include <lib/vfs/cpp/testing/dir_test_util.h>
namespace vfs_tests {
Dirent Dirent::DirentForDot() { return DirentForDirectory("."); }
Dirent Dirent::DirentForDirectory(const std::string& name) {
return Dirent(fuchsia::io::INO_UNKNOWN, fuchsia::io::DIRENT_TYPE_DIRECTORY, name);
}
Dirent Dirent::DirentForFile(const std::string& name) {
return Dirent(fuchsia::io::INO_UNKNOWN, fuchsia::io::DIRENT_TYPE_FILE, name);
}
Dirent Dirent::DirentForService(const std::string& name) {
return Dirent(fuchsia::io::INO_UNKNOWN, fuchsia::io::DIRENT_TYPE_SERVICE, name);
}
std::string Dirent::String() {
return "Dirent:\nino: " + std ::to_string(ino_) + "\ntype: " + std ::to_string(type_) +
"\nsize: " + std ::to_string(size_) + "\nname: " + name_;
}
Dirent::Dirent(uint64_t ino, uint8_t type, const std::string& name)
: ino_(ino),
type_(type),
size_(static_cast<uint8_t>(name.length())),
name_(name),
size_in_bytes_(sizeof(vdirent_t) + size_) {
ZX_DEBUG_ASSERT(name.length() <= static_cast<uint64_t>(NAME_MAX));
}
void DirConnection::AssertOpen(async_dispatcher_t* dispatcher, uint32_t flags,
zx_status_t expected_status, bool test_on_open_event) {
fuchsia::io::NodePtr node_ptr;
if (test_on_open_event) {
flags |= fuchsia::io::OPEN_FLAG_DESCRIBE;
}
EXPECT_EQ(expected_status,
GetDirectoryNode()->Serve(flags, node_ptr.NewRequest().TakeChannel(), dispatcher));
if (test_on_open_event) {
bool on_open_called = false;
node_ptr.events().OnOpen = [&](zx_status_t status,
std::unique_ptr<fuchsia::io::NodeInfo> info) {
EXPECT_FALSE(on_open_called); // should be called only once
on_open_called = true;
EXPECT_EQ(expected_status, status);
if (expected_status == ZX_OK) {
ASSERT_NE(info.get(), nullptr);
EXPECT_TRUE(info->is_directory());
} else {
EXPECT_EQ(info.get(), nullptr);
}
};
RunLoopUntil([&]() { return on_open_called; }, zx::msec(1));
}
}
void DirConnection::AssertReadDirents(fuchsia::io::DirectorySyncPtr& ptr, uint64_t max_bytes,
std::vector<Dirent>& expected_dirents,
zx_status_t expected_status) {
std::vector<uint8_t> out_dirents;
zx_status_t status;
ptr->ReadDirents(max_bytes, &status, &out_dirents);
ASSERT_EQ(expected_status, status);
if (status != ZX_OK) {
return;
}
uint64_t expected_size = 0;
for (auto& d : expected_dirents) {
expected_size += d.size_in_bytes();
}
EXPECT_EQ(expected_size, out_dirents.size());
uint64_t offset = 0;
auto data_ptr = out_dirents.data();
for (auto& d : expected_dirents) {
SCOPED_TRACE(d.String());
ASSERT_LE(sizeof(vdirent_t), out_dirents.size() - offset);
vdirent_t* de = reinterpret_cast<vdirent_t*>(data_ptr + offset);
uint64_t ino;
memcpy(&ino, &de->ino, sizeof(ino));
EXPECT_EQ(d.ino(), ino);
uint8_t size, type;
memcpy(&size, &de->size, sizeof(size));
EXPECT_EQ(d.size(), size);
memcpy(&type, &de->type, sizeof(type));
EXPECT_EQ(d.type(), type);
ASSERT_LE(d.size_in_bytes(), out_dirents.size() - offset);
EXPECT_EQ(d.name(), std::string(de->name, size));
offset += sizeof(vdirent_t) + size;
}
}
void DirConnection::AssertRewind(fuchsia::io::DirectorySyncPtr& ptr, zx_status_t expected_status) {
zx_status_t status;
ptr->Rewind(&status);
ASSERT_EQ(expected_status, status);
}
void DirConnection::AssertRead(fuchsia::io::FileSyncPtr& file, int count,
const std::string& expected_str, zx_status_t expected_status) {
zx_status_t status;
std::vector<uint8_t> buffer;
file->Read(count, &status, &buffer);
ASSERT_EQ(expected_status, status);
std::string str(buffer.size(), 0);
std::copy(buffer.begin(), buffer.end(), str.begin());
ASSERT_EQ(expected_str, str);
}
} // namespace vfs_tests