Skip to content

Commit

Permalink
Refactor file system tests and fix ls output
Browse files Browse the repository at this point in the history
format
  • Loading branch information
GregoryKogan committed Dec 4, 2023
1 parent 7dcc133 commit 9b0044b
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 17 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ endif()
add_executable(
tests
${SOURCES}
test/dirname_basename.cpp
test/converter.cpp
test/directory.cpp
test/fat.cpp
test/file_data.cpp
test/dirname_basename.cpp
test/ls.cpp
test/mkdir.cpp
)
target_link_libraries(tests GTest::gtest_main)

Expand Down
2 changes: 1 addition & 1 deletion src/CLI/CLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ auto CLI::ls(std::vector<std::string> args) -> void {
}

auto files = file_system_->ls("/");
for (auto const &file : files) { std::cout << file.to_string(verbose) << '\n'; }
for (auto const &file : files) { std::cout << file.to_string("/", verbose) << '\n'; }
}

auto CLI::mkdir(std::vector<std::string> args) -> void {
Expand Down
6 changes: 4 additions & 2 deletions src/FileSystem/FileData/FileData.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "FileData.hpp"

#include <utility>

FileData::FileData(std::string name, FileSize size, std::uint64_t first_cluster_index, bool is_directory)
: name_(std::move(name)), size_(size.bytes), first_cluster_index_(first_cluster_index),
is_directory_(is_directory) {}
Expand Down Expand Up @@ -63,9 +65,9 @@ auto FileData::from_bytes(std::vector<std::byte> const &bytes) -> FileData {
return FileData(name, FileSize{size}, first_cluster_index, is_directory);
}

auto FileData::to_string(bool verbose) const -> std::string {
auto FileData::to_string(std::string delimiter, bool verbose) const -> std::string {
if (!verbose) {
std::string is_directory_string = is_directory_ ? "/" : "";
std::string is_directory_string = is_directory_ ? std::move(delimiter) : "";
return name_ + is_directory_string;
}

Expand Down
2 changes: 1 addition & 1 deletion src/FileSystem/FileData/FileData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class FileData {

[[nodiscard]] auto to_bytes() const -> std::vector<std::byte>;
static auto from_bytes(std::vector<std::byte> const &bytes) -> FileData;
[[nodiscard]] auto to_string(bool verbose = false) const -> std::string;
[[nodiscard]] auto to_string(std::string delimiter, bool verbose = false) const -> std::string;

[[nodiscard]] static auto file_data_size() noexcept -> std::uint64_t;
};
31 changes: 19 additions & 12 deletions src/FileSystem/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ FileSystem::FileSystem(std::string const &path) {
path_resolver_ = std::make_unique<PathResolver>(PATH_DELIMITER, disk_reader_, fat_, settings_.cluster_size);

if (!is_root_dir_created()) create_root_dir();
working_dir_ = std::make_shared<FileData>("/", FileData::FileSize{root_dir_size()}, 0, true);
working_dir_ = std::make_shared<FileData>(path_resolver_->delimiter(), FileData::FileSize{root_dir_size()}, 0, true);
}

void FileSystem::make(std::string const &path, FSMaker::Settings const &settings, bool allow_big) {
Expand All @@ -27,9 +27,12 @@ void FileSystem::make(std::string const &path, FSMaker::Settings const &settings
auto FileSystem::get_settings() const noexcept -> FSMaker::Settings const & { return settings_; }

auto FileSystem::ls(std::string const &path) const -> std::vector<FileData> {
if (path != path_resolver_->delimiter()) throw std::invalid_argument("Can ls only root directory");

auto size = root_dir_size();
auto file_reader = FileReader(FileData("/", FileData::FileSize{size}, 0, true), FileHandler::FileOffset(0), fat_,
settings_.cluster_size, disk_reader_, FileReader::BlockSize(size));
auto file_reader =
FileReader(FileData(path_resolver_->delimiter(), FileData::FileSize{size}, 0, true), FileHandler::FileOffset(0),
fat_, settings_.cluster_size, disk_reader_, FileReader::BlockSize(size));
auto root_dir = Directory::from_bytes(file_reader.read_block());
return root_dir.files();
}
Expand All @@ -44,11 +47,11 @@ auto FileSystem::basename(std::string const &path) -> std::string {

auto FileSystem::mkdir(std::string const &path) -> void {
auto parent_dir_data = get_parent_dir_data(path);
if (!parent_dir_data.has_value()) throw std::runtime_error("Cannot create directory in non-existing directory");
if (!parent_dir_data.value().is_directory()) throw std::runtime_error("Cannot create directory in file");
if (!parent_dir_data.has_value()) throw std::invalid_argument("Cannot create directory in non-existing directory");
if (!parent_dir_data.value().is_directory()) throw std::invalid_argument("Cannot create directory in file");

auto dir_name = basename(path);
if (search(dir_name).has_value()) throw std::runtime_error("Directory already exists");
if (search(dir_name).has_value()) throw std::invalid_argument("Directory already exists");

auto new_dir_data = write_new_dir(parent_dir_data.value(), dir_name);

Expand All @@ -70,23 +73,24 @@ auto FileSystem::is_root_dir_created() const noexcept -> bool { return fat_->is_

auto FileSystem::create_root_dir() -> void {
auto first_cluster = fat_->allocate();
auto file_writer = FileWriter(FileData("/", FileData::FileSize{0}, first_cluster, true), FileHandler::FileOffset(0),
fat_, settings_.cluster_size, disk_writer_);
auto file_writer = FileWriter(FileData(path_resolver_->delimiter(), FileData::FileSize{0}, first_cluster, true),
FileHandler::FileOffset(0), fat_, settings_.cluster_size, disk_writer_);

auto root_dir_bytes = Directory::make_root().to_bytes();
file_writer.write_block(root_dir_bytes);
}

auto FileSystem::root_dir_size() const noexcept -> std::uint64_t {
auto file_reader =
FileReader(FileData("/", FileData::FileSize{FileData::file_data_size()}, 0, true), FileHandler::FileOffset(0),
fat_, settings_.cluster_size, disk_reader_, FileReader::BlockSize(FileData::file_data_size()));
FileReader(FileData(path_resolver_->delimiter(), FileData::FileSize{FileData::file_data_size()}, 0, true),
FileHandler::FileOffset(0), fat_, settings_.cluster_size, disk_reader_,
FileReader::BlockSize(FileData::file_data_size()));
auto root_dir_file_data = FileData::from_bytes(file_reader.read_block());
return root_dir_file_data.size().bytes;
}

auto FileSystem::root_dir_file_data() const -> FileData {
return FileData("/", FileData::FileSize{root_dir_size()}, 0, true);
return FileData(path_resolver_->delimiter(), FileData::FileSize{root_dir_size()}, 0, true);
}

auto FileSystem::search(std::string const &path) const -> std::optional<FileData> {
Expand All @@ -95,7 +99,6 @@ auto FileSystem::search(std::string const &path) const -> std::optional<FileData

auto FileSystem::get_parent_dir_data(std::string const &path) -> std::optional<FileData> {
auto parent_dir_path = dirname(path);
std::cout << "Parent dir path: " << parent_dir_path << '\n';
return search(parent_dir_path);
}

Expand All @@ -120,6 +123,10 @@ auto FileSystem::update_parent_dir(FileData const &parent_dir_data, FileData con
auto parent_dir_writer =
FileWriter(parent_dir_data, FileHandler::FileOffset(0), fat_, settings_.cluster_size, disk_writer_);
parent_dir_writer.write_block(parent_dir.to_bytes());

if (parent_dir_data.first_cluster_index() == working_dir_->first_cluster_index()) {
working_dir_->set_size(FileData::FileSize{parent_dir.to_bytes().size()});
}
}

auto operator<<(std::ostream &out_stream, FileSystem const &file_system) -> std::ostream & {
Expand Down
36 changes: 36 additions & 0 deletions test/ls.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "../src/FileSystem/FileSystem.hpp"
#include <gtest/gtest.h>

class LsTest : public testing::Test {
protected:
// NOLINTBEGIN(cppcoreguidelines-non-private-member-variables-in-classes)
std::string const PATH = "test.fs";
std::uint64_t const SIZE = 1024;
std::uint64_t const CLUSTER_SIZE = 64;

std::unique_ptr<FileSystem> file_system_;
// NOLINTEND(cppcoreguidelines-non-private-member-variables-in-classes)

void SetUp() override {
FileSystem::make(PATH, {SIZE, CLUSTER_SIZE});

file_system_ = std::make_unique<FileSystem>(PATH);
}

void TearDown() override { std::filesystem::remove(PATH); }
};

TEST_F(LsTest, Empty) {
auto const list = file_system_->ls("/");
EXPECT_EQ(list.size(), 2);
EXPECT_EQ(list[0].name(), ".");
EXPECT_EQ(list[1].name(), "..");
}

TEST_F(LsTest, NonExistent) {
EXPECT_THROW(auto const list = file_system_->ls("/non_existent"), std::invalid_argument);
}

TEST_F(LsTest, NonExistentNested) {
EXPECT_THROW(auto const list = file_system_->ls("/non_existent/nested"), std::invalid_argument);
}
45 changes: 45 additions & 0 deletions test/mkdir.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "../src/FileSystem/FileSystem.hpp"
#include <gtest/gtest.h>

class MkdirTest : public testing::Test {
protected:
// NOLINTBEGIN(cppcoreguidelines-non-private-member-variables-in-classes)
std::string const PATH = "test.fs";
std::uint64_t const SIZE = 2024;
std::uint64_t const CLUSTER_SIZE = 64;

std::unique_ptr<FileSystem> file_system_;
// NOLINTEND(cppcoreguidelines-non-private-member-variables-in-classes)

void SetUp() override {
FileSystem::make(PATH, {SIZE, CLUSTER_SIZE});

file_system_ = std::make_unique<FileSystem>(PATH);
}

void TearDown() override { std::filesystem::remove(PATH); }
};

TEST_F(MkdirTest, Empty) {
file_system_->mkdir("./a");
file_system_->mkdir("b");
file_system_->mkdir("/c");
auto const list = file_system_->ls("/");
EXPECT_EQ(list.size(), 5);
EXPECT_EQ(list[0].name(), ".");
EXPECT_EQ(list[1].name(), "..");
EXPECT_EQ(list[2].name(), "a");
EXPECT_EQ(list[3].name(), "b");
EXPECT_EQ(list[4].name(), "c");
}

TEST_F(MkdirTest, NonExistent) { EXPECT_THROW(file_system_->mkdir("/non_existent/test"), std::invalid_argument); }

TEST_F(MkdirTest, NonExistentNested) {
EXPECT_THROW(file_system_->mkdir("/non_existent/nested/test"), std::invalid_argument);
}

TEST_F(MkdirTest, AlreadyExists) {
file_system_->mkdir("/test");
EXPECT_THROW(file_system_->mkdir("/test"), std::invalid_argument);
}

0 comments on commit 9b0044b

Please sign in to comment.