@@ -425,6 +425,9 @@ TEST_CASE("rxSessionUpdate")
425425
426426 Instance ins;
427427 ins.getAllocator ().setAllocationCeiling (16 );
428+ Instance ins_1;
429+ ins_1.getAllocator ().setAllocationCeiling (16 );
430+
428431
429432 RxFrameModel frame;
430433 frame.timestamp_usec = 10'000'000 ;
@@ -440,8 +443,11 @@ TEST_CASE("rxSessionUpdate")
440443 frame.payload = reinterpret_cast <const uint8_t *>(" \x01\x01\x01 " );
441444
442445 RxSession rxs;
446+ RxSession rxs_1;
443447 rxs.transfer_id = 31 ;
444448 rxs.redundant_transport_index = 1 ;
449+ rxs_1.transfer_id = 32 ;
450+ rxs_1.redundant_transport_index = 1 ;
445451
446452 UdpardRxTransfer transfer{};
447453
@@ -457,7 +463,19 @@ TEST_CASE("rxSessionUpdate")
457463 &transfer);
458464 };
459465
460- // const auto crc = [](const char* const string) { return crcAdd(0xFFFF, std::strlen(string), string); };
466+ const auto updateAnotherSession = [&](const std::uint8_t redundant_transport_index,
467+ const std::uint64_t tid_timeout_usec,
468+ const std::size_t extent) {
469+ return rxSessionUpdate (&ins_1.getInstance (),
470+ &rxs_1,
471+ &frame,
472+ redundant_transport_index,
473+ tid_timeout_usec,
474+ extent,
475+ &transfer);
476+ };
477+
478+ const auto crc = [](const char * const string) { return crcAdd (0xFFFFFFFFU , std::strlen (string), string); };
461479
462480 // Accept one transfer.
463481 REQUIRE (1 == update (1 , 1'000'000 , 16 ));
@@ -548,6 +566,120 @@ TEST_CASE("rxSessionUpdate")
548566 REQUIRE (ins.getAllocator ().getTotalAllocatedAmount () == 16 );
549567 ins.getAllocator ().deallocate (transfer.payload );
550568
569+ // Multi-frame, first frame
570+ frame.timestamp_usec = 20'000'100 ;
571+ frame.transfer_id = 13 ;
572+ frame.end_of_transfer = false ;
573+ frame.payload_size = 7 ;
574+ frame.frame_index = 1 ;
575+ frame.payload = reinterpret_cast <const uint8_t *>(" \x06\x06\x06\x06\x06\x06\x06 " );
576+ REQUIRE (0 == update (0 , 1'000'000 , 16 ));
577+
578+ REQUIRE (rxs.transfer_timestamp_usec == 20'000'100 );
579+ REQUIRE (rxs.payload_size == 7 );
580+ REQUIRE (0 == std::memcmp (rxs.payload , " \x06\x06\x06\x06\x06\x06\x06 " , 7 ));
581+ REQUIRE (rxs.calculated_crc == crc (" \x06\x06\x06\x06\x06\x06\x06 " ));
582+ REQUIRE (rxs.transfer_id == 13U );
583+ REQUIRE (rxs.redundant_transport_index == 0 );
584+ REQUIRE (ins.getAllocator ().getNumAllocatedFragments () == 1 );
585+ REQUIRE (ins.getAllocator ().getTotalAllocatedAmount () == 16 );
586+
587+ // Update another session using same frame.
588+ REQUIRE (0 == updateAnotherSession (1 , 1'000'000 , 16 ));
589+ REQUIRE (rxs_1.transfer_timestamp_usec == 20'000'100 );
590+ REQUIRE (rxs_1.payload_size == 7 );
591+ REQUIRE (0 == std::memcmp (rxs_1.payload , " \x06\x06\x06\x06\x06\x06\x06 " , 7 ));
592+ REQUIRE (rxs_1.calculated_crc == crc (" \x06\x06\x06\x06\x06\x06\x06 " ));
593+ REQUIRE (rxs_1.transfer_id == 13U );
594+ REQUIRE (rxs_1.redundant_transport_index == 1 );
595+ REQUIRE (ins_1.getAllocator ().getNumAllocatedFragments () == 1 );
596+ REQUIRE (ins_1.getAllocator ().getTotalAllocatedAmount () == 16 );
597+
598+ // Multi-frame, bad middle, out-of-order
599+ frame.timestamp_usec = 20'000'200 ;
600+ frame.start_of_transfer = false ;
601+ frame.end_of_transfer = false ;
602+ frame.frame_index = 3 + (uint32_t ) (1U << (uint32_t ) 31U );
603+ frame.payload_size = 2 ;
604+ frame.payload = reinterpret_cast <const uint8_t *>(" \x09\x09 " );
605+ REQUIRE (-UDPARD_ERROR_OUT_OF_ORDER == update (0 , 1'000'000 , 16 ));
606+ // Update another session using same frame, fail.
607+ REQUIRE (-UDPARD_ERROR_OUT_OF_ORDER == updateAnotherSession (1 , 1'000'000 , 16 ));
608+
609+ // Multi-frame, middle.
610+ frame.timestamp_usec = 20'000'200 ;
611+ frame.start_of_transfer = false ;
612+ frame.end_of_transfer = false ;
613+ frame.frame_index = 2 ;
614+ frame.payload_size = 7 ;
615+ frame.payload = reinterpret_cast <const uint8_t *>(" \x07\x07\x07\x07\x07\x07\x07 " );
616+ REQUIRE (0 == update (0 , 1'000'000 , 16 ));
617+ REQUIRE (rxs.transfer_timestamp_usec == 20'000'100 );
618+ REQUIRE (rxs.payload_size == 14 );
619+ REQUIRE (0 == std::memcmp (rxs.payload , " \x06\x06\x06\x06\x06\x06\x06\x07\x07\x07\x07\x07\x07\x07 " , 14 ));
620+ REQUIRE (rxs.calculated_crc == crc (" \x06\x06\x06\x06\x06\x06\x06\x07\x07\x07\x07\x07\x07\x07 " ));
621+ REQUIRE (rxs.transfer_id == 13U );
622+ REQUIRE (rxs.redundant_transport_index == 0 );
623+ REQUIRE (ins.getAllocator ().getNumAllocatedFragments () == 1 );
624+ REQUIRE (ins.getAllocator ().getTotalAllocatedAmount () == 16 );
625+
626+ // Update another session using same frame.
627+ REQUIRE (0 == updateAnotherSession (1 , 1'000'000 , 16 ));
628+ REQUIRE (rxs_1.transfer_timestamp_usec == 20'000'100 );
629+ REQUIRE (rxs_1.payload_size == 14 );
630+ REQUIRE (0 == std::memcmp (rxs_1.payload , " \x06\x06\x06\x06\x06\x06\x06\x07\x07\x07\x07\x07\x07\x07 " , 14 ));
631+ REQUIRE (rxs_1.calculated_crc == crc (" \x06\x06\x06\x06\x06\x06\x06\x07\x07\x07\x07\x07\x07\x07 " ));
632+ REQUIRE (rxs_1.transfer_id == 13U );
633+ REQUIRE (rxs_1.redundant_transport_index == 1 );
634+ REQUIRE (ins_1.getAllocator ().getNumAllocatedFragments () == 1 );
635+ REQUIRE (ins_1.getAllocator ().getTotalAllocatedAmount () == 16 );
636+
637+ // Multi-frame, last.
638+ frame.timestamp_usec = 20'000'400 ;
639+ frame.start_of_transfer = false ;
640+ frame.end_of_transfer = true ;
641+ frame.frame_index = 3 + (uint32_t ) (1U << (uint32_t ) 31U );
642+ frame.payload_size = 8 ; // The payload is IMPLICITLY TRUNCATED, and the CRC IS STILL VALIDATED.
643+ frame.payload = reinterpret_cast <const uint8_t *>(" \x09\x09\x09\x09\x32\x98\x04\x7B " );
644+ REQUIRE (1 == update (0 , 1'000'000 , 16 ));
645+ REQUIRE (rxs.transfer_timestamp_usec == 20'000'100 ); // First frame.
646+ REQUIRE (rxs.payload_size == 0 );
647+ REQUIRE (rxs.payload == nullptr );
648+ REQUIRE (rxs.calculated_crc == 0xFFFFFFFFU );
649+ REQUIRE (rxs.transfer_id == 14U );
650+ REQUIRE (rxs.redundant_transport_index == 0 );
651+ REQUIRE (transfer.timestamp_usec == 20'000'100 );
652+ REQUIRE (transfer.metadata .priority == UdpardPrioritySlow);
653+ REQUIRE (transfer.metadata .transfer_kind == UdpardTransferKindMessage);
654+ REQUIRE (transfer.metadata .port_id == 2'222 );
655+ REQUIRE (transfer.metadata .remote_node_id == 55 );
656+ REQUIRE (transfer.metadata .transfer_id == 13 );
657+ REQUIRE (transfer.payload_size == 16 );
658+ REQUIRE (0 == std::memcmp (transfer.payload , " \x06\x06\x06\x06\x06\x06\x06\x07\x07\x07\x07\x07\x07\x07\x09\x09 " , 16 ));
659+ REQUIRE (ins.getAllocator ().getNumAllocatedFragments () == 1 );
660+ REQUIRE (ins.getAllocator ().getTotalAllocatedAmount () == 16 );
661+ ins.getAllocator ().deallocate (transfer.payload );
662+
663+ // Update another session using same frame.
664+ REQUIRE (1 == updateAnotherSession (1 , 1'000'000 , 16 ));
665+ REQUIRE (rxs_1.transfer_timestamp_usec == 20'000'100 ); // First frame.
666+ REQUIRE (rxs_1.payload_size == 0 );
667+ REQUIRE (rxs_1.payload == nullptr );
668+ REQUIRE (rxs_1.calculated_crc == 0xFFFFFFFFU );
669+ REQUIRE (rxs_1.transfer_id == 14U );
670+ REQUIRE (rxs_1.redundant_transport_index == 1 );
671+ REQUIRE (transfer.timestamp_usec == 20'000'100 );
672+ REQUIRE (transfer.metadata .priority == UdpardPrioritySlow);
673+ REQUIRE (transfer.metadata .transfer_kind == UdpardTransferKindMessage);
674+ REQUIRE (transfer.metadata .port_id == 2'222 );
675+ REQUIRE (transfer.metadata .remote_node_id == 55 );
676+ REQUIRE (transfer.metadata .transfer_id == 13 );
677+ REQUIRE (transfer.payload_size == 16 );
678+ REQUIRE (0 == std::memcmp (transfer.payload , " \x06\x06\x06\x06\x06\x06\x06\x07\x07\x07\x07\x07\x07\x07\x09\x09 " , 16 ));
679+ REQUIRE (ins_1.getAllocator ().getNumAllocatedFragments () == 1 );
680+ REQUIRE (ins_1.getAllocator ().getTotalAllocatedAmount () == 16 );
681+ ins_1.getAllocator ().deallocate (transfer.payload );
682+
551683 // Restart by TID timeout, not the first frame.
552684 frame.timestamp_usec = 30'000'000 ;
553685 frame.transfer_id = 12 ; // Goes back.
@@ -556,7 +688,7 @@ TEST_CASE("rxSessionUpdate")
556688 frame.payload_size = 7 ;
557689 frame.payload = reinterpret_cast <const uint8_t *>(" \x0A\x0A\x0A\x0A\x0A\x0A\x0A " );
558690 REQUIRE (0 == update (2 , 1'000'000 , 16 ));
559- REQUIRE (rxs.transfer_timestamp_usec == 20'000'000 ); // No change.
691+ REQUIRE (rxs.transfer_timestamp_usec == 20'000'100 ); // No change.
560692 REQUIRE (rxs.payload_size == 0 );
561693 REQUIRE (rxs.payload == nullptr );
562694 REQUIRE (rxs.calculated_crc == 0xFFFFFFFFU );
0 commit comments