Skip to content

Commit 260626d

Browse files
foxengwkozaczuk
authored andcommitted
tests: add DAX manager white-box unit tests
Signed-off-by: Fotis Xenakis <[email protected]> Message-Id: <VI1PR03MB377366B13B13AC199B882A95A6959@VI1PR03MB3773.eurprd03.prod.outlook.com>
1 parent ad7ea90 commit 260626d

File tree

2 files changed

+336
-3
lines changed

2 files changed

+336
-3
lines changed

modules/tests/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ common-boost-tests := tst-vfs.so tst-libc-locking.so misc-fs-stress.so \
175175
tst-bsd-tcp1-zsndrcv.so tst-async.so tst-rcu-list.so tst-tcp-listen.so \
176176
tst-poll.so tst-bitset-iter.so tst-timer-set.so tst-clock.so \
177177
tst-rcu-hashtable.so tst-unordered-ring-mpsc.so \
178-
tst-seek.so tst-ctype.so tst-wctype.so tst-string.so tst-time.so
178+
tst-seek.so tst-ctype.so tst-wctype.so tst-string.so tst-time.so tst-dax.so
179179

180180
boost-tests := $(common-boost-tests)
181181

@@ -197,15 +197,15 @@ solaris-tests := tst-solaris-taskq.so
197197
# FIXME: two of the test below can't compile now because of include path
198198
# (BSD and OSv header files get mixed up, etc.).
199199
#zfs-tests := misc-zfs-disk.so misc-zfs-io.so misc-zfs-arc.so
200-
zfs-tests := misc-zfs-io.so
200+
zfs-tests := misc-zfs-io.so
201201
solaris-tests += $(zfs-tests)
202202

203203
tests += $(solaris-tests)
204204

205205
$(zfs-tests:%=$(out)/tests/%): COMMON+= \
206206
-DBUILDING_ZFS \
207207
-I$(src)/bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs \
208-
-I$(src)/bsd/sys/cddl/contrib/opensolaris/common/zfs
208+
-I$(src)/bsd/sys/cddl/contrib/opensolaris/common/zfs
209209

210210
$(solaris-tests:%=$(out)/tests/%): COMMON+= \
211211
-Wno-strict-aliasing \

tests/tst-dax.cc

Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
/*
2+
* Copyright (C) 2021 Fotis Xenakis
3+
*
4+
* This work is open source software, licensed under the terms of the
5+
* BSD license as described in the LICENSE file in the top-level directory.
6+
*/
7+
8+
#define BOOST_TEST_MODULE tst-dax
9+
10+
#include <boost/test/unit_test.hpp>
11+
12+
#include <fs/virtiofs/virtiofs_dax.hh>
13+
14+
using virtiofs::dax_manager_stub;
15+
using virtiofs::dax_window_stub;
16+
17+
static constexpr uint64_t nodeid = 1;
18+
static constexpr uint64_t file_handle = 1;
19+
20+
// A stub DAX window with a 10-chunk capacity used in all test cases.
21+
static constexpr u64 window_chunks = 10;
22+
static constexpr u64 window_len = \
23+
window_chunks * dax_manager_stub::DEFAULT_CHUNK_SIZE;
24+
static auto window = dax_window_stub(window_len);
25+
26+
// A dax_manager with a stub underlying DAX window. Used as a test case fixture.
27+
class dax_manager_test : public dax_manager_stub {
28+
public:
29+
dax_manager_test()
30+
: dax_manager_stub {window} {}
31+
};
32+
33+
// Tests on an empty window
34+
BOOST_FIXTURE_TEST_SUITE(empty_window_tests, dax_manager_test)
35+
36+
BOOST_AUTO_TEST_CASE(first_empty_empty)
37+
{
38+
BOOST_TEST(first_empty() == 0);
39+
}
40+
41+
BOOST_AUTO_TEST_CASE(map_empty)
42+
{
43+
mapping_part mp {0, 0};
44+
45+
BOOST_TEST(map(nodeid, file_handle, 3, 0, mp, false) == 0);
46+
BOOST_TEST(mp.mstart == 0);
47+
BOOST_TEST(mp.nchunks == 3);
48+
BOOST_TEST(_mappings.size() == 1);
49+
}
50+
51+
BOOST_AUTO_TEST_CASE(unmap_empty)
52+
{
53+
mapping_part mp {0, 0};
54+
55+
BOOST_TEST(unmap(1, mp) != 0);
56+
BOOST_TEST(mp.mstart == 0);
57+
BOOST_TEST(mp.nchunks == 0);
58+
BOOST_TEST(_mappings.empty());
59+
}
60+
61+
BOOST_AUTO_TEST_CASE(map_multiple_no_coalesce)
62+
{
63+
mapping_part mp {0, 0};
64+
65+
BOOST_TEST_REQUIRE(map(nodeid, file_handle, 3, 0, mp, false) == 0);
66+
67+
BOOST_TEST(map(nodeid, file_handle, 2, 5, mp, false) == 0);
68+
BOOST_TEST(mp.mstart == 3);
69+
BOOST_TEST(mp.nchunks == 2);
70+
BOOST_TEST(_mappings.size() == 2);
71+
}
72+
73+
BOOST_AUTO_TEST_CASE(find_absent)
74+
{
75+
mapping_part mp {0, 0};
76+
77+
BOOST_TEST(!find(nodeid + 1, 0, mp));
78+
BOOST_TEST(mp.mstart == 0);
79+
BOOST_TEST(mp.nchunks == 0);
80+
BOOST_TEST(!find(nodeid, 10, mp));
81+
BOOST_TEST(mp.mstart == 0);
82+
BOOST_TEST(mp.nchunks == 0);
83+
}
84+
85+
BOOST_AUTO_TEST_SUITE_END()
86+
87+
// A pre-populated dax_manager_test. Used as a test case fixture.
88+
class dax_manager_test_populated : public dax_manager_test {
89+
public:
90+
void setup() {
91+
mapping_part mp {0, 0};
92+
93+
BOOST_TEST_REQUIRE(map(nodeid, file_handle, 3, 0, mp, false) == 0);
94+
BOOST_TEST_REQUIRE(map(nodeid, file_handle, 2, 5, mp, false) == 0);
95+
// At this point the window's state is:
96+
// | f[0] | f[1] | f[2] | f[5] | f[6] | empty | empty |...
97+
// | mapping #1 | mapping #2 |
98+
}
99+
};
100+
101+
// Tests on a pre-populated window
102+
BOOST_FIXTURE_TEST_SUITE(populated_window_tests, dax_manager_test_populated)
103+
104+
BOOST_AUTO_TEST_CASE(first_empty_populated)
105+
{
106+
BOOST_TEST(first_empty() == 5);
107+
}
108+
109+
BOOST_AUTO_TEST_CASE(map_coalesce)
110+
{
111+
mapping_part mp {0, 0};
112+
113+
BOOST_TEST(map(nodeid, file_handle, 3, 7, mp, false) == 0);
114+
BOOST_TEST(mp.mstart == 5);
115+
BOOST_TEST(mp.nchunks == 3);
116+
BOOST_TEST(_mappings.size() == 2);
117+
}
118+
119+
BOOST_AUTO_TEST_CASE(map_stable)
120+
{
121+
mapping_part mp {0, 0};
122+
123+
BOOST_TEST(map(nodeid, file_handle, 0, 0, mp, false) == 0);
124+
BOOST_TEST(mp.mstart == 5);
125+
BOOST_TEST(mp.nchunks == 0);
126+
BOOST_TEST(_mappings.size() == 2);
127+
}
128+
129+
BOOST_AUTO_TEST_CASE(unmap_stable)
130+
{
131+
mapping_part mp {0, 0};
132+
133+
BOOST_TEST(unmap(0, mp) == 0);
134+
BOOST_TEST(mp.mstart == 5);
135+
BOOST_TEST(mp.nchunks == 0);
136+
BOOST_TEST(_mappings.size() == 2);
137+
}
138+
139+
BOOST_AUTO_TEST_CASE(unmap_one_whole)
140+
{
141+
mapping_part mp {0, 0};
142+
143+
BOOST_TEST(unmap(2, mp) == 0);
144+
BOOST_TEST(mp.mstart == 3);
145+
BOOST_TEST(mp.nchunks == 2);
146+
BOOST_TEST(_mappings.size() == 1);
147+
}
148+
149+
BOOST_AUTO_TEST_CASE(unmap_one_part)
150+
{
151+
mapping_part mp {0, 0};
152+
153+
BOOST_TEST(unmap(1, mp) == 0);
154+
BOOST_TEST(mp.mstart == 4);
155+
BOOST_TEST(mp.nchunks == 1);
156+
BOOST_TEST(_mappings.size() == 2);
157+
}
158+
159+
BOOST_AUTO_TEST_CASE(unmap_multiple_part)
160+
{
161+
mapping_part mp {0, 0};
162+
163+
BOOST_TEST(unmap(3, mp) == 0);
164+
BOOST_TEST(mp.mstart == 2);
165+
BOOST_TEST(mp.nchunks == 3);
166+
BOOST_TEST(_mappings.size() == 1);
167+
}
168+
169+
BOOST_AUTO_TEST_CASE(unmap_all)
170+
{
171+
mapping_part mp {0, 0};
172+
173+
BOOST_TEST(unmap(5, mp) == 0);
174+
BOOST_TEST(mp.mstart == 0);
175+
BOOST_TEST(mp.nchunks == 5);
176+
BOOST_TEST(_mappings.empty());
177+
}
178+
179+
BOOST_AUTO_TEST_CASE(unmap_excess)
180+
{
181+
mapping_part mp {0, 0};
182+
183+
BOOST_TEST(unmap(6, mp) == 0);
184+
BOOST_TEST(mp.mstart == 0);
185+
BOOST_TEST(mp.nchunks == 5);
186+
BOOST_TEST(_mappings.empty());
187+
}
188+
189+
BOOST_AUTO_TEST_CASE(map_evict_part)
190+
{
191+
mapping_part mp {0, 0};
192+
193+
BOOST_TEST(map(nodeid, file_handle, 6, 0, mp, true) == 0);
194+
BOOST_TEST(mp.mstart == 4);
195+
BOOST_TEST(mp.nchunks == 6);
196+
BOOST_TEST(_mappings.size() == 3);
197+
}
198+
199+
BOOST_AUTO_TEST_CASE(map_evict_multiple_part)
200+
{
201+
mapping_part mp {0, 0};
202+
203+
BOOST_TEST(map(nodeid, file_handle, 9, 0, mp, true) == 0);
204+
BOOST_TEST(mp.mstart == 1);
205+
BOOST_TEST(mp.nchunks == 9);
206+
BOOST_TEST(_mappings.size() == 2);
207+
}
208+
209+
BOOST_AUTO_TEST_CASE(map_evict_all)
210+
{
211+
mapping_part mp {0, 0};
212+
213+
BOOST_TEST(map(nodeid, file_handle, 10, 0, mp, true) == 0);
214+
BOOST_TEST(mp.mstart == 0);
215+
BOOST_TEST(mp.nchunks == 10);
216+
BOOST_TEST(_mappings.size() == 1);
217+
}
218+
219+
BOOST_AUTO_TEST_CASE(find_absent)
220+
{
221+
mapping_part mp {0, 0};
222+
223+
BOOST_TEST(!find(nodeid + 1, 0, mp));
224+
BOOST_TEST(mp.mstart == 0);
225+
BOOST_TEST(mp.nchunks == 0);
226+
BOOST_TEST(!find(nodeid, 10, mp));
227+
BOOST_TEST(mp.mstart == 0);
228+
BOOST_TEST(mp.nchunks == 0);
229+
}
230+
231+
BOOST_AUTO_TEST_CASE(find_present)
232+
{
233+
mapping_part mp {0, 0};
234+
235+
BOOST_TEST(find(nodeid, 0, mp));
236+
BOOST_TEST(mp.mstart == 0);
237+
BOOST_TEST(mp.nchunks == 3);
238+
239+
BOOST_TEST(find(nodeid, 1, mp));
240+
BOOST_TEST(mp.mstart == 1);
241+
BOOST_TEST(mp.nchunks == 2);
242+
243+
BOOST_TEST(find(nodeid, 5, mp));
244+
BOOST_TEST(mp.mstart == 3);
245+
BOOST_TEST(mp.nchunks == 2);
246+
247+
BOOST_TEST(find(nodeid, 6, mp));
248+
BOOST_TEST(mp.mstart == 4);
249+
BOOST_TEST(mp.nchunks == 1);
250+
}
251+
252+
BOOST_AUTO_TEST_SUITE_END()
253+
254+
// A full dax_manager_test. Used as a test case fixture.
255+
class dax_manager_test_full : public dax_manager_test {
256+
public:
257+
void setup() {
258+
mapping_part mp {0, 0};
259+
260+
BOOST_TEST_REQUIRE(map(nodeid, file_handle, 3, 0, mp, false) == 0);
261+
BOOST_TEST_REQUIRE(map(nodeid, file_handle, 2, 5, mp, false) == 0);
262+
BOOST_TEST_REQUIRE(map(nodeid, file_handle, 5, 10, mp, false) == 0);
263+
// At this point the window's state is:
264+
// | f[0] | f[1] | f[2] | f[5] | f[6] | f[10] | f[11] | f[12] | f[13] | f[14] |
265+
// | mapping #1 | mapping #2 | mapping #3 |
266+
}
267+
};
268+
269+
BOOST_FIXTURE_TEST_SUITE(full_window_tests, dax_manager_test_full)
270+
271+
BOOST_AUTO_TEST_CASE(first_empty_full)
272+
{
273+
BOOST_TEST(first_empty() == window_chunks);
274+
}
275+
276+
BOOST_AUTO_TEST_CASE(map_full)
277+
{
278+
mapping_part mp {0, 0};
279+
280+
BOOST_TEST(map(nodeid, file_handle, 1, 10, mp, false) != 0);
281+
BOOST_TEST(mp.mstart == 10);
282+
BOOST_TEST(mp.nchunks == 0);
283+
BOOST_TEST(_mappings.size() == 3);
284+
}
285+
286+
BOOST_AUTO_TEST_CASE(map_evict_full)
287+
{
288+
mapping_part mp {0, 0};
289+
290+
BOOST_TEST(map(nodeid, file_handle, 1, 0, mp, true) == 0);
291+
BOOST_TEST(mp.mstart == 9);
292+
BOOST_TEST(mp.nchunks == 1);
293+
BOOST_TEST(_mappings.size() == 4);
294+
}
295+
296+
BOOST_AUTO_TEST_CASE(find_absent)
297+
{
298+
mapping_part mp {0, 0};
299+
300+
BOOST_TEST(!find(nodeid + 1, 0, mp));
301+
BOOST_TEST(mp.mstart == 0);
302+
BOOST_TEST(mp.nchunks == 0);
303+
BOOST_TEST(!find(nodeid, 20, mp));
304+
BOOST_TEST(mp.mstart == 0);
305+
BOOST_TEST(mp.nchunks == 0);
306+
}
307+
308+
BOOST_AUTO_TEST_CASE(find_present)
309+
{
310+
mapping_part mp {0, 0};
311+
312+
BOOST_TEST(find(nodeid, 0, mp));
313+
BOOST_TEST(mp.mstart == 0);
314+
BOOST_TEST(mp.nchunks == 3);
315+
316+
BOOST_TEST(find(nodeid, 1, mp));
317+
BOOST_TEST(mp.mstart == 1);
318+
BOOST_TEST(mp.nchunks == 2);
319+
320+
BOOST_TEST(find(nodeid, 5, mp));
321+
BOOST_TEST(mp.mstart == 3);
322+
BOOST_TEST(mp.nchunks == 2);
323+
324+
BOOST_TEST(find(nodeid, 6, mp));
325+
BOOST_TEST(mp.mstart == 4);
326+
BOOST_TEST(mp.nchunks == 1);
327+
328+
BOOST_TEST(find(nodeid, 11, mp));
329+
BOOST_TEST(mp.mstart == 6);
330+
BOOST_TEST(mp.nchunks == 4);
331+
}
332+
333+
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)