#include #include #include #include #include #include #include #include #include #include int __real_trace_path(struct ftl_map *map, struct ftl_page_desc *new_page_desc, uint32_t *page, uint32_t va); static void test_empty_root(void **state) { struct ftl_map map; uint32_t page; int ret; (void)state; map.log2_page_size = ilog2(4 * KIB); map.root = UINT32_MAX; ret = __real_trace_path(&map, NULL, &page, 0); assert_int_equal(ret, -2); } static void test_exact_match(void **state) { struct ftl_page_desc descs[] = { { .va = 0xdeadbeef, .subtrees = { [0] = 19, [1] = 21, [2] = 38, [3] = 81, [4] = 24, [5] = 64, [6] = 25, [7] = 15, [8] = 0, [9] = 73, [10] = 49, [11] = 22, [12] = 85, [13] = 45, [14] = 98, [15] = 7, [16] = 72, [17] = 26, [18] = 92, [19] = 16, [20] = 12, [21] = 57, [22] = 52, [23] = 39, [24] = 28, [25] = 42, [26] = 37, [27] = 87, [28] = 5, [29] = 27, [30] = 30, [31] = 47, }, }, }; struct ftl_page_desc ret_page_desc; struct ftl_map map; uint32_t page; int ret; (void)state; map.log2_page_size = ilog2(4 * KIB); map.root = 75; expect_value(__wrap_read_page_desc, map, &map); expect_value(__wrap_read_page_desc, upage, 75); will_return(__wrap_read_page_desc, descs); will_return(__wrap_read_page_desc, 0); ret = __real_trace_path(&map, &ret_page_desc, &page, 0xdeadbeef); assert_int_equal(ret, 0); assert_int_equal(page, 75); assert_memory_equal(&ret_page_desc, descs, sizeof ret_page_desc); } static void test_walk(void **state) { struct ftl_page_desc descs[] = { { .va = 0x7, .subtrees = { [0] = UINT32_MAX, [28] = 43, [29] = UINT32_MAX, }, }, { .va = 0xb, .subtrees = { [0] = UINT32_MAX, [28] = 42, [29] = 44, [30] = UINT32_MAX, }, }, { .va = 0xd, .subtrees = { [0] = UINT32_MAX, [29] = 43, [30] = 45, [31] = UINT32_MAX, }, }, { .va = 0xe, .subtrees = { [0] = UINT32_MAX, [30] = 44, [31] = 46, }, }, { .va = 0xf, .subtrees = { UINT32_MAX, }, }, }; struct ftl_page_desc ret_page_desc; struct ftl_map map; uint32_t page; int ret; (void)state; map.log2_page_size = ilog2(4 * KIB); map.root = 42; expect_value(__wrap_read_page_desc, map, &map); expect_value(__wrap_read_page_desc, upage, 42); will_return(__wrap_read_page_desc, descs); will_return(__wrap_read_page_desc, 0); expect_value(__wrap_read_page_desc, map, &map); expect_value(__wrap_read_page_desc, upage, 43); will_return(__wrap_read_page_desc, descs + 1); will_return(__wrap_read_page_desc, 0); expect_value(__wrap_read_page_desc, map, &map); expect_value(__wrap_read_page_desc, upage, 44); will_return(__wrap_read_page_desc, descs + 2); will_return(__wrap_read_page_desc, 0); expect_value(__wrap_read_page_desc, map, &map); expect_value(__wrap_read_page_desc, upage, 45); will_return(__wrap_read_page_desc, descs + 3); will_return(__wrap_read_page_desc, 0); expect_value(__wrap_read_page_desc, map, &map); expect_value(__wrap_read_page_desc, upage, 46); will_return(__wrap_read_page_desc, descs + 3); will_return(__wrap_read_page_desc, 0); ret = __real_trace_path(&map, &ret_page_desc, &page, 0xf); assert_int_equal(ret, 0); assert_int_equal(page, 46); assert_int_equal(ret_page_desc.va, 0xf); assert_int_equal(ret_page_desc.subtrees[28], 42); assert_int_equal(ret_page_desc.subtrees[29], 43); assert_int_equal(ret_page_desc.subtrees[30], 44); assert_int_equal(ret_page_desc.subtrees[31], 45); } int test_trace_path(void) { const struct CMUnitTest tests[] = { { "trace_path: empty root", test_empty_root, NULL, NULL, NULL }, { "trace_path: exact match", test_exact_match, NULL, NULL, NULL }, { "trace_path: page descriptor walk", test_walk, NULL, NULL, NULL }, }; return cmocka_run_group_tests_name("trace_path", tests, NULL, NULL); }