@@ -1784,5 +1784,90 @@ TEST(RecvLifecycleTest,
17841784 StatusIs (absl::StatusCode::kNotFound ));
17851785}
17861786
1787+ // ExecuteLayerH2d: H2dSyncDispatch fails. The receive finishes with the
1788+ // dispatch error in the h2d phase, releases the op it took and settles at
1789+ // once, since no copy was issued; the poll reports it failed.
1790+ TEST (RecvLifecycleTest, FailedH2dDispatchFailsAndSettlesTheReceive) {
1791+ GetFaultInjector ().Reset ();
1792+ absl::Cleanup reset_faults = [] { GetFaultInjector ().Reset (); };
1793+ FaultInjectionRule failed_dispatch;
1794+ failed_dispatch.hook = std::string (hooks::kTransferRecvSessionH2dDispatch );
1795+ failed_dispatch.probability = 1.0 ;
1796+ ABSL_ASSERT_OK (GetFaultInjector ().Install ({failed_dispatch}));
1797+
1798+ RecvTestManager consumer (/* num_layers=*/ 1 );
1799+ consumer.AddRecv (" req" , /* uuid=*/ 501 );
1800+ EXPECT_FALSE (consumer.ReceiveLayer (/* layer=*/ 0 , /* uuid=*/ 501 ).ok ());
1801+ EXPECT_EQ (consumer.copies_issued (), 0 );
1802+ EXPECT_EQ (consumer.free_slots (), kSlots );
1803+
1804+ CompleteReadResult completions = consumer.CompleteReadWithDetails ();
1805+ EXPECT_THAT (completions.received , IsEmpty ());
1806+ EXPECT_THAT (completions.failed , ElementsAre (" req" ));
1807+ EXPECT_EQ (completions.details [" req" ].phase , " h2d" );
1808+ EXPECT_FALSE (consumer.has_recv (501 ));
1809+ }
1810+
1811+ // A second Finish(error) on a draining receive changes nothing: the first
1812+ // error is the one reported, once, when the copy ends.
1813+ TEST (RecvLifecycleTest, SecondFinishOnAFailedReceiveIsANoOp) {
1814+ RecvTestManager consumer (/* num_layers=*/ 1 , /* timeout_s=*/ 10.0 );
1815+ consumer.AddRecv (" req" , /* uuid=*/ 502 );
1816+ ABSL_ASSERT_OK (consumer.ReceiveLayer (/* layer=*/ 0 , /* uuid=*/ 502 ));
1817+ consumer.FailRecv (/* uuid=*/ 502 , absl::InternalError (" first" ));
1818+ consumer.FailRecv (/* uuid=*/ 502 , absl::UnavailableError (" second" ));
1819+ EXPECT_TRUE (consumer.has_recv (502 ));
1820+ EXPECT_EQ (consumer.free_slots (), kSlots - 1 );
1821+
1822+ consumer.FinishCopy (0 , absl::OkStatus ());
1823+ CompleteReadResult completions = consumer.CompleteReadWithDetails ();
1824+ EXPECT_THAT (completions.failed , ElementsAre (" req" ));
1825+ EXPECT_EQ (completions.details [" req" ].code , " INTERNAL" );
1826+ EXPECT_EQ (completions.details [" req" ].reason , " first" );
1827+ EXPECT_EQ (consumer.free_slots (), kSlots );
1828+ EXPECT_THAT (consumer.CompleteReadWithDetails ().failed , IsEmpty ());
1829+ }
1830+
1831+ // An incoming push lease that closes while the layer's copy is still
1832+ // running, the usual order for an asynchronous H2D: the lease release
1833+ // neither settles the receive nor returns its staging; the copy's
1834+ // completion does.
1835+ TEST (RecvLifecycleTest, PushLeaseClosingBeforeTheCopyEndsDoesNotSettle) {
1836+ RecvTestManager consumer (/* num_layers=*/ 1 , /* timeout_s=*/ 10.0 );
1837+ consumer.AddRecv (" req" , /* uuid=*/ 503 );
1838+ ABSL_ASSERT_OK (consumer.base ()->BeginIncomingPush (/* uuid=*/ 503 ));
1839+ ABSL_ASSERT_OK (consumer.ReceiveLayer (/* layer=*/ 0 , /* uuid=*/ 503 ));
1840+ ABSL_ASSERT_OK (consumer.ReceiveBlocks ({0 }, /* uuid=*/ 503 ));
1841+ ABSL_ASSERT_OK (consumer.base ()->EndIncomingPush (/* uuid=*/ 503 ));
1842+
1843+ Reports during = consumer.CompleteReadRaw ();
1844+ EXPECT_THAT (DoneReceiving (during), IsEmpty ());
1845+ EXPECT_TRUE (consumer.has_recv (503 ));
1846+ EXPECT_EQ (consumer.free_slots (), kSlots - 1 );
1847+
1848+ consumer.FinishCopy (0 , absl::OkStatus ());
1849+ Reports after = consumer.CompleteReadRaw ();
1850+ EXPECT_THAT (DoneReceiving (after), ElementsAre (" req" ));
1851+ EXPECT_EQ (consumer.free_slots (), kSlots );
1852+ }
1853+
1854+ // A cancelled receive whose only copy then fails keeps the cancellation: the
1855+ // copy's error is absorbed by the draining receive, its callback ends the
1856+ // last op, and the receive settles and is reported failed once.
1857+ TEST (RecvDrainTest, CancelledReceiveWhoseCopyThenFailsStaysCancelled) {
1858+ RecvTestManager consumer (/* num_layers=*/ 1 , /* timeout_s=*/ 10.0 );
1859+ consumer.AddRecv (" req" , /* uuid=*/ 504 );
1860+ ABSL_ASSERT_OK (consumer.ReceiveLayer (/* layer=*/ 0 , /* uuid=*/ 504 ));
1861+ consumer.FailRecv (/* uuid=*/ 504 , absl::CancelledError (" cancel" ));
1862+ EXPECT_EQ (consumer.free_slots (), kSlots - 1 );
1863+
1864+ consumer.FinishCopy (0 , absl::InternalError (" copy failed" ));
1865+ EXPECT_EQ (consumer.free_slots (), kSlots );
1866+ CompleteReadResult completions = consumer.CompleteReadWithDetails ();
1867+ EXPECT_THAT (completions.failed , ElementsAre (" req" ));
1868+ EXPECT_EQ (completions.details [" req" ].code , " CANCELLED" );
1869+ EXPECT_THAT (consumer.CompleteReadWithDetails ().failed , IsEmpty ());
1870+ }
1871+
17871872} // namespace
17881873} // namespace tpu_raiden
0 commit comments