mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
test(perf): end J2's HTTP window at the accepted quiet sample
The post-terminal window read the ledger after waitForMockQuiet returned, so a request arriving in between was counted although its completion was never waited for. waitForMockQuiet now returns the ledger position its accepted sample read; later requests are kept as evidence (httpRequestsAfterSettledByRoute) instead of the counter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b43ecc2870
commit
b0bbd73bb1
4 files changed
+38
-12
No files matched your search
@@ -133,8 +133,8 @@ async function waitForQuiet(
|
||||
*/
|
||||
async function waitForMockQuiet(
|
||||
ledger: JourneyMockRequestLedger
|
||||
): Promise<void> {
|
||||
await waitForJourneyQuiet({
|
||||
): Promise<number> {
|
||||
const { sample: quiet } = await waitForJourneyQuiet({
|
||||
inFlight: (activity) => activity.inFlight,
|
||||
pollMs: POLL_MS,
|
||||
quietMs: QUIET_MS,
|
||||
@@ -145,6 +145,11 @@ async function waitForMockQuiet(
|
||||
timeoutError: () => new Error('open-source-journey-mock-not-quiet'),
|
||||
timeoutMs: SETTLE_TIMEOUT_MS,
|
||||
});
|
||||
// The window ends at the ledger position this accepted sample read. A
|
||||
// request that arrives after it was never seen in flight, so its
|
||||
// response and follow-ups are not waited for; counting it would make
|
||||
// the counter depend on when the ledger is read.
|
||||
return quiet.requests;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,7 +207,7 @@ export async function measureOpenSourceJourney(
|
||||
OPEN_SOURCE_JOURNEY_MAIN_IPC_STATE_KEY,
|
||||
10_000
|
||||
);
|
||||
await waitForMockQuiet(ledger);
|
||||
const settledAfterLedgerMark = await waitForMockQuiet(ledger);
|
||||
// The journey starts at the renderer's click stamp, not when Playwright
|
||||
// began its actionability checks, so a request that arrives in between
|
||||
// stays before the click like it does for every other J2 counter. The
|
||||
@@ -216,14 +221,20 @@ export async function measureOpenSourceJourney(
|
||||
const beforeClick = sinceSpawn.filter(
|
||||
(entry) => entry.epochMs < clickEpochMs
|
||||
);
|
||||
const afterClick = sinceSpawn.filter(
|
||||
(entry) => entry.epochMs >= clickEpochMs
|
||||
);
|
||||
return {
|
||||
http: {
|
||||
afterSettleBeforeClick: beforeClick.filter(
|
||||
(entry) => entry.sequence >= settledLedgerMark
|
||||
).length,
|
||||
afterSettled: afterClick.filter(
|
||||
(entry) => entry.sequence >= settledAfterLedgerMark
|
||||
),
|
||||
beforeClick,
|
||||
requests: sinceSpawn.filter(
|
||||
(entry) => entry.epochMs >= clickEpochMs
|
||||
requests: afterClick.filter(
|
||||
(entry) => entry.sequence < settledAfterLedgerMark
|
||||
),
|
||||
},
|
||||
ipc,
|
||||
|
||||
@@ -83,6 +83,9 @@ function measurement(
|
||||
return {
|
||||
http: {
|
||||
afterSettleBeforeClick: 0,
|
||||
afterSettled: [
|
||||
request(3, '/player_api.php?action=get_vod_streams', 12_500),
|
||||
],
|
||||
beforeClick: [
|
||||
request(0, '/player_api.php?action=get_account_info', 2_000),
|
||||
],
|
||||
@@ -129,6 +132,10 @@ test('maps the click-started probe, IPC window and mock ledger to exact counters
|
||||
'/assets/marketing/poster/a': 1,
|
||||
'/player_api.php?action=get_account_info': 1,
|
||||
});
|
||||
// Arrived after the post-terminal quiet sample: evidence, not counted.
|
||||
assert.deepEqual(record.evidence['httpRequestsAfterSettledByRoute'], {
|
||||
'/player_api.php?action=get_vod_streams': 1,
|
||||
});
|
||||
assert.deepEqual(record.evidence['httpRequestsBeforeClickByRoute'], {
|
||||
'/player_api.php?action=get_account_info': 1,
|
||||
});
|
||||
|
||||
@@ -50,6 +50,11 @@ export interface OpenSourceJourneyMeasurement {
|
||||
readonly http: {
|
||||
/** Mock requests after the app settled but before the click stamp. */
|
||||
readonly afterSettleBeforeClick: number;
|
||||
/**
|
||||
* Requests after the post-terminal quiet sample; outside the window
|
||||
* because their completion was not waited for.
|
||||
*/
|
||||
readonly afterSettled: readonly JourneyMockRequest[];
|
||||
/** Mock requests from the spawn (J1 and settling) until the click. */
|
||||
readonly beforeClick: readonly JourneyMockRequest[];
|
||||
/** Mock requests from the click until the mock was quiet again. */
|
||||
@@ -171,6 +176,9 @@ export function toOpenSourceIterationRecord(
|
||||
httpRequestsBeforeClickByRoute: countJourneyMockRoutes(
|
||||
http.beforeClick
|
||||
),
|
||||
httpRequestsAfterSettledByRoute: countJourneyMockRoutes(
|
||||
http.afterSettled
|
||||
),
|
||||
httpRequestsByRoute: countJourneyMockRoutes(http.requests),
|
||||
httpRequestsToFirstPage: requestsToFirstPage,
|
||||
ipcCallsAfterFirstPage: ipc.callsAfterSentinel,
|
||||
|
||||
@@ -311,13 +311,13 @@ strings and stream paths carry credentials and are never stored.
|
||||
|
||||
### Counters
|
||||
|
||||
| Counter | Source |
|
||||
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `renderer.ipcCallsToFirstPage` | Bridge `start` trace events between the start and end sentinels, counted by a second `journey-main-ipc-capture.ts` instance installed with `startSentinelId`. Calls before the start marker are tallied separately (`callsBeforeStart`); a start marker that is missing, repeated or received after the end sentinel fails the iteration. |
|
||||
| `renderer.domMutationsToFirstPage` | `MutationRecord`s from the click until the terminal batch. Records produced before the click (hover, settling) are taken from the observer at the start and counted under `evidence.settle` instead. |
|
||||
| `renderer.layoutShiftScore` | Sum of all `layout-shift` entries from the click until the post-paint cutoff, rounded to three decimals. Unlike J1 it includes entries with `hadRecentInput === true`: the journey is a response to the click and runs inside the 500 ms input window, so the CLS filter would always read 0. The split is under `evidence.layoutShift`. |
|
||||
| `renderer.longTasks` | `longtask` entries over 50 ms whose time range overlaps the window from the click to the cutoff. The task that dispatches the click began before the event's timestamp and still counts; buffered J1 tasks that ended before the click are dropped. Evidence until it is shown to be stable on the CI runner, as for J1. |
|
||||
| `main.mockHttpRequestsToSettled` | Requests the proxy received from the click until, after the terminal batch, no new request had arrived for 1 s and none was in flight (a response slower than that, and what it triggers, stays inside the window). The window starts at the renderer's click stamp, the same boundary as every other J2 counter, not when Playwright began its actionability checks; the proxy stamps requests with the test process's wall clock, and both processes read the same host clock. Bounding by the terminal would compare the test process's clock with the renderer's, so the count up to the terminal epoch is evidence only (`evidence.httpRequestsToFirstPage`); `evidence.httpRequestsByRoute` names the requests. |
|
||||
| Counter | Source |
|
||||
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `renderer.ipcCallsToFirstPage` | Bridge `start` trace events between the start and end sentinels, counted by a second `journey-main-ipc-capture.ts` instance installed with `startSentinelId`. Calls before the start marker are tallied separately (`callsBeforeStart`); a start marker that is missing, repeated or received after the end sentinel fails the iteration. |
|
||||
| `renderer.domMutationsToFirstPage` | `MutationRecord`s from the click until the terminal batch. Records produced before the click (hover, settling) are taken from the observer at the start and counted under `evidence.settle` instead. |
|
||||
| `renderer.layoutShiftScore` | Sum of all `layout-shift` entries from the click until the post-paint cutoff, rounded to three decimals. Unlike J1 it includes entries with `hadRecentInput === true`: the journey is a response to the click and runs inside the 500 ms input window, so the CLS filter would always read 0. The split is under `evidence.layoutShift`. |
|
||||
| `renderer.longTasks` | `longtask` entries over 50 ms whose time range overlaps the window from the click to the cutoff. The task that dispatches the click began before the event's timestamp and still counts; buffered J1 tasks that ended before the click are dropped. Evidence until it is shown to be stable on the CI runner, as for J1. |
|
||||
| `main.mockHttpRequestsToSettled` | Requests the proxy received from the click until, after the terminal batch, no new request had arrived for 1 s and none was in flight (a response slower than that, and what it triggers, stays inside the window). The window ends at the ledger position read by that accepted quiet sample; a request arriving after it was never seen in flight, so it goes to `evidence.httpRequestsAfterSettledByRoute` instead of the counter. The window starts at the renderer's click stamp, the same boundary as every other J2 counter, not when Playwright began its actionability checks; the proxy stamps requests with the test process's wall clock, and both processes read the same host clock. Bounding by the terminal would compare the test process's clock with the renderer's, so the count up to the terminal epoch is evidence only (`evidence.httpRequestsToFirstPage`); `evidence.httpRequestsByRoute` names the requests. |
|
||||
|
||||
Two counters are listed under `unavailable`. `renderer.cdTicksToFirstPage`
|
||||
is missing for the same reason as its J1 counterpart.
|
||||
|
||||
Reference in new issue
Block a user