blob: 79da778c2d5a8029693b196817ce69d33a4338ef [file] [log] [blame]
// Copyright 2018 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 <utility>
#include <fbl/vector.h>
#include <zxtest/zxtest.h>
#include "src/lib/storage/vfs/cpp/dir_test_util.h"
#include "src/lib/storage/vfs/cpp/lazy_dir.h"
#include "src/lib/storage/vfs/cpp/pseudo_file.h"
#include "src/lib/storage/vfs/cpp/vfs.h"
namespace {
class TestLazyDirHelper : public fs::LazyDir {
public:
struct TestContent {
uint64_t id;
fbl::String name;
};
void GetContents(LazyEntryVector* out_vector) override {
out_vector->reserve(contents_.size());
for (const auto& content : contents_) {
out_vector->push_back({content.id, content.name, V_TYPE_FILE});
}
}
zx_status_t GetFile(fbl::RefPtr<fs::Vnode>* out, uint64_t id, fbl::String name) override {
last_output_file = fbl::MakeRefCounted<fs::UnbufferedPseudoFile>();
*out = last_output_file;
last_id = id;
last_name = name;
return ZX_OK;
}
void AddContent(TestContent content) { contents_.push_back(std::move(content)); }
fbl::RefPtr<fs::Vnode> last_output_file;
uint64_t last_id;
fbl::String last_name;
private:
fbl::Vector<TestContent> contents_;
};
TEST(LazyDir, ApiTest) {
TestLazyDirHelper test;
{
fs::VdirCookie cookie;
uint8_t buffer[4096];
size_t len;
EXPECT_EQ(test.Readdir(&cookie, buffer, sizeof(buffer), &len), ZX_OK);
fs::DirentChecker dc(buffer, len);
dc.ExpectEntry(".", V_TYPE_DIR);
dc.ExpectEnd();
}
test.AddContent({1, "test"});
{
fs::VdirCookie cookie;
uint8_t buffer[4096];
size_t len;
EXPECT_EQ(test.Readdir(&cookie, buffer, sizeof(buffer), &len), ZX_OK);
fs::DirentChecker dc(buffer, len);
dc.ExpectEntry(".", V_TYPE_DIR);
dc.ExpectEntry("test", V_TYPE_FILE);
dc.ExpectEnd();
fbl::RefPtr<fs::Vnode> out;
EXPECT_EQ(test.Lookup("test", &out), ZX_OK);
EXPECT_EQ(1, test.last_id);
EXPECT_TRUE(strcmp("test", test.last_name.c_str()) == 0);
EXPECT_EQ(out.get(), test.last_output_file.get());
EXPECT_EQ(test.Lookup("test2", &out), ZX_ERR_NOT_FOUND);
}
test.AddContent({33, "aaaa"});
{
fs::VdirCookie cookie;
uint8_t buffer[4096];
size_t len;
EXPECT_EQ(test.Readdir(&cookie, buffer, sizeof(buffer), &len), ZX_OK);
fs::DirentChecker dc(buffer, len);
dc.ExpectEntry(".", V_TYPE_DIR);
dc.ExpectEntry("test", V_TYPE_FILE);
dc.ExpectEntry("aaaa", V_TYPE_FILE);
dc.ExpectEnd();
fbl::RefPtr<fs::Vnode> out;
EXPECT_EQ(test.Lookup("aaaa", &out), ZX_OK);
EXPECT_EQ(33, test.last_id);
EXPECT_TRUE(strcmp("aaaa", test.last_name.c_str()) == 0);
EXPECT_EQ(out.get(), test.last_output_file.get());
}
{
// Ensure manually setting cookie past entries excludes them, but leaves "."
fs::VdirCookie cookie;
cookie.n = 30;
uint8_t buffer[4096];
size_t len;
EXPECT_EQ(test.Readdir(&cookie, buffer, sizeof(buffer), &len), ZX_OK);
fs::DirentChecker dc(buffer, len);
dc.ExpectEntry(".", V_TYPE_DIR);
dc.ExpectEntry("aaaa", V_TYPE_FILE);
dc.ExpectEnd();
// Expect that "." is missing when reusing the cookie.
EXPECT_EQ(test.Readdir(&cookie, buffer, sizeof(buffer), &len), ZX_OK);
dc = fs::DirentChecker(buffer, len);
dc.ExpectEnd();
}
}
} // namespace