mirror of
https://github.com/InstanceBrick/nightcap.git
synced 2026-10-17 21:00:47 +02:00
fix(webview): allow 5 s for helper startup and log its timing
Slow starts (cold Flatpak) could exceed the 3 s ready deadline and kill login verification windows. Launch and timeout logs now report elapsed ms.
This commit is contained in:
1 parent
5f83c4a64f
commit
9b041ec2ac
2 files changed
+66
-6
No files matched your search
@@ -22,7 +22,8 @@ namespace {
|
||||
constexpr size_t kMaxPendingLaunchRequests = 8;
|
||||
// libroblox's static TLS requires the proven 16 MiB guest-thread stack floor.
|
||||
constexpr size_t kLaunchWorkerStackSize = 64ULL * 1024 * 1024;
|
||||
constexpr std::chrono::milliseconds kWebSurfaceReadyTimeout{3000};
|
||||
// Covers helper exec through window creation, including cold Flatpak starts.
|
||||
constexpr std::chrono::milliseconds kWebSurfaceReadyTimeout{5000};
|
||||
constexpr char kRobloxBaseUrl[] = "https://www.roblox.com/";
|
||||
|
||||
Status Invalid(std::string message) {
|
||||
@@ -159,24 +160,33 @@ Status LaunchRobloxWebSurface(
|
||||
}
|
||||
std::fprintf(stderr, " [%s] opening validated Roblox web surface\n",
|
||||
transport);
|
||||
const auto started = std::chrono::steady_clock::now();
|
||||
const WebViewHelperLaunchResult launched =
|
||||
LaunchWebViewHelper(helper, url, std::move(exit_observer));
|
||||
if (!launched) {
|
||||
return Unavailable("could not display Roblox web surface: " +
|
||||
launched.error);
|
||||
}
|
||||
if (launched.process == nullptr ||
|
||||
!launched.process->WaitUntilReady(kWebSurfaceReadyTimeout)) {
|
||||
const bool ready = launched.process != nullptr &&
|
||||
launched.process->WaitUntilReady(kWebSurfaceReadyTimeout);
|
||||
const long long elapsed_ms =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - started)
|
||||
.count();
|
||||
if (!ready) {
|
||||
if (launched.process != nullptr) {
|
||||
(void)launched.process->RequestClose();
|
||||
}
|
||||
return Unavailable(
|
||||
"Roblox web surface did not become ready before the deadline");
|
||||
"Roblox web surface did not become ready before the deadline (" +
|
||||
std::to_string(elapsed_ms) + " ms of " +
|
||||
std::to_string(kWebSurfaceReadyTimeout.count()) + " ms)");
|
||||
}
|
||||
if (process != nullptr) {
|
||||
*process = launched.process;
|
||||
}
|
||||
std::fprintf(stderr, " [%s] Roblox web surface launched\n", transport);
|
||||
std::fprintf(stderr, " [%s] Roblox web surface launched in %lld ms\n",
|
||||
transport, elapsed_ms);
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
|
||||
@@ -1023,7 +1023,7 @@ TEST(RobloxExperienceCompositionTest,
|
||||
class RobloxExperienceCompositionWebSurfaceTest : public ::testing::Test {
|
||||
protected:
|
||||
struct Helper {
|
||||
Helper() {
|
||||
explicit Helper(const char* before_ready = "") {
|
||||
char pattern[] = "/tmp/mocktail_surface_close_XXXXXX";
|
||||
const char* created = mkdtemp(pattern);
|
||||
if (created == nullptr) return;
|
||||
@@ -1035,6 +1035,7 @@ import socket, sys
|
||||
sys.stdin.buffer.read()
|
||||
s = socket.socket(fileno=198)
|
||||
s.settimeout(5)
|
||||
)PY" << before_ready << R"PY(
|
||||
s.send(b'MWVE' + bytes([1, 3, 0, 0]) + bytes(4))
|
||||
while True:
|
||||
packet = s.recv(1024 * 1024)
|
||||
@@ -1071,6 +1072,14 @@ while True:
|
||||
++static_cast<ExitProbe*>(context)->calls;
|
||||
}
|
||||
|
||||
static Status Open(RobloxExperienceComposition* composition,
|
||||
const std::shared_ptr<ExitProbe>& probe) {
|
||||
return composition->OpenWebSurface(
|
||||
"https://www.roblox.com/challenge/cdn/hybrid", "webview",
|
||||
RobloxExperienceComposition::WebSurfaceRoute::kWebView,
|
||||
{probe, &RobloxExperienceCompositionWebSurfaceTest::ObserveExit}, {});
|
||||
}
|
||||
|
||||
static std::unique_ptr<RobloxExperienceComposition> MakeComposition(
|
||||
const SecureRobloxCredential* credential = nullptr) {
|
||||
return std::make_unique<RobloxExperienceComposition>(
|
||||
@@ -1278,6 +1287,47 @@ TEST_F(RobloxExperienceCompositionWebSurfaceTest,
|
||||
EXPECT_EQ(probe->calls, 1);
|
||||
}
|
||||
|
||||
TEST_F(RobloxExperienceCompositionWebSurfaceTest,
|
||||
WaitsForSlowHelperStartupBeforeRejectingSurface) {
|
||||
Helper helper("import time\ntime.sleep(3.5)\n");
|
||||
ASSERT_FALSE(helper.path.empty());
|
||||
ASSERT_EQ(setenv("MOCKTAIL_WEBVIEW_HELPER", helper.path.c_str(), 1), 0);
|
||||
SecureRobloxCredential credential{".ROBLOSECURITY=typed-secret"};
|
||||
auto composition = MakeComposition(&credential);
|
||||
auto probe = std::make_shared<ExitProbe>();
|
||||
|
||||
::testing::internal::CaptureStderr();
|
||||
const Status status = Open(composition.get(), probe);
|
||||
const std::string log = ::testing::internal::GetCapturedStderr();
|
||||
unsetenv("MOCKTAIL_WEBVIEW_HELPER");
|
||||
|
||||
EXPECT_TRUE(status.ok()) << status.message();
|
||||
const std::string marker = "Roblox web surface launched in ";
|
||||
const size_t at = log.find(marker);
|
||||
ASSERT_NE(at, std::string::npos) << log;
|
||||
EXPECT_GE(std::stol(log.substr(at + marker.size())), 3500) << log;
|
||||
EXPECT_TRUE(Close(composition.get()).ok());
|
||||
}
|
||||
|
||||
TEST_F(RobloxExperienceCompositionWebSurfaceTest,
|
||||
ReportsElapsedStartupTimeWhenHelperNeverBecomesReady) {
|
||||
Helper helper("sys.exit(0)\n");
|
||||
ASSERT_FALSE(helper.path.empty());
|
||||
ASSERT_EQ(setenv("MOCKTAIL_WEBVIEW_HELPER", helper.path.c_str(), 1), 0);
|
||||
SecureRobloxCredential credential{".ROBLOSECURITY=typed-secret"};
|
||||
auto composition = MakeComposition(&credential);
|
||||
auto probe = std::make_shared<ExitProbe>();
|
||||
|
||||
const Status status = Open(composition.get(), probe);
|
||||
unsetenv("MOCKTAIL_WEBVIEW_HELPER");
|
||||
|
||||
ASSERT_FALSE(status.ok());
|
||||
EXPECT_NE(status.message().find("did not become ready"), std::string::npos)
|
||||
<< status.message();
|
||||
EXPECT_NE(status.message().find(" ms of 5000 ms"), std::string::npos)
|
||||
<< status.message();
|
||||
}
|
||||
|
||||
namespace {} // namespace
|
||||
} // namespace runtime
|
||||
} // namespace mocktail
|
||||
Reference in new issue
Block a user