[Test] (P11 B2): the unset knob on a stream and on a no-AHardwareBuffer shared-segment session - T2, no W/I fallback line, the fallback counted; the 0x80 ask accepted and 0x81 refused

This commit is contained in:
2026-09-29 20:15:29 -04:00
parent b32140e614
commit 91900bdc5e
4 changed files with 75 additions and 3 deletions
@@ -567,6 +567,19 @@ TEST_F(SplitBufferSet, TheAdoptTierIsSettledAtTheHandshakeAndNeverFatal) {
EXPECT_EQ(Tier::SettleAdoptTierAtHandshake(false, Tier::AdoptTierSide::Server), 2u);
EXPECT_TRUE(MG_Remote::Client::AdoptTierIsEmulate());
}
// UNSET (the default since 2026-09-29): a T0 ask of its own kind over shared segments, 2 over a
// stream, and a session-free caller runs T2 quietly instead of dying - it never named a tier.
MG_Config::Ipc.AdoptTier = MG_Config::kAdoptTierUnset;
Tier::ForgetAdoptTierSettlementForTest();
EXPECT_TRUE(MG_Remote::Client::AdoptTierIsEmulate());
EXPECT_EQ(Tier::AdoptTierAskFor(false), Tier::kAdoptAskT0Default);
EXPECT_EQ(Tier::AdoptTierAskFor(true), 2u);
EXPECT_EQ(Tier::SettleAdoptTierAtHandshake(false, Tier::AdoptTierSide::Client), Tier::kAdoptAskT0Default);
for (const auto side : {Tier::AdoptTierSide::Client, Tier::AdoptTierSide::Server}) {
Tier::ForgetAdoptTierSettlementForTest();
EXPECT_EQ(Tier::SettleAdoptTierAtHandshake(true, side), 2u);
}
EXPECT_TRUE(MG_Remote::Client::AdoptTierIsEmulate());
MG_Config::Ipc.AdoptTier = 2;
}
@@ -151,6 +151,33 @@ TEST(AdoptTierStream, AClientNamingT0OrT1IsRefusedOnceAndItsMapPersistentIsDecli
}
}
// P11 B2: THE KNOB UNSET - T0 BY DEFAULT since 2026-09-29 - ON A STREAM. The Hello asks 2 (a stream
// carries T2 only), the session runs T2, and nothing says so above MGLOG_D: every tcp session would
// otherwise carry A1's line. The client still COUNTS the fallback (ClientSession::T0Fallbacks,
// reported through PeerReport::pixel). The supervisor's own knob is unset as well (ServerSpawn
// scrubs it), so its stream settle is quiet too.
// RED-ONCE: log the unset stream settle at W instead of D -> one AdoptTierOnStream line, not 0.
TEST(AdoptTierStream, AnUnsetKnobRunsT2OnAStreamQuietlyAndCountsTheFallback) {
ServerProcess server;
ASSERT_TRUE(LaunchSupervisor("adopt-unset", &server)) << server.Log();
const auto body = [](Remote::Client::ClientSession& client, PeerReport& r) {
MapPersistentThenARecord(client, r);
r.pixel = static_cast<Uint32>(client.T0Fallbacks());
};
const PeerReport r = RunPeer(server.endpoint, body, /*stopCleanly=*/true, 30000, 0, nullptr,
[] { MG_Config::Ipc.AdoptTier = MG_Config::kAdoptTierUnset; });
const std::string client = ClientLog(server);
ASSERT_EQ(r.started, 1) << "the session did not come up: " << r.note << "\n" << client;
EXPECT_EQ(r.status, Remote::Wire::ReplySink::kStatusDeclined) << "a stream session runs T2\n" << client;
EXPECT_EQ(r.applied, 1) << client;
EXPECT_EQ(r.pixel, 1u) << "the stream's T0 fallback was not counted\n" << client;
for (const char* line : {"AdoptTierOnStream", "T0 by default", "AdoptT0Unavailable", "T0 session totals"}) {
EXPECT_EQ(Count(client, line), 0u) << "an unset knob's fallback is MGLOG_D only: " << line << "\n" << client;
EXPECT_EQ(Count(server.Log(), line), 0u) << line << "\n" << server.Log();
}
EXPECT_EQ(Count(client, "Fatal{"), 0u) << client;
}
TEST(AdoptTierStream, AServerNamingT0RefusesOncePerSessionAndServesT2) {
ServerProcess server;
const std::string peerBase = "/tmp/mgl-p11-adopt-server-peers-" + std::to_string(::getpid()) + ".log";
@@ -242,6 +242,36 @@ TEST(RemoteClientAdoptT0, KnobTwoIsTodaysT2WithNoT0Line) {
EXPECT_EQ(child.Log.find("Fatal{"), std::string::npos) << child.Log;
}
// THE KNOB UNSET - T0 BY DEFAULT, the user's decision of 2026-09-29 - over shared segments on the
// host's own platform (no AHardwareBuffer): the Hello asks T0 of its default kind, the server
// refuses it at its first bind and the client falls back at its first map_persistent - both
// QUIETLY (MGLOG_D only: every host session would otherwise carry two lines), both COUNTED.
// Knob 0's named lines are KnobZero... / NoAhardwareBuffer... above; this is the unset half.
// RED-ONCE: log the unset path's fallbacks at W instead of D -> the line counts below are 1, not 0.
TEST(RemoteClientAdoptT0, AnUnsetKnobFallsBackToT2QuietlyAndCountsIt) {
const auto child = RunInChild([] {
MG_Config::Ipc.AdoptTier = MG_Config::kAdoptTierUnset;
MG_Pipe::MGPipeSetResourceOps(&g_fakeOps); // a backend WITH the members: the platform decides
StartControlSession();
if (!Srv::ServerSessionInstance().AdoptT0Asked()) ::_exit(210); // the Hello asked T0 by default
if (!Srv::ServerSessionInstance().AdoptT0Quiet()) ::_exit(211);
GrantAtFirstBind();
if (Srv::ServerSessionInstance().AdoptT0()) ::_exit(212);
if (Srv::ServerSessionInstance().T0Refusals() != 1) ::_exit(213); // counted, not said
const auto seed = Pattern(kT0Bytes, 0x66);
const MGPHandleOnly handle = MakeBufferStore(5, kT0Bytes);
if (MGPipeRouteMapPersistent(handle, kT0Bytes, seed.data()) != nullptr) ::_exit(214); // T2: declined
if (ClientSessionInstance().AdoptT0()) ::_exit(215);
if (ClientSessionInstance().T0Fallbacks() != 1) ::_exit(216); // counted, not said
ClientSessionInstance().Stop();
});
ExpectChildSuccess(child);
for (const char* line : {"AdoptT0Unavailable", "T0 by default", "T0 POST", "T0 session totals", "Refuse{"})
EXPECT_EQ(CountOf(child.Log, line), 0u) << "an unset knob's fallback is MGLOG_D only: " << line << "\n"
<< child.Log;
EXPECT_EQ(child.Log.find("Fatal{"), std::string::npos) << child.Log;
}
// Knob 1 names T1, which P11 closed: one named refusal, the Hello asks T2, never a Fatal.
TEST(RemoteClientAdoptT0, KnobOneIsRefusedByNameAndAsksT2) {
const auto child = RunInChild([] {
@@ -285,7 +285,8 @@ TEST(SessionHandshakeTest, ARevisionFourPeerIsRefusedByNameAtRevisionFive) {
// legal ask is the Welcome's.
TEST(SessionHandshakeTest, AHelloAskingAnAdoptTierThatIsNotAnAskIsRefusedByName) {
using namespace ::MobileGL::Wire;
for (const Uint8 ask : {Uint8{0}, Uint8{1}, Uint8{2}, Uint8{7}}) {
// 0x80 is the T0 ask of an unset knob (T0 by default, refusals quiet); 0x81 is not an ask.
for (const Uint8 ask : {Uint8{0}, Uint8{1}, Uint8{2}, Uint8{7}, Uint8{0x80}, Uint8{0x81}}) {
SCOPED_TRACE(static_cast<int>(ask));
std::unique_ptr<Transport::InProcessTransport> client, server;
Transport::InProcessTransport::CreatePair(client, server);
@@ -302,7 +303,7 @@ TEST(SessionHandshakeTest, AHelloAskingAnAdoptTierThatIsNotAnAskIsRefusedByName)
sizes.CmdRingBytes = 4096; sizes.StageBytes = 4096;
sizes.ReplyBytes = 4096; sizes.EventRingBytes = 4096;
session.SetSegmentSizes(sizes);
const Bool legal = ask == 0 || ask == 2;
const Bool legal = ask == 0 || ask == 2 || ask == 0x80;
EXPECT_EQ(session.Accept(*server, &first), legal ? MOBILEGL_OK : MOBILEGL_ERR_PROTOCOL_MISMATCH);
const auto reply = ReadHandshakeFrame(*client);
ASSERT_FALSE(reply.empty());
@@ -311,7 +312,8 @@ TEST(SessionHandshakeTest, AHelloAskingAnAdoptTierThatIsNotAnAskIsRefusedByName)
ASSERT_NE(envelope->msg_as_Welcome(), nullptr);
ASSERT_NE(envelope->msg_as_Welcome()->linkTerms(), nullptr);
EXPECT_EQ(envelope->msg_as_Welcome()->linkTerms()->adoptTier(), ask) << "the Welcome echoes the ask";
EXPECT_EQ(session.AdoptT0Asked(), ask == 0);
EXPECT_EQ(session.AdoptT0Asked(), ask == 0 || ask == 0x80);
EXPECT_EQ(session.AdoptT0Quiet(), ask == 0x80) << "only the default ask is quiet";
EXPECT_FALSE(session.AdoptT0()) << "no grant before the first native bind";
} else {
ASSERT_NE(envelope->msg_as_Refuse(), nullptr);