Skip to content

Commit b001246

Browse files
JohnLyu2copybara-github
authored andcommitted
Add TransferReceiveSession lifecycle and drain tests.
PiperOrigin-RevId: 1010611883
1 parent 64dfdda commit b001246

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

‎tpu_sync/kv_cache/kv_cache_manager_with_transfer_send_drain_test.cc‎

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)