|
11 | 11 | namespace { |
12 | 12 |
|
13 | 13 | /// The data is copied. |
14 | | -udpard_fragment_t* make_test_fragment(const udpard_mem_resource_t& fragment_memory, |
15 | | - const udpard_mem_resource_t& payload_memory, |
16 | | - const udpard_mem_deleter_t payload_deleter, |
17 | | - const size_t offset, |
18 | | - const size_t size, |
19 | | - const void* data) |
| 14 | +udpard_fragment_t* make_test_fragment(const udpard_mem_resource_t fragment_memory, |
| 15 | + const udpard_mem_resource_t payload_memory, |
| 16 | + const udpard_mem_deleter_t payload_deleter, |
| 17 | + const size_t offset, |
| 18 | + const size_t size, |
| 19 | + const void* data) |
20 | 20 | { |
21 | | - auto* const frag = |
| 21 | + auto* frag = |
22 | 22 | static_cast<udpard_fragment_t*>(fragment_memory.alloc(fragment_memory.user, sizeof(udpard_fragment_t))); |
23 | 23 | if (frag == nullptr) { |
24 | 24 | return nullptr; |
@@ -53,10 +53,10 @@ void test_udpard_fragment_seek() |
53 | 53 | const udpard_mem_resource_t mem_payload = instrumented_allocator_make_resource(&alloc_payload); |
54 | 54 | const udpard_mem_deleter_t del_payload = instrumented_allocator_make_deleter(&alloc_payload); |
55 | 55 |
|
56 | | - // Test with single fragment at offset 0. |
| 56 | + // Test 1: Single fragment at offset 0 (root node). |
57 | 57 | // Note: udpard_fragment_seek() uses the index_offset tree structure internally, |
58 | 58 | // which can only be properly built by the RX pipeline. For public API testing, |
59 | | - // we can only test simple cases with standalone fragments. |
| 59 | + // we can only test simple cases with manually constructed tree structures. |
60 | 60 | udpard_fragment_t* single = make_test_fragment(mem_frag, mem_payload, del_payload, 0, 5, "hello"); |
61 | 61 | TEST_ASSERT_NOT_NULL(single); |
62 | 62 | single->next = nullptr; |
@@ -84,15 +84,81 @@ void test_udpard_fragment_seek() |
84 | 84 | mem_frag.free(mem_frag.user, sizeof(udpard_fragment_t), single); |
85 | 85 | TEST_ASSERT_EQUAL_size_t(0, alloc_frag.allocated_fragments); |
86 | 86 | TEST_ASSERT_EQUAL_size_t(0, alloc_payload.allocated_fragments); |
| 87 | + |
| 88 | + instrumented_allocator_reset(&alloc_frag); |
| 89 | + instrumented_allocator_reset(&alloc_payload); |
| 90 | + |
| 91 | + // Test 2: Tree with root and child - to test the root-finding loop. |
| 92 | + // Create a simple tree: root at offset 5, left child at offset 0, right child at offset 10 |
| 93 | + udpard_fragment_t* root = make_test_fragment(mem_frag, mem_payload, del_payload, 5, 3, "mid"); |
| 94 | + udpard_fragment_t* left = make_test_fragment(mem_frag, mem_payload, del_payload, 0, 3, "abc"); |
| 95 | + udpard_fragment_t* right = make_test_fragment(mem_frag, mem_payload, del_payload, 10, 4, "wxyz"); |
| 96 | + TEST_ASSERT_NOT_NULL(root); |
| 97 | + TEST_ASSERT_NOT_NULL(left); |
| 98 | + TEST_ASSERT_NOT_NULL(right); |
| 99 | + |
| 100 | + // Build tree structure: root has left and right children |
| 101 | + root->index_offset.up = nullptr; // root has no parent |
| 102 | + root->index_offset.lr[0] = &left->index_offset; // left child |
| 103 | + root->index_offset.lr[1] = &right->index_offset; // right child |
| 104 | + root->index_offset.bf = 0; |
| 105 | + |
| 106 | + left->index_offset.up = &root->index_offset; // parent is root |
| 107 | + left->index_offset.lr[0] = nullptr; |
| 108 | + left->index_offset.lr[1] = nullptr; |
| 109 | + left->index_offset.bf = 0; |
| 110 | + |
| 111 | + right->index_offset.up = &root->index_offset; // parent is root |
| 112 | + right->index_offset.lr[0] = nullptr; |
| 113 | + right->index_offset.lr[1] = nullptr; |
| 114 | + right->index_offset.bf = 0; |
| 115 | + |
| 116 | + // Link fragments in order using next pointer |
| 117 | + left->next = root; |
| 118 | + root->next = right; |
| 119 | + right->next = nullptr; |
| 120 | + |
| 121 | + // Test seeking from the left child (non-root) - should traverse up to root first. |
| 122 | + // Seeking to offset 0 should find the left fragment. |
| 123 | + TEST_ASSERT_EQUAL_PTR(left, udpard_fragment_seek(left, 0)); |
| 124 | + TEST_ASSERT_EQUAL_PTR(left, udpard_fragment_seek(left, 1)); |
| 125 | + TEST_ASSERT_EQUAL_PTR(left, udpard_fragment_seek(left, 2)); |
| 126 | + |
| 127 | + // Seeking from left child to middle fragment's range [5-8). |
| 128 | + TEST_ASSERT_EQUAL_PTR(root, udpard_fragment_seek(left, 5)); |
| 129 | + TEST_ASSERT_EQUAL_PTR(root, udpard_fragment_seek(left, 6)); |
| 130 | + TEST_ASSERT_EQUAL_PTR(root, udpard_fragment_seek(left, 7)); |
| 131 | + |
| 132 | + // Seeking from right child (non-root) to its own range [10-14). |
| 133 | + TEST_ASSERT_EQUAL_PTR(right, udpard_fragment_seek(right, 10)); |
| 134 | + TEST_ASSERT_EQUAL_PTR(right, udpard_fragment_seek(right, 11)); |
| 135 | + TEST_ASSERT_EQUAL_PTR(right, udpard_fragment_seek(right, 13)); |
| 136 | + |
| 137 | + // Seeking from right child back to left child - should traverse up to root first. |
| 138 | + TEST_ASSERT_EQUAL_PTR(left, udpard_fragment_seek(right, 0)); |
| 139 | + TEST_ASSERT_EQUAL_PTR(left, udpard_fragment_seek(right, 2)); |
| 140 | + |
| 141 | + // Seeking from any node to gaps should return NULL. |
| 142 | + TEST_ASSERT_NULL(udpard_fragment_seek(left, 3)); // gap [3-5) |
| 143 | + TEST_ASSERT_NULL(udpard_fragment_seek(root, 8)); // gap [8-10) |
| 144 | + TEST_ASSERT_NULL(udpard_fragment_seek(right, 14)); // beyond all fragments |
| 145 | + |
| 146 | + // Cleanup. |
| 147 | + mem_payload.free(mem_payload.user, left->origin.size, left->origin.data); |
| 148 | + mem_frag.free(mem_frag.user, sizeof(udpard_fragment_t), left); |
| 149 | + mem_payload.free(mem_payload.user, root->origin.size, root->origin.data); |
| 150 | + mem_frag.free(mem_frag.user, sizeof(udpard_fragment_t), root); |
| 151 | + mem_payload.free(mem_payload.user, right->origin.size, right->origin.data); |
| 152 | + mem_frag.free(mem_frag.user, sizeof(udpard_fragment_t), right); |
| 153 | + TEST_ASSERT_EQUAL_size_t(0, alloc_frag.allocated_fragments); |
| 154 | + TEST_ASSERT_EQUAL_size_t(0, alloc_payload.allocated_fragments); |
87 | 155 | } |
88 | 156 |
|
89 | 157 | } // namespace |
90 | 158 |
|
91 | | -extern "C" |
92 | | -{ |
93 | | -void setUp() {} |
94 | | -void tearDown() {} |
95 | | -} |
| 159 | +extern "C" void setUp() {} |
| 160 | + |
| 161 | +extern "C" void tearDown() {} |
96 | 162 |
|
97 | 163 | int main() |
98 | 164 | { |
|
0 commit comments