Skip to content

Commit f187562

Browse files
tests
1 parent f4a875f commit f187562

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

tests/src/test_intrusive_tx.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,85 @@ static void test_tx_spool_deduplication(void)
11421142
TEST_ASSERT_EQUAL_size_t(0, alloc_b.allocated_fragments);
11431143
}
11441144

1145+
// Verifies that eject callbacks are ONLY invoked from udpard_tx_poll(), never from push functions.
1146+
static void test_tx_eject_only_from_poll(void)
1147+
{
1148+
instrumented_allocator_t alloc = { 0 };
1149+
instrumented_allocator_new(&alloc);
1150+
udpard_tx_mem_resources_t mem = { .transfer = instrumented_allocator_make_resource(&alloc) };
1151+
for (size_t i = 0; i < UDPARD_IFACE_COUNT_MAX; i++) {
1152+
mem.payload[i] = instrumented_allocator_make_resource(&alloc);
1153+
}
1154+
1155+
udpard_tx_t tx = { 0 };
1156+
eject_state_t eject = { .count = 0, .allow = true };
1157+
udpard_tx_vtable_t vt = { .eject_subject = eject_subject_with_flag, .eject_p2p = eject_p2p_with_flag };
1158+
TEST_ASSERT_TRUE(udpard_tx_new(&tx, 60U, 1U, 16U, mem, &vt));
1159+
tx.user = &eject;
1160+
1161+
const uint16_t iface_bitmap_1 = (1U << 0U);
1162+
1163+
// Push a subject transfer; eject must NOT be called.
1164+
eject.count = 0;
1165+
TEST_ASSERT_TRUE(udpard_tx_push(
1166+
&tx, 0, 1000, iface_bitmap_1, udpard_prio_fast, 100, 1, make_scattered(NULL, 0), NULL, UDPARD_USER_CONTEXT_NULL));
1167+
TEST_ASSERT_EQUAL_size_t(0, eject.count); // eject NOT called from push
1168+
1169+
// Push a P2P transfer; eject must NOT be called.
1170+
const udpard_remote_t remote = { .uid = 999, .endpoints = { make_ep(10) } };
1171+
TEST_ASSERT_TRUE(udpard_tx_push_p2p(&tx,
1172+
0,
1173+
1000,
1174+
udpard_prio_fast,
1175+
0xABCD,
1176+
42,
1177+
remote,
1178+
make_scattered(NULL, 0),
1179+
NULL,
1180+
UDPARD_USER_CONTEXT_NULL,
1181+
NULL));
1182+
TEST_ASSERT_EQUAL_size_t(0, eject.count); // eject NOT called from push_p2p
1183+
1184+
// Now poll; eject MUST be called.
1185+
udpard_tx_poll(&tx, 0, UDPARD_IFACE_BITMAP_ALL);
1186+
TEST_ASSERT_GREATER_THAN_size_t(0, eject.count); // eject called from poll
1187+
1188+
// Push more transfers while frames are pending; eject still must NOT be called.
1189+
const size_t eject_count_before = eject.count;
1190+
eject.allow = false; // block ejection to keep frames pending
1191+
TEST_ASSERT_TRUE(udpard_tx_push(&tx,
1192+
0,
1193+
1000,
1194+
iface_bitmap_1,
1195+
udpard_prio_nominal,
1196+
200,
1197+
2,
1198+
make_scattered(NULL, 0),
1199+
NULL,
1200+
UDPARD_USER_CONTEXT_NULL));
1201+
TEST_ASSERT_EQUAL_size_t(eject_count_before, eject.count); // eject NOT called from push
1202+
1203+
TEST_ASSERT_TRUE(udpard_tx_push_p2p(&tx,
1204+
0,
1205+
1000,
1206+
udpard_prio_nominal,
1207+
0xBEEF,
1208+
99,
1209+
remote,
1210+
make_scattered(NULL, 0),
1211+
NULL,
1212+
UDPARD_USER_CONTEXT_NULL,
1213+
NULL));
1214+
TEST_ASSERT_EQUAL_size_t(eject_count_before, eject.count); // eject NOT called from push_p2p
1215+
1216+
// Poll again; eject called again (but rejected by callback).
1217+
udpard_tx_poll(&tx, 0, UDPARD_IFACE_BITMAP_ALL);
1218+
TEST_ASSERT_GREATER_THAN_size_t(eject_count_before, eject.count); // eject called from poll
1219+
1220+
udpard_tx_free(&tx);
1221+
instrumented_allocator_reset(&alloc);
1222+
}
1223+
11451224
void setUp(void) {}
11461225

11471226
void tearDown(void) {}
@@ -1161,6 +1240,7 @@ int main(void)
11611240
RUN_TEST(test_tx_cancel_p2p);
11621241
RUN_TEST(test_tx_cancel_all);
11631242
RUN_TEST(test_tx_spool_deduplication);
1243+
RUN_TEST(test_tx_eject_only_from_poll);
11641244
RUN_TEST(test_tx_ack_and_scheduler);
11651245
return UNITY_END();
11661246
}

0 commit comments

Comments
 (0)