Skip to content

Commit 3261204

Browse files
more test
1 parent e337e86 commit 3261204

File tree

2 files changed

+78
-3
lines changed

2 files changed

+78
-3
lines changed

libudpard/udpard.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ void udpard_fragment_free_all(udpard_fragment_t* const frag, const udpard_mem_re
106106
// Descend the tree
107107
for (uint_fast8_t i = 0; i < 2; i++) {
108108
if (frag->index_offset.lr[i] != NULL) {
109+
frag->index_offset.lr[i]->up = NULL; // Prevent backtrack ascension from this branch
109110
udpard_fragment_free_all((udpard_fragment_t*)frag->index_offset.lr[i], fragment_memory_resource);
111+
frag->index_offset.lr[i] = NULL; // Avoid dangly pointers even if we're headed for imminent destruction
110112
}
111113
}
112114
// Delete this fragment
@@ -115,7 +117,7 @@ void udpard_fragment_free_all(udpard_fragment_t* const frag, const udpard_mem_re
115117
mem_free(fragment_memory_resource, sizeof(udpard_fragment_t), frag);
116118
if (parent != NULL) {
117119
parent->index_offset.lr[parent->index_offset.lr[1] == (udpard_tree_t*)frag] = NULL;
118-
udpard_fragment_free_all(parent, fragment_memory_resource); // tail call
120+
udpard_fragment_free_all(parent, fragment_memory_resource); // tail call hopefully
119121
}
120122
}
121123
}

tests/src/test_intrusive_rx.c

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static void test_rx_fragment_tree_update_a(void)
9797
udpard_tree_t* root = NULL;
9898
size_t cov = 0;
9999
rx_fragment_tree_update_result_t res = rx_fragment_tree_not_done;
100-
//
100+
// Add fragment.
101101
res = rx_fragment_tree_update(&root, //
102102
mem_frag,
103103
del_payload,
@@ -139,7 +139,7 @@ static void test_rx_fragment_tree_update_a(void)
139139
udpard_tree_t* root = NULL;
140140
size_t cov = 0;
141141
rx_fragment_tree_update_result_t res = rx_fragment_tree_not_done;
142-
//
142+
// Add fragment.
143143
res = rx_fragment_tree_update(&root, //
144144
mem_frag,
145145
del_payload,
@@ -173,6 +173,79 @@ static void test_rx_fragment_tree_update_a(void)
173173
TEST_ASSERT_EQUAL_size_t(1, alloc_frag.count_free);
174174
TEST_ASSERT_EQUAL_size_t(1, alloc_payload.count_free);
175175
}
176+
177+
instrumented_allocator_reset(&alloc_frag);
178+
instrumented_allocator_reset(&alloc_payload);
179+
180+
// Multi-frame reassembly test: "abc def xyz "; the last nul is beyond the extent.
181+
{
182+
udpard_tree_t* root = NULL;
183+
size_t cov = 0;
184+
rx_fragment_tree_update_result_t res = rx_fragment_tree_not_done;
185+
// Add fragment.
186+
res = rx_fragment_tree_update(&root, //
187+
mem_frag,
188+
del_payload,
189+
make_frame_base(mem_payload, 0, "abc"),
190+
100,
191+
10,
192+
&cov);
193+
TEST_ASSERT_EQUAL(rx_fragment_tree_not_done, res);
194+
TEST_ASSERT_EQUAL_size_t(4, cov);
195+
TEST_ASSERT_NOT_NULL(root);
196+
TEST_ASSERT_EQUAL(1, tree_count(root));
197+
// Add fragment.
198+
res = rx_fragment_tree_update(&root, //
199+
mem_frag,
200+
del_payload,
201+
make_frame_base(mem_payload, 8, "xyz"),
202+
100,
203+
11,
204+
&cov);
205+
TEST_ASSERT_EQUAL(rx_fragment_tree_not_done, res);
206+
TEST_ASSERT_EQUAL_size_t(4, cov); // not extended due to the gap in the middle.
207+
TEST_ASSERT_NOT_NULL(root);
208+
TEST_ASSERT_EQUAL(2, tree_count(root));
209+
// Add fragment.
210+
res = rx_fragment_tree_update(&root, //
211+
mem_frag,
212+
del_payload,
213+
make_frame_base(mem_payload, 4, "def"),
214+
100,
215+
11,
216+
&cov);
217+
TEST_ASSERT_EQUAL(rx_fragment_tree_done, res);
218+
TEST_ASSERT_EQUAL_size_t(12, cov); // extended to cover the two remaining frames.
219+
TEST_ASSERT_NOT_NULL(root);
220+
TEST_ASSERT_EQUAL(3, tree_count(root));
221+
// Check the retained payload.
222+
TEST_ASSERT_EQUAL_size_t(0, fragment_at(root, 0)->offset);
223+
TEST_ASSERT_EQUAL_size_t(4, fragment_at(root, 0)->view.size);
224+
TEST_ASSERT_EQUAL_STRING("abc", fragment_at(root, 0)->view.data);
225+
TEST_ASSERT_EQUAL_size_t(4, fragment_at(root, 1)->offset);
226+
TEST_ASSERT_EQUAL_size_t(4, fragment_at(root, 1)->view.size);
227+
TEST_ASSERT_EQUAL_STRING("def", fragment_at(root, 1)->view.data);
228+
TEST_ASSERT_EQUAL_size_t(8, fragment_at(root, 2)->offset);
229+
TEST_ASSERT_EQUAL_size_t(4, fragment_at(root, 2)->view.size);
230+
TEST_ASSERT_EQUAL_STRING("xyz", fragment_at(root, 2)->view.data);
231+
TEST_ASSERT_NULL(fragment_at(root, 3));
232+
// Check the heap.
233+
TEST_ASSERT_EQUAL_size_t(3, alloc_frag.allocated_fragments);
234+
TEST_ASSERT_EQUAL_size_t(3, alloc_payload.allocated_fragments);
235+
TEST_ASSERT_EQUAL_size_t(3, alloc_frag.count_alloc);
236+
TEST_ASSERT_EQUAL_size_t(3, alloc_payload.count_alloc);
237+
TEST_ASSERT_EQUAL_size_t(0, alloc_frag.count_free);
238+
TEST_ASSERT_EQUAL_size_t(0, alloc_payload.count_free);
239+
// Free the tree (as in freedom). The free tree is free to manifest its own destiny.
240+
udpard_fragment_free_all((udpard_fragment_t*)root, mem_frag);
241+
// Check the heap.
242+
TEST_ASSERT_EQUAL_size_t(0, alloc_frag.allocated_fragments);
243+
TEST_ASSERT_EQUAL_size_t(0, alloc_payload.allocated_fragments);
244+
TEST_ASSERT_EQUAL_size_t(3, alloc_frag.count_alloc);
245+
TEST_ASSERT_EQUAL_size_t(3, alloc_payload.count_alloc);
246+
TEST_ASSERT_EQUAL_size_t(3, alloc_frag.count_free);
247+
TEST_ASSERT_EQUAL_size_t(3, alloc_payload.count_free);
248+
}
176249
}
177250

178251
static void test_rx_transfer_id_forward_distance(void)

0 commit comments

Comments
 (0)