diff --git a/kernel/Makefile b/kernel/Makefile index 1de781dd..38dae863 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -2,6 +2,11 @@ default: debug/kernel.bin include ../cpp.mk +TESTSUITE_CPP_FILES=$(wildcard test_suite/*.cpp) src/path.cpp src/assert.cpp +TESTSUITE_FLAGS=--std=c++11 -I../tstl/include -I../tstl/test_suite/ -Iinclude -DTHOR_NO_ASSERT + +TEST_CXX ?= g++ + THOR_FLAGS=-DCONFIG_HISTORY=y # Ask GCC for the crtbegin and crtend files @@ -61,6 +66,13 @@ debug/kernel.bin: $(LINK_O_FILES) @ $(CXX) $(KERNEL_LINK_FLAGS) $(KERNEL_CPP_FLAGS_64) -o $@.o $(LINK_O_FILES) @ $(OC) -R .note -R .comment -O binary --set-section-flags .bss=alloc,load,contents $@.o $@ +debug/bin/tester: $(TESTSUITE_CPP_FILES) + @ mkdir -p debug/bin/ + $(TEST_CXX) $(WARNING_FLAGS) $(TESTSUITE_FLAGS) -o debug/bin/tester -g $(TESTSUITE_CPP_FILES) + +test: debug/bin/tester + ./debug/bin/tester + clean: @ echo -e "Remove compiled files (deps/objects)" @ rm -rf debug diff --git a/kernel/test_suite/path.cpp b/kernel/test_suite/path.cpp new file mode 100644 index 00000000..acbdb6e0 --- /dev/null +++ b/kernel/test_suite/path.cpp @@ -0,0 +1,398 @@ +//======================================================================= +// Copyright Baptiste Wicht 2013-2018. +// Distributed under the terms of the MIT License. +// (See accompanying file LICENSE or copy at +// http://www.opensource.org/licenses/MIT) +//======================================================================= + +#include +#include +#include + +#include "vfs/path.hpp" + +#include "test.hpp" + +namespace { + +void test_empty(){ + path p; + + CHECK_DIRECT(p.empty()); + CHECK_DIRECT(!p.is_valid()); + CHECK_EQUALS_DIRECT(p.size(), 0); +} + +void test_root(){ + path p("/"); + + CHECK_DIRECT(!p.empty()); + CHECK_DIRECT(p.is_valid()); + CHECK_DIRECT(p.is_absolute()); + CHECK_DIRECT(p.is_root()); + CHECK_DIRECT(!p.is_sub_root()); + CHECK_EQUALS_DIRECT(p.size(), 1); + CHECK_DIRECT(p.root_name() == "/"); + CHECK_DIRECT(p.base_name() == "/"); + CHECK_DIRECT(p.name(0) == "/"); +} + +void test_path_0(){ + path p1("/a1"); + path p2("/a1/"); + + CHECK_DIRECT(!p1.empty()); + CHECK_DIRECT(p1.is_valid()); + CHECK_DIRECT(p1.is_absolute()); + CHECK_DIRECT(p1.is_sub_root()); + CHECK_EQUALS_DIRECT(p1.size(), 2); + CHECK_DIRECT(p1.root_name() == "/"); + CHECK_DIRECT(p1.base_name() == "a1"); + CHECK_DIRECT(p1.sub_root_name() == "a1"); + CHECK_DIRECT(p1.name(0) == "/"); + CHECK_DIRECT(p1.name(1) == "a1"); + + CHECK_DIRECT(!p2.empty()); + CHECK_DIRECT(p2.is_valid()); + CHECK_DIRECT(p2.is_absolute()); + CHECK_DIRECT(p2.is_sub_root()); + CHECK_EQUALS_DIRECT(p2.size(), 2); + CHECK_DIRECT(p2.root_name() == "/"); + CHECK_DIRECT(p2.base_name() == "a1"); + CHECK_DIRECT(p2.sub_root_name() == "a1"); + CHECK_DIRECT(p2.name(0) == "/"); + CHECK_DIRECT(p2.name(1) == "a1"); + + CHECK_DIRECT(p1 == p1); + CHECK_DIRECT(p1 == p2); + CHECK_DIRECT(p2 == p1); +} + +void test_path_1(){ + path p1("a1"); + path p2("a1/"); + + CHECK_DIRECT(!p1.empty()); + CHECK_DIRECT(p1.is_valid()); + CHECK_DIRECT(!p1.is_absolute()); + CHECK_DIRECT(!p1.is_sub_root()); + CHECK_EQUALS_DIRECT(p1.size(), 1); + CHECK_DIRECT(p1.root_name() == "a1"); + CHECK_DIRECT(p1.base_name() == "a1"); + CHECK_DIRECT(p1.name(0) == "a1"); + + CHECK_DIRECT(!p2.empty()); + CHECK_DIRECT(p2.is_valid()); + CHECK_DIRECT(!p2.is_absolute()); + CHECK_DIRECT(!p2.is_sub_root()); + CHECK_EQUALS_DIRECT(p2.size(), 1); + CHECK_DIRECT(p2.root_name() == "a1"); + CHECK_DIRECT(p2.base_name() == "a1"); + CHECK_DIRECT(p2.name(0) == "a1"); + + CHECK_DIRECT(p1 == p1); + CHECK_DIRECT(p1 == p2); + CHECK_DIRECT(p2 == p1); +} + +void test_path_2(){ + path p1("/a1/b2/c"); + path p2("/a1/b2/c/"); + + CHECK_DIRECT(!p1.empty()); + CHECK_DIRECT(p1.is_valid()); + CHECK_DIRECT(p1.is_absolute()); + CHECK_DIRECT(!p1.is_sub_root()); + CHECK_EQUALS_DIRECT(p1.size(), 4); + CHECK_DIRECT(p1.root_name() == "/"); + CHECK_DIRECT(p1.base_name() == "c"); + CHECK_DIRECT(p1.sub_root_name() == "a1"); + CHECK_DIRECT(p1.name(0) == "/"); + CHECK_DIRECT(p1.name(1) == "a1"); + CHECK_DIRECT(p1.name(2) == "b2"); + CHECK_DIRECT(p1.name(3) == "c"); + + //printf("%.*s \n", int(p1.name(1).size()), p1.name(1).data()); + + CHECK_DIRECT(!p2.empty()); + CHECK_DIRECT(p2.is_valid()); + CHECK_DIRECT(p2.is_absolute()); + CHECK_DIRECT(!p2.is_sub_root()); + CHECK_EQUALS_DIRECT(p2.size(), 4); + CHECK_DIRECT(p2.root_name() == "/"); + CHECK_DIRECT(p2.base_name() == "c"); + CHECK_DIRECT(p2.sub_root_name() == "a1"); + CHECK_DIRECT(p2.name(0) == "/"); + CHECK_DIRECT(p2.name(1) == "a1"); + CHECK_DIRECT(p2.name(2) == "b2"); + CHECK_DIRECT(p2.name(3) == "c"); + + CHECK_DIRECT(p1 == p1); + CHECK_DIRECT(p1 == p2); + CHECK_DIRECT(p2 == p1); +} + +void test_path_3(){ + path p1("a1/b2/c"); + path p2("a1/b2/c/"); + + CHECK_DIRECT(!p1.empty()); + CHECK_DIRECT(p1.is_valid()); + CHECK_DIRECT(!p1.is_absolute()); + CHECK_DIRECT(!p1.is_sub_root()); + CHECK_EQUALS_DIRECT(p1.size(), 3); + CHECK_DIRECT(p1.root_name() == "a1"); + CHECK_DIRECT(p1.base_name() == "c"); + CHECK_DIRECT(p1.name(0) == "a1"); + CHECK_DIRECT(p1.name(1) == "b2"); + CHECK_DIRECT(p1.name(2) == "c"); + + CHECK_DIRECT(!p2.empty()); + CHECK_DIRECT(p2.is_valid()); + CHECK_DIRECT(!p2.is_absolute()); + CHECK_DIRECT(!p2.is_sub_root()); + CHECK_EQUALS_DIRECT(p2.size(), 3); + CHECK_DIRECT(p2.root_name() == "a1"); + CHECK_DIRECT(p2.base_name() == "c"); + CHECK_DIRECT(p2.name(0) == "a1"); + CHECK_DIRECT(p2.name(1) == "b2"); + CHECK_DIRECT(p2.name(2) == "c"); + + CHECK_DIRECT(p1 == p1); + CHECK_DIRECT(p1 == p2); + CHECK_DIRECT(p2 == p1); +} + +void test_invalidate(){ + path p1("/a1/b2/c"); + path p2("a1/b2/c/"); + + p1.invalidate(); + p2.invalidate(); + + CHECK_DIRECT(!p1.is_valid()); + CHECK_DIRECT(!p2.is_valid()); +} + +void test_not_equals(){ + path p1("/a1/b2/c"); + path p2("a1/b2/c/"); + + CHECK_DIRECT(p1 != p2); + CHECK_DIRECT(p2 != p1); + + CHECK_DIRECT(!(p1 == p2)); + CHECK_DIRECT(!(p2 == p1)); + + CHECK_DIRECT(!(p1 == "/a1/b3")); + CHECK_DIRECT(!(p1 == "/")); + CHECK_DIRECT(!(p1 == "/a1/b2/c1")); +} + +void test_concat_0(){ + auto p1 = path("/a1") / path("b2") / path("c"); + auto p2 = path("/a1") / "b2" / "c"; + auto p3 = path("/a1/b2") / path("c"); + auto p4 = path("/") / path("a1/b2") / "c"; + auto p5 = path("/a1") / "b2/c"; + auto p6 = path() / path("/") / path("a1") / path("b2/c"); + + CHECK_DIRECT(!p1.empty()); + CHECK_DIRECT(p1.is_valid()); + CHECK_DIRECT(p1.is_absolute()); + CHECK_DIRECT(!p1.is_sub_root()); + CHECK_EQUALS_DIRECT(p1.size(), 4); + CHECK_DIRECT(p1.root_name() == "/"); + CHECK_DIRECT(p1.base_name() == "c"); + CHECK_DIRECT(p1.sub_root_name() == "a1"); + CHECK_DIRECT(p1.name(0) == "/"); + CHECK_DIRECT(p1.name(1) == "a1"); + CHECK_DIRECT(p1.name(2) == "b2"); + CHECK_DIRECT(p1.name(3) == "c"); + + CHECK_DIRECT(!p2.empty()); + CHECK_DIRECT(p2.is_valid()); + CHECK_DIRECT(p2.is_absolute()); + CHECK_DIRECT(!p2.is_sub_root()); + CHECK_EQUALS_DIRECT(p2.size(), 4); + CHECK_DIRECT(p2.root_name() == "/"); + CHECK_DIRECT(p2.base_name() == "c"); + CHECK_DIRECT(p2.sub_root_name() == "a1"); + CHECK_DIRECT(p2.name(0) == "/"); + CHECK_DIRECT(p2.name(1) == "a1"); + CHECK_DIRECT(p2.name(2) == "b2"); + CHECK_DIRECT(p2.name(3) == "c"); + + CHECK_DIRECT(!p3.empty()); + CHECK_DIRECT(p3.is_valid()); + CHECK_DIRECT(p3.is_absolute()); + CHECK_DIRECT(!p3.is_sub_root()); + CHECK_EQUALS_DIRECT(p3.size(), 4); + CHECK_DIRECT(p3.root_name() == "/"); + CHECK_DIRECT(p3.base_name() == "c"); + CHECK_DIRECT(p3.sub_root_name() == "a1"); + CHECK_DIRECT(p3.name(0) == "/"); + CHECK_DIRECT(p3.name(1) == "a1"); + CHECK_DIRECT(p3.name(2) == "b2"); + CHECK_DIRECT(p3.name(3) == "c"); + + CHECK_DIRECT(!p4.empty()); + CHECK_DIRECT(p4.is_valid()); + CHECK_DIRECT(p4.is_absolute()); + CHECK_DIRECT(!p4.is_sub_root()); + CHECK_EQUALS_DIRECT(p4.size(), 4); + CHECK_DIRECT(p4.root_name() == "/"); + CHECK_DIRECT(p4.base_name() == "c"); + CHECK_DIRECT(p4.sub_root_name() == "a1"); + CHECK_DIRECT(p4.name(0) == "/"); + CHECK_DIRECT(p4.name(1) == "a1"); + CHECK_DIRECT(p4.name(2) == "b2"); + CHECK_DIRECT(p4.name(3) == "c"); + + CHECK_DIRECT(!p5.empty()); + CHECK_DIRECT(p5.is_valid()); + CHECK_DIRECT(p5.is_absolute()); + CHECK_DIRECT(!p5.is_sub_root()); + CHECK_EQUALS_DIRECT(p5.size(), 4); + CHECK_DIRECT(p5.root_name() == "/"); + CHECK_DIRECT(p5.base_name() == "c"); + CHECK_DIRECT(p5.sub_root_name() == "a1"); + CHECK_DIRECT(p5.name(0) == "/"); + CHECK_DIRECT(p5.name(1) == "a1"); + CHECK_DIRECT(p5.name(2) == "b2"); + CHECK_DIRECT(p5.name(3) == "c"); + + CHECK_DIRECT(!p6.empty()); + CHECK_DIRECT(p6.is_valid()); + CHECK_DIRECT(p6.is_absolute()); + CHECK_DIRECT(!p6.is_sub_root()); + CHECK_EQUALS_DIRECT(p6.size(), 4); + CHECK_DIRECT(p6.root_name() == "/"); + CHECK_DIRECT(p6.base_name() == "c"); + CHECK_DIRECT(p6.sub_root_name() == "a1"); + CHECK_DIRECT(p6.name(0) == "/"); + CHECK_DIRECT(p6.name(1) == "a1"); + CHECK_DIRECT(p6.name(2) == "b2"); + CHECK_DIRECT(p6.name(3) == "c"); +} + +void test_concat_1(){ + auto p1 = path("a1") / path("b2") / path("c"); + auto p2 = path("a1") / "b2" / "c"; + auto p3 = path("a1/b2") / path("c"); + auto p4 = path("a1/b2") / "c"; + auto p5 = path("a1") / "b2/c"; + auto p6 = path() / path("a1") / path("b2/c"); + + CHECK_DIRECT(!p1.empty()); + CHECK_DIRECT(p1.is_valid()); + CHECK_DIRECT(!p1.is_absolute()); + CHECK_DIRECT(!p1.is_sub_root()); + CHECK_EQUALS_DIRECT(p1.size(), 3); + CHECK_DIRECT(p1.root_name() == "a1"); + CHECK_DIRECT(p1.base_name() == "c"); + CHECK_DIRECT(p1.name(0) == "a1"); + CHECK_DIRECT(p1.name(1) == "b2"); + CHECK_DIRECT(p1.name(2) == "c"); + + CHECK_DIRECT(!p2.empty()); + CHECK_DIRECT(p2.is_valid()); + CHECK_DIRECT(!p2.is_absolute()); + CHECK_DIRECT(!p2.is_sub_root()); + CHECK_EQUALS_DIRECT(p2.size(), 3); + CHECK_DIRECT(p2.root_name() == "a1"); + CHECK_DIRECT(p2.base_name() == "c"); + CHECK_DIRECT(p2.name(0) == "a1"); + CHECK_DIRECT(p2.name(1) == "b2"); + CHECK_DIRECT(p2.name(2) == "c"); + + CHECK_DIRECT(!p3.empty()); + CHECK_DIRECT(p3.is_valid()); + CHECK_DIRECT(!p3.is_absolute()); + CHECK_DIRECT(!p3.is_sub_root()); + CHECK_EQUALS_DIRECT(p3.size(), 3); + CHECK_DIRECT(p3.root_name() == "a1"); + CHECK_DIRECT(p3.base_name() == "c"); + CHECK_DIRECT(p3.name(0) == "a1"); + CHECK_DIRECT(p3.name(1) == "b2"); + CHECK_DIRECT(p3.name(2) == "c"); + + CHECK_DIRECT(!p4.empty()); + CHECK_DIRECT(p4.is_valid()); + CHECK_DIRECT(!p4.is_absolute()); + CHECK_DIRECT(!p4.is_sub_root()); + CHECK_EQUALS_DIRECT(p4.size(), 3); + CHECK_DIRECT(p4.root_name() == "a1"); + CHECK_DIRECT(p4.base_name() == "c"); + CHECK_DIRECT(p4.name(0) == "a1"); + CHECK_DIRECT(p4.name(1) == "b2"); + CHECK_DIRECT(p4.name(2) == "c"); + + CHECK_DIRECT(!p5.empty()); + CHECK_DIRECT(p5.is_valid()); + CHECK_DIRECT(!p5.is_absolute()); + CHECK_DIRECT(!p5.is_sub_root()); + CHECK_EQUALS_DIRECT(p5.size(), 3); + CHECK_DIRECT(p5.root_name() == "a1"); + CHECK_DIRECT(p5.base_name() == "c"); + CHECK_DIRECT(p5.name(0) == "a1"); + CHECK_DIRECT(p5.name(1) == "b2"); + CHECK_DIRECT(p5.name(2) == "c"); + + CHECK_DIRECT(!p6.empty()); + CHECK_DIRECT(p6.is_valid()); + CHECK_DIRECT(!p6.is_absolute()); + CHECK_DIRECT(!p6.is_sub_root()); + CHECK_EQUALS_DIRECT(p6.size(), 3); + CHECK_DIRECT(p6.root_name() == "a1"); + CHECK_DIRECT(p6.base_name() == "c"); + CHECK_DIRECT(p6.name(0) == "a1"); + CHECK_DIRECT(p6.name(1) == "b2"); + CHECK_DIRECT(p6.name(2) == "c"); +} + +void test_sub_path(){ + path p1("/a/b/c/d/e/"); + path p2("a/b/c/d/e/"); + + CHECK_DIRECT(p1.sub_path(0) == p1); + CHECK_DIRECT(p1.sub_path(1) == path("a/b/c/d/e")); + CHECK_DIRECT(p1.sub_path(2) == path("b/c/d/e")); + CHECK_DIRECT(p1.sub_path(3) == path("c/d/e")); + CHECK_DIRECT(p1.sub_path(4) == path("d/e")); + CHECK_DIRECT(p1.sub_path(5) == path("e")); + + CHECK_DIRECT(p2.sub_path(0) == p2); + CHECK_DIRECT(p2.sub_path(1) == path("b/c/d/e")); + CHECK_DIRECT(p2.sub_path(2) == path("c/d/e")); + CHECK_DIRECT(p2.sub_path(3) == path("d/e")); + CHECK_DIRECT(p2.sub_path(4) == path("e")); +} + +void test_branch_path(){ + path p1("/a/b/c/d/e/"); + path p2("a/b/c/d/e/"); + + CHECK_DIRECT(p1.branch_path() == "/a/b/c/d/"); + CHECK_DIRECT(p1.branch_path() == "/a/b/c/d"); + + CHECK_DIRECT(p2.branch_path() == "a/b/c/d/"); + CHECK_DIRECT(p2.branch_path() == "a/b/c/d"); +} + +} //end of anonymous namespace + +void path_tests(){ + test_empty(); + test_root(); + test_path_0(); + test_path_1(); + test_path_2(); + test_path_3(); + test_invalidate(); + test_not_equals(); + test_concat_0(); + test_concat_1(); + test_sub_path(); + test_branch_path(); +} diff --git a/kernel/test_suite/test.cpp b/kernel/test_suite/test.cpp new file mode 100644 index 00000000..4add076e --- /dev/null +++ b/kernel/test_suite/test.cpp @@ -0,0 +1,68 @@ +//======================================================================= +// Copyright Baptiste Wicht 2013-2018. +// Distributed under the terms of the MIT License. +// (See accompanying file LICENSE or copy at +// http://www.opensource.org/licenses/MIT) +//======================================================================= + +#include +#include + +#include "test.hpp" + +void path_tests(); + +int main(){ + path_tests(); + + printf("All tests finished\n"); + + return 0; +} + +// TODO Avoid that duplication + +void check(bool condition){ + if(!condition){ + printf("Check failed\n"); + } +} + +void check(bool condition, const char* message){ + if(!condition){ + printf("Check failed: \"%s\"\n", message); + } +} + +void check_equals(long value, long expected, const char* message){ + if(value != expected){ + printf("Check failed: \"%s\"\n", message); + printf("\t expected: %ld was: %ld\n", expected, value); + } +} + +void check(bool condition, const char* where, size_t line){ + if(!condition){ + printf("%s:%lu Check failed\n", where, line); + } +} + +void check(bool condition, const char* message, const char* where, size_t line){ + if(!condition){ + printf("%s:%lu Check failed: \"%s\"\n", where, line, message); + } +} + +void check_equals(long value, long expected, const char* message, const char* where, size_t line){ + if(value != expected){ + printf("%s:%lu Check failed: \"%s\"\n", where, line, message); + printf("\t expected: %ld was: %ld\n", expected, value); + } +} + +void check_equals(long value, long expected, const char* where, size_t line){ + if(value != expected){ + printf("%s:%lu Check failed", where, line); + printf("\t expected: %ld was: %ld\n", expected, value); + } +} diff --git a/tstl/test_suite/test.cpp b/tstl/test_suite/test.cpp index d2308be3..d482754a 100644 --- a/tstl/test_suite/test.cpp +++ b/tstl/test_suite/test.cpp @@ -81,3 +81,10 @@ void check_equals(long value, long expected, const char* message, const char* wh printf("\t expected: %ld was: %ld\n", expected, value); } } + +void check_equals(long value, long expected, const char* where, size_t line){ + if(value != expected){ + printf("%s:%lu Check failed\n", where, line); + printf("\t expected: %ld was: %ld\n", expected, value); + } +} diff --git a/tstl/test_suite/test.hpp b/tstl/test_suite/test.hpp index 0d381da4..70214a76 100644 --- a/tstl/test_suite/test.hpp +++ b/tstl/test_suite/test.hpp @@ -11,6 +11,9 @@ #define CHECK(cond, message) check(cond, message, __PRETTY_FUNCTION__, __LINE__) #define CHECK_EQUALS(a, b, message) check_equals(a, b, message, __PRETTY_FUNCTION__, __LINE__) +#define CHECK_DIRECT(cond) check(cond, __PRETTY_FUNCTION__, __LINE__) +#define CHECK_EQUALS_DIRECT(a, b) check_equals(a, b, __PRETTY_FUNCTION__, __LINE__) + void check(bool condition); void check(bool condition, const char* message); void check_equals(long value, long expected, const char* message); @@ -18,3 +21,4 @@ void check_equals(long value, long expected, const char* message); void check(bool condition, const char* where, size_t line); void check(bool condition, const char* message, const char* where, size_t line); void check_equals(long value, long expected, const char* message, const char* where, size_t line); +void check_equals(long value, long expected, const char* where, size_t line);