test(cdp): assert the heavy fixture actually served the page
The test's whole value is that its fixture keeps the navigation settle loop pumping, but nothing checked the fixture was reached. Pointing `page_url` at a dead port passed in 0.6s instead of 1.25s, and that degraded version no longer reproduced the #430 abort on the pre-fix tree -- so a fixture regression would have turned this back into the `data:`-URL test it was written to replace, silently and while staying green. Count the requests the fixture answers and assert on it. Two per client, not three: the engine does not fetch the `<img>`, only the document and /slow.js. Verified the assertion kills the dead-port mutant (0 requests, fails) and that the real run is stable across repeats. Refs #430.
This commit is contained in:
1 parent
319c6034fe
commit
ab7d407747
1 file changed
+29
-2
@@ -20,6 +20,8 @@
|
|||||||
//! Run with `cargo test -p obscura-cdp --test concurrent_connections_heavy_page
|
//! Run with `cargo test -p obscura-cdp --test concurrent_connections_heavy_page
|
||||||
//! -- --nocapture`.
|
//! -- --nocapture`.
|
||||||
|
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use futures_util::{SinkExt, StreamExt};
|
use futures_util::{SinkExt, StreamExt};
|
||||||
@@ -41,7 +43,12 @@ async fn pick_port() -> u16 {
|
|||||||
/// delay (keeping the navigation settle loop pumping) and an inline
|
/// delay (keeping the navigation settle loop pumping) and an inline
|
||||||
/// `setInterval` that keeps the event loop non-idle. Serves every connection it
|
/// `setInterval` that keeps the event loop non-idle. Serves every connection it
|
||||||
/// accepts until the test ends.
|
/// accepts until the test ends.
|
||||||
async fn serve_heavy_fixture(listener: TcpListener) {
|
///
|
||||||
|
/// `served` counts the requests it answers. The test asserts on it: without
|
||||||
|
/// that, pointing `page_url` at a dead port still passes (verified), because
|
||||||
|
/// nothing else here checks the heavy page ever loaded -- and a test whose
|
||||||
|
/// fixture silently drops out stops reproducing #430 while staying green.
|
||||||
|
async fn serve_heavy_fixture(listener: TcpListener, served: Arc<AtomicUsize>) {
|
||||||
let body = "<!DOCTYPE html><html><head>\
|
let body = "<!DOCTYPE html><html><head>\
|
||||||
<script src=\"/slow.js\"></script>\
|
<script src=\"/slow.js\"></script>\
|
||||||
</head><body><h1>heavy</h1><img src=\"/slow.png\">\
|
</head><body><h1>heavy</h1><img src=\"/slow.png\">\
|
||||||
@@ -52,12 +59,14 @@ async fn serve_heavy_fixture(listener: TcpListener) {
|
|||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
|
let served = served.clone();
|
||||||
tokio::task::spawn_local(async move {
|
tokio::task::spawn_local(async move {
|
||||||
let mut buf = [0u8; 2048];
|
let mut buf = [0u8; 2048];
|
||||||
let n = sock.read(&mut buf).await.unwrap_or(0);
|
let n = sock.read(&mut buf).await.unwrap_or(0);
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
served.fetch_add(1, Ordering::Relaxed);
|
||||||
let req = String::from_utf8_lossy(&buf[..n]);
|
let req = String::from_utf8_lossy(&buf[..n]);
|
||||||
let path = req
|
let path = req
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
@@ -198,7 +207,8 @@ async fn concurrent_connections_heavy_page_do_not_abort_v8() {
|
|||||||
local
|
local
|
||||||
.run_until(async {
|
.run_until(async {
|
||||||
// Fixture HTTP server.
|
// Fixture HTTP server.
|
||||||
tokio::task::spawn_local(serve_heavy_fixture(fixture));
|
let served = Arc::new(AtomicUsize::new(0));
|
||||||
|
tokio::task::spawn_local(serve_heavy_fixture(fixture, served.clone()));
|
||||||
|
|
||||||
// CDP server. allow_private_network so it may fetch 127.0.0.1.
|
// CDP server. allow_private_network so it may fetch 127.0.0.1.
|
||||||
tokio::task::spawn_local(async move {
|
tokio::task::spawn_local(async move {
|
||||||
@@ -240,6 +250,23 @@ async fn concurrent_connections_heavy_page_do_not_abort_v8() {
|
|||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
assert_eq!(ok as u64, CLIENTS, "every concurrent client must complete");
|
assert_eq!(ok as u64, CLIENTS, "every concurrent client must complete");
|
||||||
|
|
||||||
|
// The fixture must actually have served each client the page and
|
||||||
|
// its slow script -- that is what keeps the settle loop pumping and
|
||||||
|
// makes this a #430 repro at all. Without this assertion, pointing
|
||||||
|
// `page_url` at a dead port still passes (verified), and the test
|
||||||
|
// silently degrades into the `data:`-URL one it was written to
|
||||||
|
// replace. Two per client, not three: the engine does not fetch the
|
||||||
|
// `<img>`, so only the document and /slow.js are requested.
|
||||||
|
let hits = served.load(Ordering::Relaxed);
|
||||||
|
assert!(
|
||||||
|
hits >= CLIENTS as usize * 2,
|
||||||
|
"fixture served {} requests, expected at least {} ({} clients x document \
|
||||||
|
+ /slow.js): the heavy page never loaded, so this run proves nothing",
|
||||||
|
hits,
|
||||||
|
CLIENTS as usize * 2,
|
||||||
|
CLIENTS
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user