aboutsummaryrefslogtreecommitdiff
path: root/kernel/src
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src')
-rw-r--r--kernel/src/filesystem/file_descriptor_table.cpp5
-rw-r--r--kernel/src/filesystem/file_descriptor_table.tests.cpp155
2 files changed, 160 insertions, 0 deletions
diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp
index 287aea2..a31e2e6 100644
--- a/kernel/src/filesystem/file_descriptor_table.cpp
+++ b/kernel/src/filesystem/file_descriptor_table.cpp
@@ -37,6 +37,11 @@ namespace kernel::filesystem
return *global_file_descriptor_table;
}
+ auto file_descriptor_table::reset() -> void
+ {
+ global_file_descriptor_table.reset();
+ }
+
auto file_descriptor_table::add_file(kstd::shared_ptr<open_file_description> const & file_description) -> int
{
if (!file_description)
diff --git a/kernel/src/filesystem/file_descriptor_table.tests.cpp b/kernel/src/filesystem/file_descriptor_table.tests.cpp
new file mode 100644
index 0000000..c431d01
--- /dev/null
+++ b/kernel/src/filesystem/file_descriptor_table.tests.cpp
@@ -0,0 +1,155 @@
+#include "kernel/filesystem/file_descriptor_table.hpp"
+
+#include "kernel/filesystem/open_file_description.hpp"
+#include "kernel/test_support/cpu.hpp"
+#include "kernel/test_support/filesystem/inode.hpp"
+
+#include <kstd/memory>
+#include <kstd/print>
+#include <kstd/vector>
+
+#include <catch2/catch_test_macros.hpp>
+
+struct file_descriptor_table_RAII
+{
+ file_descriptor_table_RAII()
+ {
+ kernel::filesystem::file_descriptor_table::init();
+ }
+ ~file_descriptor_table_RAII()
+ {
+ kernel::filesystem::file_descriptor_table::reset();
+ }
+};
+
+struct file_descriptor_table_reset_only
+{
+ ~file_descriptor_table_reset_only()
+ {
+ kernel::filesystem::file_descriptor_table::reset();
+ }
+};
+
+SCENARIO_METHOD(file_descriptor_table_reset_only, "File descriptor table initialization",
+ "[filesystem][file_descriptor_table]")
+{
+ THEN("accessing the file descriptor table before initialization panics")
+ {
+ REQUIRE_THROWS_AS(kernel::filesystem::file_descriptor_table::get(), kernel::tests::cpu::halt);
+ }
+
+ THEN("the file descriptor table can be initialized and accessed")
+ {
+ kernel::filesystem::file_descriptor_table::init();
+ REQUIRE_NOTHROW(kernel::filesystem::file_descriptor_table::get());
+ }
+
+ THEN("initializing the file descriptor table more than once panics")
+ {
+ kernel::filesystem::file_descriptor_table::init();
+ REQUIRE_THROWS_AS(kernel::filesystem::file_descriptor_table::init(), kernel::tests::cpu::halt);
+ }
+}
+
+SCENARIO_METHOD(file_descriptor_table_RAII, "File descriptor table add/get file", "[filesystem][file_descriptor_table]")
+{
+ GIVEN("a file descriptor table and an open file description")
+ {
+ auto & table = kernel::filesystem::file_descriptor_table::get();
+ auto inode = kstd::make_shared<kernel::tests::filesystem::inode>();
+ auto file_description_1 = kstd::make_shared<kernel::filesystem::open_file_description>(inode);
+ auto file_description_2 = kstd::make_shared<kernel::filesystem::open_file_description>(inode);
+
+ WHEN("adding the open file description to the file descriptor table")
+ {
+ auto fd_1 = table.add_file(file_description_1);
+ auto fd_2 = table.add_file(file_description_2);
+ auto fd_3 = table.add_file(file_description_2);
+
+ THEN("a valid file descriptor is returned")
+ {
+ REQUIRE(fd_1 == 0);
+ REQUIRE(fd_2 == 1);
+ REQUIRE(fd_3 == 1);
+ }
+
+ THEN("the file description can be retrieved using the returned file descriptor")
+ {
+ auto retrieved_description = table.get_file(fd_1);
+ REQUIRE(retrieved_description == file_description_1);
+ }
+ }
+ }
+
+ GIVEN("a invalid open file description")
+ {
+ auto & table = kernel::filesystem::file_descriptor_table::get();
+
+ THEN("adding a null file description returns an error code")
+ {
+ auto fd = table.add_file(nullptr);
+ REQUIRE(fd == -1);
+ }
+
+ THEN("retrieving a file description with a negative file descriptor returns a null pointer")
+ {
+ auto retrieved_description = table.get_file(-1);
+ REQUIRE(retrieved_description == nullptr);
+ }
+
+ THEN("retrieving a file description with an out-of-bounds file descriptor returns a null pointer")
+ {
+ auto retrieved_description = table.get_file(1000);
+ REQUIRE(retrieved_description == nullptr);
+ }
+ }
+}
+
+SCENARIO_METHOD(file_descriptor_table_RAII, "File descriptor table remove file", "[filesystem][file_descriptor_table]")
+{
+ GIVEN("a file descriptor table with an open file description")
+ {
+ auto & table = kernel::filesystem::file_descriptor_table::get();
+ auto inode = kstd::make_shared<kernel::tests::filesystem::inode>();
+ auto file_description = kstd::make_shared<kernel::filesystem::open_file_description>(inode);
+ auto fd = table.add_file(file_description);
+
+ WHEN("removing the file description using the file descriptor")
+ {
+ table.remove_file(fd);
+
+ THEN("the file description can no longer be retrieved using the file descriptor")
+ {
+ auto retrieved_description = table.get_file(fd);
+ REQUIRE(retrieved_description == nullptr);
+ }
+ }
+
+ WHEN("removing a file description the other file descriptor keep the same index")
+ {
+ auto fd2 = table.add_file(file_description);
+ table.remove_file(fd);
+
+ THEN("the second file description can still be retrieved using its file descriptor")
+ {
+ auto retrieved_description = table.get_file(fd2);
+ REQUIRE(retrieved_description == file_description);
+ }
+ }
+ }
+
+ GIVEN("an invalid file descriptor")
+ {
+ auto & table = kernel::filesystem::file_descriptor_table::get();
+
+ THEN("removing a file with a negative file descriptor does nothing")
+ {
+ REQUIRE_NOTHROW(table.remove_file(-1));
+ }
+
+ THEN("removing a file with an out-of-bounds file descriptor does nothing")
+ {
+ REQUIRE_NOTHROW(table.remove_file(1000));
+ }
+ }
+} \ No newline at end of file