Signed-off-by: Fotis Xenakis <[email protected]>
---
modules/tests/Makefile | 6 +-
tests/tst-dax.cc | 333 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 336 insertions(+), 3 deletions(-)
create mode 100644 tests/tst-dax.cc
diff --git a/modules/tests/Makefile b/modules/tests/Makefile
index 016b72bd..c3e2fd8d 100644
--- a/modules/tests/Makefile
+++ b/modules/tests/Makefile
@@ -175,7 +175,7 @@ common-boost-tests := tst-vfs.so tst-libc-locking.so
misc-fs-stress.so \
tst-bsd-tcp1-zsndrcv.so tst-async.so tst-rcu-list.so tst-tcp-listen.so \
tst-poll.so tst-bitset-iter.so tst-timer-set.so tst-clock.so \
tst-rcu-hashtable.so tst-unordered-ring-mpsc.so \
- tst-seek.so tst-ctype.so tst-wctype.so tst-string.so tst-time.so
+ tst-seek.so tst-ctype.so tst-wctype.so tst-string.so tst-time.so
tst-dax.so
boost-tests := $(common-boost-tests)
@@ -197,7 +197,7 @@ solaris-tests := tst-solaris-taskq.so
# FIXME: two of the test below can't compile now because of include path
# (BSD and OSv header files get mixed up, etc.).
#zfs-tests := misc-zfs-disk.so misc-zfs-io.so misc-zfs-arc.so
-zfs-tests := misc-zfs-io.so
+zfs-tests := misc-zfs-io.so
solaris-tests += $(zfs-tests)
tests += $(solaris-tests)
@@ -205,7 +205,7 @@ tests += $(solaris-tests)
$(zfs-tests:%=$(out)/tests/%): COMMON+= \
-DBUILDING_ZFS \
-I$(src)/bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs \
- -I$(src)/bsd/sys/cddl/contrib/opensolaris/common/zfs
+ -I$(src)/bsd/sys/cddl/contrib/opensolaris/common/zfs
$(solaris-tests:%=$(out)/tests/%): COMMON+= \
-Wno-strict-aliasing \
diff --git a/tests/tst-dax.cc b/tests/tst-dax.cc
new file mode 100644
index 00000000..c99cdd2f
--- /dev/null
+++ b/tests/tst-dax.cc
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2021 Fotis Xenakis
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#define BOOST_TEST_MODULE tst-dax
+
+#include <boost/test/unit_test.hpp>
+
+#include <fs/virtiofs/virtiofs_dax.hh>
+
+using virtiofs::dax_manager_stub;
+using virtiofs::dax_window_stub;
+
+static constexpr uint64_t nodeid = 1;
+static constexpr uint64_t file_handle = 1;
+
+// A stub DAX window with a 10-chunk capacity used in all test cases.
+static constexpr u64 window_chunks = 10;
+static constexpr u64 window_len = \
+ window_chunks * dax_manager_stub::DEFAULT_CHUNK_SIZE;
+static auto window = dax_window_stub(window_len);
+
+// A dax_manager with a stub underlying DAX window. Used as a test case
fixture.
+class dax_manager_test : public dax_manager_stub {
+public:
+ dax_manager_test()
+ : dax_manager_stub {window} {}
+};
+
+// Tests on an empty window
+BOOST_FIXTURE_TEST_SUITE(empty_window_tests, dax_manager_test)
+
+ BOOST_AUTO_TEST_CASE(first_empty_empty)
+ {
+ BOOST_TEST(first_empty() == 0);
+ }
+
+ BOOST_AUTO_TEST_CASE(map_empty)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(map(nodeid, file_handle, 3, 0, mp, false) == 0);
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 3);
+ BOOST_TEST(_mappings.size() == 1);
+ }
+
+ BOOST_AUTO_TEST_CASE(unmap_empty)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(unmap(1, mp) != 0);
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 0);
+ BOOST_TEST(_mappings.empty());
+ }
+
+ BOOST_AUTO_TEST_CASE(map_multiple_no_coalesce)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST_REQUIRE(map(nodeid, file_handle, 3, 0, mp, false) == 0);
+
+ BOOST_TEST(map(nodeid, file_handle, 2, 5, mp, false) == 0);
+ BOOST_TEST(mp.mstart == 3);
+ BOOST_TEST(mp.nchunks == 2);
+ BOOST_TEST(_mappings.size() == 2);
+ }
+
+ BOOST_AUTO_TEST_CASE(find_absent)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(!find(nodeid + 1, 0, mp));
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 0);
+ BOOST_TEST(!find(nodeid, 10, mp));
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 0);
+ }
+
+BOOST_AUTO_TEST_SUITE_END()
+
+// A pre-populated dax_manager_test. Used as a test case fixture.
+class dax_manager_test_populated : public dax_manager_test {
+public:
+ void setup() {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST_REQUIRE(map(nodeid, file_handle, 3, 0, mp, false) == 0);
+ BOOST_TEST_REQUIRE(map(nodeid, file_handle, 2, 5, mp, false) == 0);
+ // At this point the window's state is:
+ // | f[0] | f[1] | f[2] | f[5] | f[6] | empty | empty |...
+ // | mapping #1 | mapping #2 |
+ }
+};
+
+// Tests on a pre-populated window
+BOOST_FIXTURE_TEST_SUITE(populated_window_tests, dax_manager_test_populated)
+
+ BOOST_AUTO_TEST_CASE(first_empty_populated)
+ {
+ BOOST_TEST(first_empty() == 5);
+ }
+
+ BOOST_AUTO_TEST_CASE(map_coalesce)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(map(nodeid, file_handle, 3, 7, mp, false) == 0);
+ BOOST_TEST(mp.mstart == 5);
+ BOOST_TEST(mp.nchunks == 3);
+ BOOST_TEST(_mappings.size() == 2);
+ }
+
+ BOOST_AUTO_TEST_CASE(map_stable)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(map(nodeid, file_handle, 0, 0, mp, false) == 0);
+ BOOST_TEST(mp.mstart == 5);
+ BOOST_TEST(mp.nchunks == 0);
+ BOOST_TEST(_mappings.size() == 2);
+ }
+
+ BOOST_AUTO_TEST_CASE(unmap_stable)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(unmap(0, mp) == 0);
+ BOOST_TEST(mp.mstart == 5);
+ BOOST_TEST(mp.nchunks == 0);
+ BOOST_TEST(_mappings.size() == 2);
+ }
+
+ BOOST_AUTO_TEST_CASE(unmap_one_whole)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(unmap(2, mp) == 0);
+ BOOST_TEST(mp.mstart == 3);
+ BOOST_TEST(mp.nchunks == 2);
+ BOOST_TEST(_mappings.size() == 1);
+ }
+
+ BOOST_AUTO_TEST_CASE(unmap_one_part)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(unmap(1, mp) == 0);
+ BOOST_TEST(mp.mstart == 4);
+ BOOST_TEST(mp.nchunks == 1);
+ BOOST_TEST(_mappings.size() == 2);
+ }
+
+ BOOST_AUTO_TEST_CASE(unmap_multiple_part)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(unmap(3, mp) == 0);
+ BOOST_TEST(mp.mstart == 2);
+ BOOST_TEST(mp.nchunks == 3);
+ BOOST_TEST(_mappings.size() == 1);
+ }
+
+ BOOST_AUTO_TEST_CASE(unmap_all)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(unmap(5, mp) == 0);
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 5);
+ BOOST_TEST(_mappings.empty());
+ }
+
+ BOOST_AUTO_TEST_CASE(unmap_excess)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(unmap(6, mp) == 0);
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 5);
+ BOOST_TEST(_mappings.empty());
+ }
+
+ BOOST_AUTO_TEST_CASE(map_evict_part)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(map(nodeid, file_handle, 6, 0, mp, true) == 0);
+ BOOST_TEST(mp.mstart == 4);
+ BOOST_TEST(mp.nchunks == 6);
+ BOOST_TEST(_mappings.size() == 3);
+ }
+
+ BOOST_AUTO_TEST_CASE(map_evict_multiple_part)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(map(nodeid, file_handle, 9, 0, mp, true) == 0);
+ BOOST_TEST(mp.mstart == 1);
+ BOOST_TEST(mp.nchunks == 9);
+ BOOST_TEST(_mappings.size() == 2);
+ }
+
+ BOOST_AUTO_TEST_CASE(map_evict_all)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(map(nodeid, file_handle, 10, 0, mp, true) == 0);
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 10);
+ BOOST_TEST(_mappings.size() == 1);
+ }
+
+ BOOST_AUTO_TEST_CASE(find_absent)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(!find(nodeid + 1, 0, mp));
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 0);
+ BOOST_TEST(!find(nodeid, 10, mp));
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 0);
+ }
+
+ BOOST_AUTO_TEST_CASE(find_present)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(find(nodeid, 0, mp));
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 3);
+
+ BOOST_TEST(find(nodeid, 1, mp));
+ BOOST_TEST(mp.mstart == 1);
+ BOOST_TEST(mp.nchunks == 2);
+
+ BOOST_TEST(find(nodeid, 5, mp));
+ BOOST_TEST(mp.mstart == 3);
+ BOOST_TEST(mp.nchunks == 2);
+
+ BOOST_TEST(find(nodeid, 6, mp));
+ BOOST_TEST(mp.mstart == 4);
+ BOOST_TEST(mp.nchunks == 1);
+ }
+
+BOOST_AUTO_TEST_SUITE_END()
+
+// A full dax_manager_test. Used as a test case fixture.
+class dax_manager_test_full : public dax_manager_test {
+public:
+ void setup() {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST_REQUIRE(map(nodeid, file_handle, 3, 0, mp, false) == 0);
+ BOOST_TEST_REQUIRE(map(nodeid, file_handle, 2, 5, mp, false) == 0);
+ BOOST_TEST_REQUIRE(map(nodeid, file_handle, 5, 10, mp, false) == 0);
+ // At this point the window's state is:
+ // | f[0] | f[1] | f[2] | f[5] | f[6] | f[10] | f[11] | f[12] | f[13]
| f[14] |
+ // | mapping #1 | mapping #2 | mapping #3
|
+ }
+};
+
+BOOST_FIXTURE_TEST_SUITE(full_window_tests, dax_manager_test_full)
+
+ BOOST_AUTO_TEST_CASE(first_empty_full)
+ {
+ BOOST_TEST(first_empty() == window_chunks);
+ }
+
+ BOOST_AUTO_TEST_CASE(map_full)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(map(nodeid, file_handle, 1, 10, mp, false) != 0);
+ BOOST_TEST(mp.mstart == 10);
+ BOOST_TEST(mp.nchunks == 0);
+ BOOST_TEST(_mappings.size() == 3);
+ }
+
+ BOOST_AUTO_TEST_CASE(map_evict_full)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(map(nodeid, file_handle, 1, 0, mp, true) == 0);
+ BOOST_TEST(mp.mstart == 9);
+ BOOST_TEST(mp.nchunks == 1);
+ BOOST_TEST(_mappings.size() == 4);
+ }
+
+ BOOST_AUTO_TEST_CASE(find_absent)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(!find(nodeid + 1, 0, mp));
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 0);
+ BOOST_TEST(!find(nodeid, 20, mp));
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 0);
+ }
+
+ BOOST_AUTO_TEST_CASE(find_present)
+ {
+ mapping_part mp {0, 0};
+
+ BOOST_TEST(find(nodeid, 0, mp));
+ BOOST_TEST(mp.mstart == 0);
+ BOOST_TEST(mp.nchunks == 3);
+
+ BOOST_TEST(find(nodeid, 1, mp));
+ BOOST_TEST(mp.mstart == 1);
+ BOOST_TEST(mp.nchunks == 2);
+
+ BOOST_TEST(find(nodeid, 5, mp));
+ BOOST_TEST(mp.mstart == 3);
+ BOOST_TEST(mp.nchunks == 2);
+
+ BOOST_TEST(find(nodeid, 6, mp));
+ BOOST_TEST(mp.mstart == 4);
+ BOOST_TEST(mp.nchunks == 1);
+
+ BOOST_TEST(find(nodeid, 11, mp));
+ BOOST_TEST(mp.mstart == 6);
+ BOOST_TEST(mp.nchunks == 4);
+ }
+
+BOOST_AUTO_TEST_SUITE_END()
--
2.30.1
--
You received this message because you are subscribed to the Google Groups "OSv
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/osv-dev/VI1PR03MB377366B13B13AC199B882A95A6959%40VI1PR03MB3773.eurprd03.prod.outlook.com.