test(performance): add end-to-end Xtream benchmark harness (#1300)

* docs(performance): plan Xtream benchmark

* feat(xtream-mock-server): add deterministic 100k fixture

* style(xtream-mock-server): apply repository formatting

* fix(xtream-mock-server): harden performance fixture data

* feat(xtream-mock-server): add performance control plane

* docs(performance): correct Xtream capture plan

* fix(xtream-mock-server): harden performance controls

* fix(xtream-mock-server): harden control lifecycle

* feat(performance): add Xtream preload markers

* feat(performance): trace Xtream main phases

* feat(performance): mark Xtream store publications

* feat(performance): trace Xtream database phases

* feat(performance): trace Xtream delete cancellation

* feat(performance): capture Xtream phase attribution

* feat(performance): mark Sources Xtream refresh

* test(performance): define Xtream benchmark evidence contracts

* test(performance): add Xtream benchmark runner

* test(performance): surface failure evidence writes

* test(performance): align database read clock

* test(performance): preserve capture failure contracts
This commit is contained in:
4gray authored and GitHub committed 2026-07-28 08:08:07 +02:00
1 parent 5e725a06f3
commit a2fafcfc08
256 files changed
+43760 -883

No files matched your search

+2 -2
View File
@@ -87,8 +87,8 @@ IPTVNATOR_TRACE_STARTUP=1 nx serve electron-backend
- `IPTVNATOR_TRACE_WINDOW=1` traces BrowserWindow lifecycle and unresponsive events
- `IPTVNATOR_TRACE_PLAYER=1` traces external-player activity and bounded Embedded MPV runtime-probe stderr
- `IPTVNATOR_TRACE_RENDERER_CONSOLE=1` mirrors renderer console output into the Electron terminal
- `IPTVNATOR_PERF_CAPTURE=1` enables development/test-only, redacted preload IPC request/completion markers plus count-only M3U acquire/parse/normalize and renderer store phase capture; renderer wrappers emit only while the benchmark installs its Symbol hook, benchmark tooling sets the flag explicitly, and production launches must leave it unset
- `IPTVNATOR_PERF_WORKER_PROFILING=1` enables development/test-only, request-scoped worker receive/work/response-post timestamps, thread CPU, event-loop utilization/delay, count-only playlist serialization/SQLite write/read/deserialization phase events, valid-sample-counted isolate peak memory, and the database worker's idle-only one-shot post-GC heap probe; overlapping database requests are explicitly invalidated instead of misattributed, the performance benchmark sets the flag automatically, and production launches must leave it unset
- `IPTVNATOR_PERF_CAPTURE=1` enables development/test-only, redacted M3U and Xtream preload IPC request/completion markers plus count-only M3U acquire/parse/normalize, Xtream main network/JSON-transform/success-response-ready/cancel-dispatch, and renderer store phase capture; renderer wrappers emit only while the benchmark installs its Symbol hook, benchmark tooling sets the flag explicitly, and production launches must leave it unset
- `IPTVNATOR_PERF_WORKER_PROFILING=1` enables development/test-only, request-scoped worker receive/work/response-post timestamps, thread CPU, event-loop utilization/delay, count-only playlist serialization/SQLite write/read/deserialization plus Xtream category/content/cache-clear/delete/in-source-search phase events, profiling-only worker cancel-receipt acknowledgements, valid-sample-counted isolate peak memory, and the database worker's idle-only one-shot post-GC heap probe; overlapping database requests are explicitly invalidated instead of misattributed, the performance benchmark sets the flag automatically, and production launches must leave it unset
- Settings, portal request/response, and trace payloads must use
`@iptvnator/shared/logging` or the redacting portal logger before reaching
+2 -2
View File
@@ -142,8 +142,8 @@ Useful narrower flags:
- `IPTVNATOR_TRACE_WINDOW=1` traces BrowserWindow navigation/load lifecycle
- `IPTVNATOR_TRACE_PLAYER=1` traces external-player activity and bounded Embedded MPV runtime-probe stderr
- `IPTVNATOR_TRACE_RENDERER_CONSOLE=1` mirrors renderer console logs into the Electron terminal
- `IPTVNATOR_PERF_CAPTURE=1` enables development/test-only, redacted preload IPC request/completion markers plus count-only M3U acquire/parse/normalize and renderer store phase capture; renderer wrappers emit only while the benchmark installs its Symbol hook, benchmark tooling sets the flag explicitly, and production launches must leave it unset
- `IPTVNATOR_PERF_WORKER_PROFILING=1` enables development/test-only, request-scoped worker receive/work/response-post timestamps, thread CPU, event-loop utilization/delay, count-only playlist serialization/SQLite write/read/deserialization phase events, valid-sample-counted isolate peak memory, and the database worker's idle-only one-shot post-GC heap probe; overlapping database requests are explicitly invalidated instead of misattributed, the performance benchmark sets the flag automatically, and production launches must leave it unset
- `IPTVNATOR_PERF_CAPTURE=1` enables development/test-only, redacted M3U and Xtream preload IPC request/completion markers plus count-only M3U acquire/parse/normalize, Xtream main network/JSON-transform/success-response-ready/cancel-dispatch, and renderer store phase capture; renderer wrappers emit only while the benchmark installs its Symbol hook, benchmark tooling sets the flag explicitly, and production launches must leave it unset
- `IPTVNATOR_PERF_WORKER_PROFILING=1` enables development/test-only, request-scoped worker receive/work/response-post timestamps, thread CPU, event-loop utilization/delay, count-only playlist serialization/SQLite write/read/deserialization plus Xtream category/content/cache-clear/delete/in-source-search phase events, profiling-only worker cancel-receipt acknowledgements, valid-sample-counted isolate peak memory, and the database worker's idle-only one-shot post-GC heap probe; overlapping database requests are explicitly invalidated instead of misattributed, the performance benchmark sets the flag automatically, and production launches must leave it unset
Settings, portal request/response, and trace payloads must use
`@iptvnator/shared/logging` or the redacting portal logger before reaching
@@ -0,0 +1,34 @@
import { randomBytes } from 'node:crypto';
import { workspaceRoot } from '@nx/devkit';
import { defineConfig } from '@playwright/test';
const controlToken =
process.env['IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN'] ??
randomBytes(32).toString('base64url');
process.env['IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN'] = controlToken;
export default defineConfig({
fullyParallel: false,
reporter: [['list']],
retries: 0,
testDir: './src',
testMatch: 'xtream.performance.ts',
timeout: 30 * 60 * 1_000,
use: {
testIdAttribute: 'data-test-id',
},
webServer: {
command: 'pnpm nx run xtream-mock-server:serve',
cwd: workspaceRoot,
env: {
HOST: '127.0.0.1',
IPTVNATOR_XTREAM_MOCK_CONTROL: '1',
IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN: controlToken,
PORT: '3221',
},
reuseExistingServer: false,
url: 'http://127.0.0.1:3221/health',
},
workers: 1,
});
+10
View File
@@ -39,6 +39,16 @@
"command": "pnpm exec playwright test --config=playwright.performance.config.ts src/m3u-import.performance.ts"
}
},
"benchmark-xtream": {
"dependsOn": ["electron-backend:build-performance"],
"executor": "nx:run-commands",
"cache": false,
"parallelism": false,
"options": {
"cwd": "apps/electron-backend-e2e",
"command": "pnpm exec playwright test --config=playwright.xtream-performance.config.ts src/xtream.performance.ts"
}
},
"packaged-frame-copy-smoke": {
"dependsOn": ["test-packaged-frame-copy-fixtures"],
"executor": "nx:run-commands",
@@ -77,7 +77,9 @@ type ElectronFixtures = {
export type LaunchElectronAppOptions = {
args?: readonly string[];
environmentInheritance?: 'all' | 'runtime-only';
env?: Record<string, string | undefined>;
omitEnvKeys?: readonly string[];
};
export type PortalDebugEvent = {
@@ -197,16 +199,7 @@ export async function launchElectronApp(
const electronApp = await electron.launch({
args,
env: {
...process.env,
// Electron E2E uses local mock HTTP servers for playlists, portals, and EPG sources.
IPTVNATOR_ALLOW_PRIVATE_NETWORK_URLS:
process.env['IPTVNATOR_ALLOW_PRIVATE_NETWORK_URLS'] ?? '1',
...options.env,
ELECTRON_IS_DEV: '0',
IPTVNATOR_E2E_DATA_DIR: dataDir,
NODE_ENV: 'test',
},
env: buildElectronLaunchEnvironment(dataDir, options),
});
attachElectronProcessDiagnostics(electronApp);
@@ -222,6 +215,86 @@ export async function launchElectronApp(
};
}
export function buildElectronLaunchEnvironment(
dataDir: string,
options: LaunchElectronAppOptions = {},
inheritedEnvironment: NodeJS.ProcessEnv = process.env
): Record<string, string> {
if (
options.environmentInheritance !== undefined &&
options.environmentInheritance !== 'all' &&
options.environmentInheritance !== 'runtime-only'
) {
throw new Error('Electron environment inheritance mode is invalid');
}
const runtimeOnly = options.environmentInheritance === 'runtime-only';
const environment: Record<string, string | undefined> = {
...(runtimeOnly
? selectElectronRuntimeEnvironment(inheritedEnvironment)
: inheritedEnvironment),
// Electron E2E uses local mock HTTP servers for playlists, portals, and EPG sources.
IPTVNATOR_ALLOW_PRIVATE_NETWORK_URLS: runtimeOnly
? '1'
: (inheritedEnvironment['IPTVNATOR_ALLOW_PRIVATE_NETWORK_URLS'] ??
'1'),
...options.env,
ELECTRON_IS_DEV: '0',
IPTVNATOR_E2E_DATA_DIR: dataDir,
NODE_ENV: 'test',
};
for (const key of options.omitEnvKeys ?? []) {
delete environment[key];
}
return Object.fromEntries(
Object.entries(environment).filter(
(entry): entry is [string, string] => typeof entry[1] === 'string'
)
);
}
export const ELECTRON_RUNTIME_ENVIRONMENT_KEYS = Object.freeze([
'APPDATA',
'COMSPEC',
'DBUS_SESSION_BUS_ADDRESS',
'DISPLAY',
'HOME',
'LANG',
'LANGUAGE',
'LC_ALL',
'LC_CTYPE',
'LOCALAPPDATA',
'LOGNAME',
'PATH',
'PATHEXT',
'SYSTEMROOT',
'TEMP',
'TMP',
'TMPDIR',
'USER',
'USERPROFILE',
'WAYLAND_DISPLAY',
'WINDIR',
'XAUTHORITY',
'XDG_RUNTIME_DIR',
'XDG_SESSION_TYPE',
'__CF_USER_TEXT_ENCODING',
] as const);
function selectElectronRuntimeEnvironment(
inheritedEnvironment: NodeJS.ProcessEnv
): Record<string, string> {
const selected: Record<string, string> = {};
const allowed = new Set(
ELECTRON_RUNTIME_ENVIRONMENT_KEYS.map((key) => key.toUpperCase())
);
for (const [key, value] of Object.entries(inheritedEnvironment)) {
if (typeof value === 'string' && allowed.has(key.toUpperCase())) {
selected[key] = value;
}
}
return selected;
}
/**
* Resolve the x64 unpacked Linux executable produced by electron-builder.
* An explicit path wins so CI can point at an AppImage/Flatpak extraction
@@ -1703,9 +1776,7 @@ export async function expectWorkspaceSearchStatus(
}
/** The degraded-search hint chip must be absent (e.g. complete local search). */
export async function expectNoWorkspaceSearchStatus(
page: Page
): Promise<void> {
export async function expectNoWorkspaceSearchStatus(page: Page): Promise<void> {
await expect(
page.locator('app-workspace-shell-header .search-chip--status')
).toHaveCount(0);
@@ -0,0 +1,161 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { createDatabaseWorkerCancelCapture } from './database-worker-cancel-capture';
function dispatch(overrides: Record<string, unknown> = {}) {
return {
captureGeneration: 3,
ipcCallId: 9,
operationId: 'operation-1',
postedEpochMs: 110,
requestId: 'request-1',
sourceEpochMs: 100,
...overrides,
};
}
function receipt(overrides: Record<string, unknown> = {}) {
return {
type: 'performance-cancel-received',
epochMs: 120,
operationId: 'operation-1',
requestId: 'request-1',
...overrides,
};
}
describe('database worker cancel capture', () => {
it('restores without module closures for Electron-main injection', () => {
const source = createDatabaseWorkerCancelCapture.toString();
assert.doesNotMatch(source, /__name/);
const factory = new Function(
`"use strict"; return (${source});`
)() as typeof createDatabaseWorkerCancelCapture;
factory().start(1);
});
it('keeps dispatch, worker receipt, and terminal cancellation distinct', () => {
const capture = createDatabaseWorkerCancelCapture();
capture.start(3);
assert.equal(capture.acceptDispatch(dispatch()), true);
assert.equal(
capture.acceptReceipt({
captureGeneration: 3,
message: receipt(),
receivedEpochMs: 121,
recordGeneration: 3,
}),
true
);
assert.equal(
capture.acceptTerminal({
captureGeneration: 3,
operationId: 'operation-1',
receivedEpochMs: 130,
recordGeneration: 3,
requestId: 'request-1',
}),
true
);
const snapshot = capture.stop();
assert.deepEqual(snapshot.invalidReasons, []);
assert.deepEqual(
snapshot.timeline.map(({ epochMs, type }) => ({ epochMs, type })),
[
{ epochMs: 110, type: 'db-cancel-dispatched' },
{ epochMs: 120, type: 'db-cancel-received' },
{ epochMs: 130, type: 'db-cancel-terminal-received' },
]
);
});
it('rejects extra fields, non-monotonic epochs, and cross-generation receipts', () => {
for (const testCase of [
{
message: receipt({ credential: 'forbidden' }),
receivedEpochMs: 121,
recordGeneration: 3,
},
{
message: receipt({ epochMs: 109 }),
receivedEpochMs: 121,
recordGeneration: 3,
},
{
message: receipt({ epochMs: 122 }),
receivedEpochMs: 121,
recordGeneration: 3,
},
{
message: receipt(),
receivedEpochMs: 121,
recordGeneration: 2,
},
]) {
const capture = createDatabaseWorkerCancelCapture();
capture.start(3);
assert.equal(capture.acceptDispatch(dispatch()), true);
assert.equal(
capture.acceptReceipt({
captureGeneration: 3,
...testCase,
}),
false
);
assert.notEqual(capture.stop().invalidReasons.length, 0);
}
});
it('invalidates a missing receipt separately from a missing terminal', () => {
const missingReceipt = createDatabaseWorkerCancelCapture();
missingReceipt.start(3);
assert.equal(missingReceipt.acceptDispatch(dispatch()), true);
assert.deepEqual(missingReceipt.stop().invalidReasons, [
'cancel-receipt-missing',
'cancel-terminal-missing',
]);
const missingTerminal = createDatabaseWorkerCancelCapture();
missingTerminal.start(3);
assert.equal(missingTerminal.acceptDispatch(dispatch()), true);
assert.equal(
missingTerminal.acceptReceipt({
captureGeneration: 3,
message: receipt(),
receivedEpochMs: 121,
recordGeneration: 3,
}),
true
);
assert.deepEqual(missingTerminal.stop().invalidReasons, [
'cancel-terminal-missing',
]);
});
it('fails neutrally for revoked or throwing proxy input', () => {
const capture = createDatabaseWorkerCancelCapture();
capture.start(3);
const revoked = Proxy.revocable({}, {});
revoked.revoke();
const throwing = new Proxy(
{},
{
get() {
throw new Error('property access denied');
},
ownKeys() {
throw new Error('keys denied');
},
}
);
assert.doesNotThrow(() => capture.acceptDispatch(revoked.proxy));
assert.equal(capture.acceptDispatch(revoked.proxy), false);
assert.doesNotThrow(() => capture.acceptReceipt(throwing as never));
assert.equal(capture.acceptReceipt(throwing as never), false);
assert.doesNotThrow(() => capture.acceptTerminal(throwing as never));
assert.equal(capture.acceptTerminal(throwing as never), false);
});
});
@@ -0,0 +1,295 @@
export interface DatabaseWorkerCancelTimelineRecord {
readonly epochMs: number;
readonly ipcCallId: number;
readonly operationId: string;
readonly requestId: string;
readonly sourceEpochMs: number;
readonly type:
| 'db-cancel-dispatched'
| 'db-cancel-received'
| 'db-cancel-terminal-received';
}
export interface DatabaseWorkerCancelCaptureSnapshot {
readonly invalidReasons: readonly string[];
readonly timeline: readonly DatabaseWorkerCancelTimelineRecord[];
}
export interface DatabaseWorkerCancelCapture {
acceptDispatch(input: unknown): boolean;
acceptReceipt(input: {
readonly captureGeneration: number;
readonly message: unknown;
readonly receivedEpochMs: number;
readonly recordGeneration: number | null;
}): boolean;
acceptTerminal(input: {
readonly captureGeneration: number;
readonly operationId: string;
readonly receivedEpochMs: number;
readonly recordGeneration: number | null;
readonly requestId: string;
}): boolean;
start(captureGeneration: number): void;
stop(): DatabaseWorkerCancelCaptureSnapshot;
}
export function createDatabaseWorkerCancelCapture(): DatabaseWorkerCancelCapture {
type JsonRecord = Record<string, unknown>;
interface DispatchState {
readonly captureGeneration: number;
readonly ipcCallId: number;
readonly operationId: string;
readonly postedEpochMs: number;
readonly requestId: string;
readonly sourceEpochMs: number;
receiptEpochMs: number | null;
terminalEpochMs: number | null;
}
const dispatchKeys = new Set([
'captureGeneration',
'ipcCallId',
'operationId',
'postedEpochMs',
'requestId',
'sourceEpochMs',
]);
const receiptKeys = new Set([
'type',
'epochMs',
'operationId',
'requestId',
]);
const identifierPattern = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
let active = false;
let generation = 0;
let invalidReasons: string[] = [];
let timeline: DatabaseWorkerCancelTimelineRecord[] = [];
const dispatches = new Map<string, DispatchState>();
const helpers = {
invalidate(reason: string): false {
invalidReasons.push(reason);
return false;
},
isEpoch(value: unknown): value is number {
return (
typeof value === 'number' && Number.isFinite(value) && value > 0
);
},
isGeneration(value: unknown): value is number {
return Number.isSafeInteger(value) && Number(value) > 0;
},
isIdentifier(value: unknown): value is string {
return typeof value === 'string' && identifierPattern.test(value);
},
isRecord(value: unknown): value is JsonRecord {
return (
typeof value === 'object' &&
value !== null &&
!Array.isArray(value)
);
},
ownsOnly(value: JsonRecord, keys: ReadonlySet<string>): boolean {
const ownKeys = Reflect.ownKeys(value);
return (
ownKeys.length === keys.size &&
ownKeys.every((key) => typeof key === 'string' && keys.has(key))
);
},
timelineRecord(
dispatch: DispatchState,
epochMs: number,
type: DatabaseWorkerCancelTimelineRecord['type']
): DatabaseWorkerCancelTimelineRecord {
return {
epochMs,
ipcCallId: dispatch.ipcCallId,
operationId: dispatch.operationId,
requestId: dispatch.requestId,
sourceEpochMs: dispatch.sourceEpochMs,
type,
};
},
};
return {
acceptDispatch(input): boolean {
try {
if (
!active ||
!helpers.isRecord(input) ||
!helpers.ownsOnly(input, dispatchKeys) ||
input['captureGeneration'] !== generation ||
!helpers.isGeneration(input['captureGeneration']) ||
!Number.isSafeInteger(input['ipcCallId']) ||
Number(input['ipcCallId']) <= 0 ||
!helpers.isIdentifier(input['operationId']) ||
!helpers.isIdentifier(input['requestId']) ||
!helpers.isEpoch(input['postedEpochMs']) ||
!helpers.isEpoch(input['sourceEpochMs']) ||
Number(input['sourceEpochMs']) >
Number(input['postedEpochMs'])
) {
return helpers.invalidate('cancel-dispatch-invalid');
}
const requestId = input['requestId'];
if (dispatches.has(requestId)) {
return helpers.invalidate('cancel-dispatch-duplicate');
}
const dispatch = {
captureGeneration: generation,
ipcCallId: Number(input['ipcCallId']),
operationId: input['operationId'],
postedEpochMs: Number(input['postedEpochMs']),
receiptEpochMs: null,
requestId,
sourceEpochMs: Number(input['sourceEpochMs']),
terminalEpochMs: null,
};
dispatches.set(requestId, dispatch);
timeline.push(
helpers.timelineRecord(
dispatch,
dispatch.postedEpochMs,
'db-cancel-dispatched'
)
);
return true;
} catch {
return helpers.invalidate('cancel-dispatch-invalid');
}
},
acceptReceipt(input): boolean {
try {
if (
!active ||
input.captureGeneration !== generation ||
input.recordGeneration !== generation
) {
return helpers.invalidate(
'cancel-receipt-generation-mismatch'
);
}
const message = input.message;
if (
!helpers.isRecord(message) ||
!helpers.ownsOnly(message, receiptKeys) ||
message['type'] !== 'performance-cancel-received' ||
!helpers.isIdentifier(message['operationId']) ||
!helpers.isIdentifier(message['requestId']) ||
!helpers.isEpoch(message['epochMs']) ||
!helpers.isEpoch(input.receivedEpochMs)
) {
return helpers.invalidate('cancel-receipt-invalid-schema');
}
const dispatch = dispatches.get(message['requestId']);
if (!dispatch) {
return helpers.invalidate(
'cancel-receipt-dispatch-missing'
);
}
if (dispatch.operationId !== message['operationId']) {
return helpers.invalidate(
'cancel-receipt-correlation-mismatch'
);
}
if (
Number(message['epochMs']) < dispatch.postedEpochMs ||
Number(message['epochMs']) > input.receivedEpochMs
) {
return helpers.invalidate('cancel-receipt-epoch-invalid');
}
if (dispatch.receiptEpochMs !== null) {
return helpers.invalidate('cancel-receipt-duplicate');
}
dispatch.receiptEpochMs = Number(message['epochMs']);
timeline.push(
helpers.timelineRecord(
dispatch,
dispatch.receiptEpochMs,
'db-cancel-received'
)
);
return true;
} catch {
return helpers.invalidate('cancel-receipt-invalid-schema');
}
},
acceptTerminal(input): boolean {
try {
if (
!active ||
input.captureGeneration !== generation ||
input.recordGeneration !== generation
) {
return helpers.invalidate(
'cancel-terminal-generation-mismatch'
);
}
if (
!helpers.isIdentifier(input.operationId) ||
!helpers.isIdentifier(input.requestId) ||
!helpers.isEpoch(input.receivedEpochMs)
) {
return helpers.invalidate('cancel-terminal-invalid');
}
const dispatch = dispatches.get(input.requestId);
if (!dispatch) {
return helpers.invalidate(
'cancel-terminal-dispatch-missing'
);
}
if (dispatch.operationId !== input.operationId) {
return helpers.invalidate(
'cancel-terminal-correlation-mismatch'
);
}
if (
dispatch.receiptEpochMs === null ||
input.receivedEpochMs < dispatch.receiptEpochMs
) {
return helpers.invalidate('cancel-terminal-before-receipt');
}
if (dispatch.terminalEpochMs !== null) {
return helpers.invalidate('cancel-terminal-duplicate');
}
dispatch.terminalEpochMs = input.receivedEpochMs;
timeline.push(
helpers.timelineRecord(
dispatch,
dispatch.terminalEpochMs,
'db-cancel-terminal-received'
)
);
return true;
} catch {
return helpers.invalidate('cancel-terminal-invalid');
}
},
start(captureGeneration): void {
if (!helpers.isGeneration(captureGeneration)) {
throw new Error('database-worker-cancel-generation-invalid');
}
active = true;
generation = captureGeneration;
invalidReasons = [];
timeline = [];
dispatches.clear();
},
stop(): DatabaseWorkerCancelCaptureSnapshot {
for (const dispatch of dispatches.values()) {
if (dispatch.receiptEpochMs === null) {
invalidReasons.push('cancel-receipt-missing');
}
if (dispatch.terminalEpochMs === null) {
invalidReasons.push('cancel-terminal-missing');
}
}
active = false;
return Object.freeze({
invalidReasons: Object.freeze([...invalidReasons]),
timeline: Object.freeze([...timeline]),
});
},
};
}
@@ -370,21 +370,22 @@ test('worker capture failures use an artifact-neutral timeline label', () => {
assert.doesNotMatch(source, /worker-profile-error:\$\{stage\}/);
});
test('capture generation resets artifact paths and always emits current DB records', () => {
test('capture generation resets artifact paths while arming and always emits current DB records', () => {
const source = readFileSync(
new URL('./m3u-refresh-main-capture.ts', import.meta.url),
'utf8'
);
const start = source.indexOf('const startCapture = async (');
const diagnostic = source.indexOf('if (state.diagnostic)', start);
const api = source.indexOf('const api =', start);
const profileReset = source.indexOf('state.mainProfilePath = null', start);
const snapshotReset = source.indexOf(
'state.mainSnapshotPath = null',
start
);
assert.ok(profileReset > start && profileReset < diagnostic);
assert.ok(snapshotReset > start && snapshotReset < diagnostic);
assert.ok(profileReset > start && profileReset < api);
assert.ok(snapshotReset > start && snapshotReset < api);
assert.doesNotMatch(source.slice(start, api), /'Profiler\.start'/);
assert.match(
source,
/record\.captureGeneration === state\.captureGeneration[\s\S]*record\.kind === 'database\.worker'/
@@ -0,0 +1,105 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
buildElectronLaunchEnvironment,
ELECTRON_RUNTIME_ENVIRONMENT_KEYS,
} from '../electron-test-fixtures';
import { assertXtreamBenchmarkEnvironmentIsolated } from './xtream-benchmark-iteration-support';
describe('Electron launch environment isolation', () => {
it('inherits only portable runtime keys for a profiled benchmark child', () => {
const environment = buildElectronLaunchEnvironment(
'/tmp/iptvnator-performance',
{
environmentInheritance: 'runtime-only',
env: {
IPTVNATOR_PERF_CAPTURE: '1',
},
},
{
AWS_SECRET_ACCESS_KEY: 'aws-secret',
ELECTRON_RUN_AS_NODE: '1',
GITHUB_TOKEN: 'github-secret',
HTTPS_PROXY: 'https://user:password@proxy.invalid',
IPTVNATOR_ALLOW_PRIVATE_NETWORK_URLS: '0',
IPTVNATOR_REAL_PROVIDER_URL: 'https://provider.invalid',
IPTVNATOR_XTREAM_MOCK_CONTROL: '1',
IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN: 'secret-token',
NODE_OPTIONS: '--require credential-dumper.js',
PATH: '/usr/bin',
REAL_PROVIDER_PASSWORD: 'provider-password',
REAL_PROVIDER_URL: 'https://provider.invalid',
TMPDIR: '/tmp/runtime',
}
);
assert.equal(environment['IPTVNATOR_PERF_CAPTURE'], '1');
assert.equal(environment['IPTVNATOR_ALLOW_PRIVATE_NETWORK_URLS'], '1');
assert.equal(environment['PATH'], '/usr/bin');
assert.equal(environment['TMPDIR'], '/tmp/runtime');
for (const key of [
'AWS_SECRET_ACCESS_KEY',
'ELECTRON_RUN_AS_NODE',
'GITHUB_TOKEN',
'HTTPS_PROXY',
'IPTVNATOR_REAL_PROVIDER_URL',
'IPTVNATOR_XTREAM_MOCK_CONTROL',
'IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN',
'NODE_OPTIONS',
'REAL_PROVIDER_PASSWORD',
'REAL_PROVIDER_URL',
]) {
assert.equal(environment[key], undefined, key);
}
});
it('drops undefined overrides instead of serializing them into the child', () => {
const environment = buildElectronLaunchEnvironment(
'/tmp/iptvnator-performance',
{ env: { OPTIONAL_DEBUG_FLAG: undefined } },
{ OPTIONAL_DEBUG_FLAG: 'inherited' }
);
assert.equal(environment['OPTIONAL_DEBUG_FLAG'], undefined);
});
it('checks the effective Electron main environment, not only launch input', async () => {
const allowed = [
...ELECTRON_RUNTIME_ENVIRONMENT_KEYS,
'ELECTRON_IS_DEV',
'IPTVNATOR_ALLOW_PRIVATE_NETWORK_URLS',
'IPTVNATOR_DB_WORKER_BATCH_DELAY_MS',
'IPTVNATOR_E2E_DATA_DIR',
'IPTVNATOR_PERF_CAPTURE',
'IPTVNATOR_PERF_WORKER_PROFILING',
'IPTVNATOR_TRACE_RENDERER_CONSOLE',
'NODE_ENV',
];
await assert.doesNotReject(
assertXtreamBenchmarkEnvironmentIsolated(fakeApp(allowed))
);
for (const leaked of [
'GITHUB_TOKEN',
'HTTPS_PROXY',
'NODE_OPTIONS',
'REAL_PROVIDER_URL',
]) {
await assert.rejects(
assertXtreamBenchmarkEnvironmentIsolated(
fakeApp([...allowed, leaked])
),
/xtream-benchmark-environment-reached-electron/
);
}
});
});
function fakeApp(keys: readonly string[]) {
return {
electronApp: {
evaluate: async () => [...keys],
},
} as never;
}
@@ -73,6 +73,14 @@ export function isCpuProfile(value: unknown): boolean {
return elapsed > 0;
}
export function readCpuProfileDurationMicros(value: unknown): number | null {
if (!isCpuProfile(value)) {
return null;
}
const profile = value as Record<string, number>;
return profile['endTime'] - profile['startTime'];
}
export function isHeapSnapshot(value: unknown): boolean {
if (
!isRecord(value) ||
@@ -69,7 +69,10 @@ export async function resolveM3uImportBenchmarkConfiguration(): Promise<M3uImpor
);
await assertMissing(layout.variantDirectory);
await assertPerformanceArtifactCapacity(layout.variantDirectory);
await mkdir(layout.variantDirectory, { recursive: true });
await mkdir(layout.variantDirectory, {
mode: 0o700,
recursive: true,
});
return Object.freeze({
...layout,
electronVersion: electronPackage.version,
@@ -1,7 +1,7 @@
import { once } from 'node:events';
import { createWriteStream } from 'node:fs';
import { writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { finished } from 'node:stream/promises';
import type { CDPSession } from '@playwright/test';
@@ -9,6 +9,11 @@ interface TraceData {
readonly value: readonly unknown[];
}
export interface RendererHeapUsageSample {
readonly epochMs: number;
readonly usedSize: number;
}
export interface RendererArtifactCapture {
beginTraceOutput(): void;
readonly cpuProfilePath: string | null;
@@ -27,7 +32,9 @@ export function createRendererArtifactCapture(options: {
const tracePath = options.diagnostic
? join(options.outputDirectory, 'renderer.trace.json')
: null;
const traceOutput = tracePath ? createWriteStream(tracePath) : null;
const traceOutput = tracePath
? createWriteStream(tracePath, { flags: 'wx', mode: 0o600 })
: null;
let traceOutputOpened = false;
let traceOutputFinish: Promise<void> | null = null;
let traceFirstEvent = true;
@@ -62,9 +69,7 @@ export function createRendererArtifactCapture(options: {
traceOutput.write(']}');
traceOutput.end();
}
if (!traceOutput.writableFinished) {
await once(traceOutput, 'finish');
}
await finished(traceOutput);
})();
return traceOutputFinish;
},
@@ -122,7 +127,7 @@ export async function stopRendererDiagnosticCapture(
await writeFile(
requirePath(artifacts.cpuProfilePath, 'renderer CPU profile'),
JSON.stringify(cpuProfile['profile']),
'utf8'
{ encoding: 'utf8', flag: 'wx', mode: 0o600 }
);
await session.send('Tracing.end');
await artifacts.traceComplete;
@@ -145,7 +150,8 @@ export async function takeRendererHeapSnapshot(
path: string | null
): Promise<void> {
const output = createWriteStream(
requirePath(path, 'renderer heap snapshot')
requirePath(path, 'renderer heap snapshot'),
{ flags: 'wx', mode: 0o600 }
);
const onChunk = ({ chunk }: { readonly chunk: string }): void => {
output.write(chunk);
@@ -158,9 +164,43 @@ export async function takeRendererHeapSnapshot(
} finally {
session.off('HeapProfiler.addHeapSnapshotChunk', onChunk);
output.end();
if (!output.writableFinished) {
await once(output, 'finish');
}
await finished(output);
}
}
export function selectRendererPeakHeapUsedBytes(
samples: readonly RendererHeapUsageSample[],
measurementStartEpochMs: number,
terminalEpochMs: number
): number {
const inWindow = samples.filter(
({ epochMs, usedSize }) =>
Number.isFinite(epochMs) &&
epochMs >= measurementStartEpochMs &&
epochMs <= terminalEpochMs &&
Number.isFinite(usedSize) &&
usedSize >= 0
);
if (inWindow.length === 0) {
throw new Error('renderer-heap-window-empty');
}
return Math.max(...inWindow.map(({ usedSize }) => usedSize));
}
export function assertRendererMeasurementWindow(input: {
readonly captureCutoffEpochMs: number;
readonly measurementStartEpochMs: number;
readonly operationStartEpochMs: number;
readonly terminalEpochMs: number;
}): void {
const epochs = Object.values(input);
if (
!epochs.every((epoch) => Number.isFinite(epoch) && epoch > 0) ||
input.measurementStartEpochMs < input.operationStartEpochMs ||
input.terminalEpochMs < input.measurementStartEpochMs ||
input.captureCutoffEpochMs < input.terminalEpochMs
) {
throw new Error('renderer-measurement-window-invalid');
}
}
@@ -82,7 +82,10 @@ async function runScenario(
assertSyntheticM3uImportUrl(server.resourceUrl);
await server.prime();
await assertPerformanceArtifactCapacity(scenarioDirectory);
await mkdir(scenarioDirectory, { recursive: false });
await mkdir(scenarioDirectory, {
mode: 0o700,
recursive: false,
});
for (const definition of definitions) {
console.log(
`[performance] ${config.variant}/${scenario.id}/${definition.runId} starting`
@@ -163,7 +166,10 @@ async function runIteration(
): Promise<M3uImportIterationResult> {
const iterationDirectory = join(scenarioDirectory, definition.runId);
await assertPerformanceArtifactCapacity(iterationDirectory);
await mkdir(iterationDirectory, { recursive: false });
await mkdir(iterationDirectory, {
mode: 0o700,
recursive: false,
});
const dataDirectory = await mkdtemp(
join(tmpdir(), 'iptvnator-m3u-import-performance-')
);
@@ -179,6 +185,7 @@ async function runIteration(
`--remote-debugging-port=${config.rendererCdpPort}`,
`--user-data-dir=${join(dataDirectory, 'user-data')}`,
],
environmentInheritance: 'runtime-only',
env: {
IPTVNATOR_DB_WORKER_BATCH_DELAY_MS: '0',
IPTVNATOR_PERF_CAPTURE: '1',
@@ -188,10 +195,7 @@ async function runIteration(
},
});
app.mainWindow.setDefaultTimeout(120_000);
await assertRendererCdpTarget(
app.mainWindow,
config.rendererCdpPort
);
await assertRendererCdpTarget(app.mainWindow, config.rendererCdpPort);
await installMainCapture(app.electronApp);
const rendererWindowIdentity = await resolveRendererWindowIdentity(app);
const requestsBefore = server.requestCount();
@@ -1,7 +1,7 @@
import type { RendererProcessRssCapture } from './renderer-process-rss-capture';
import type { RendererRssValidity } from './renderer-rss-validity';
import type {
AppPlaylistPerformancePhase,
DatabaseWorkerPerformancePhase,
PerformancePhaseEvent,
} from '@iptvnator/shared/interfaces';
@@ -57,8 +57,7 @@ export type WorkerPostGcHeapCapture =
};
export const WORKER_PEAK_MEMORY_UNAVAILABLE_REASON = {
EXTERNAL_MEMORY_SAMPLES_MISSING:
'worker-external-memory-samples-missing',
EXTERNAL_MEMORY_SAMPLES_MISSING: 'worker-external-memory-samples-missing',
HEAP_USED_SAMPLES_MISSING: 'worker-heap-used-samples-missing',
} as const;
@@ -86,17 +85,23 @@ export interface ProcessMemoryMetrics {
}
export interface MainTimelineRecord {
readonly action?: string | null;
readonly boundary?: 'end' | 'start';
readonly byteCount?: number;
readonly categoryType?: string | null;
readonly contentType?: string | null;
readonly durationMs?: number | null;
readonly epochMs: number;
readonly ipcCallId?: number;
readonly itemCount?: number;
readonly itemCount?: number | null;
readonly method?: string;
readonly operation?: string;
readonly operationId?: string;
readonly operationId?: string | null;
readonly outcome?: 'error' | 'success' | null;
readonly phase?: string;
readonly playlistId?: string;
readonly playlistId?: string | null;
readonly requestId?: string;
readonly sessionId?: string | null;
readonly success?: boolean;
readonly sourceEpochMs?: number;
readonly type: string;
@@ -114,7 +119,7 @@ export interface WorkerRequestPerformanceMetrics {
readonly operationId: string | null;
readonly operationIdUnavailableReason: string | null;
readonly performanceCaptureUnavailableReason: string | null;
readonly phaseEvents: readonly PerformancePhaseEvent<AppPlaylistPerformancePhase>[];
readonly phaseEvents: readonly PerformancePhaseEvent<DatabaseWorkerPerformancePhase>[];
readonly playlistId: string | null;
readonly requestId: string | null;
readonly requestReceivedEpochMs: number | null;
@@ -186,7 +186,10 @@ async function runIteration(
): Promise<CancellationIterationResult> {
const iterationDirectory = join(config.outputDirectory, definition.runId);
await assertPerformanceArtifactCapacity(iterationDirectory);
await mkdir(iterationDirectory, { recursive: false });
await mkdir(iterationDirectory, {
mode: 0o700,
recursive: false,
});
const dataDirectory = await mkdtemp(
join(tmpdir(), 'iptvnator-m3u-performance-')
);
@@ -204,6 +207,7 @@ async function runIteration(
`--remote-debugging-port=${RENDERER_CDP_PORT}`,
`--user-data-dir=${join(dataDirectory, 'user-data')}`,
],
environmentInheritance: 'runtime-only',
env: {
IPTVNATOR_DB_WORKER_BATCH_DELAY_MS: '0',
IPTVNATOR_PERF_CAPTURE: '1',
@@ -448,7 +452,10 @@ async function resolveConfiguration(): Promise<BenchmarkConfiguration> {
const outputDirectory = join(outputRoot, variant);
await assertMissing(outputDirectory);
await assertPerformanceArtifactCapacity(outputDirectory);
await mkdir(outputDirectory, { recursive: true });
await mkdir(outputDirectory, {
mode: 0o700,
recursive: true,
});
return Object.freeze({
electronVersion: electronPackage.version,
gitCommit: sourceState.commit,
File diff suppressed because it is too large. Load diff
@@ -1,8 +1,8 @@
/* eslint-disable max-lines -- Renderer CDP and injected-page lifecycle are kept together so raw artifact boundaries stay auditable. */
import { once } from 'node:events';
import { createWriteStream } from 'node:fs';
import { writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { finished } from 'node:stream/promises';
import type { CDPSession, Page } from '@playwright/test';
@@ -106,7 +106,8 @@ export async function startRendererCapture(
await session.send('Profiler.enable');
await session.send('Profiler.start');
traceOutput = createWriteStream(
requireArtifactPath(tracePath, 'renderer trace')
requireArtifactPath(tracePath, 'renderer trace'),
{ flags: 'wx', mode: 0o600 }
);
traceOutput.write('{"traceEvents":[');
session.on('Tracing.dataCollected', onTraceData);
@@ -143,7 +144,7 @@ export async function startRendererCapture(
await writeFile(
requireArtifactPath(cpuProfilePath, 'renderer CPU profile'),
JSON.stringify(cpuProfile['profile']),
'utf8'
{ encoding: 'utf8', flag: 'wx', mode: 0o600 }
);
await session.send('Tracing.end');
await traceComplete;
@@ -152,7 +153,7 @@ export async function startRendererCapture(
traceOutput?.write(']}');
traceOutput?.end();
if (traceOutput) {
await once(traceOutput, 'finish');
await finished(traceOutput);
}
}
@@ -167,7 +168,8 @@ export async function startRendererCapture(
requireArtifactPath(
heapSnapshotPath,
'renderer heap snapshot'
)
),
{ flags: 'wx', mode: 0o600 }
);
const onSnapshotChunk = (message: {
readonly chunk: string;
@@ -186,7 +188,7 @@ export async function startRendererCapture(
onSnapshotChunk
);
output.end();
await once(output, 'finish');
await finished(output);
}
await session.detach();
@@ -211,8 +213,7 @@ export async function startRendererCapture(
unknown
>;
const state = target[stateKey] as
| { cancelClickEpochMs: number | null }
| undefined;
{ cancelClickEpochMs: number | null } | undefined;
return typeof state?.cancelClickEpochMs === 'number';
},
RENDERER_CAPTURE_STATE_KEY,
@@ -228,8 +229,7 @@ export async function startRendererCapture(
unknown
>;
const state = target[stateKey] as
| { uiPaintedEpochMs: number | null }
| undefined;
{ uiPaintedEpochMs: number | null } | undefined;
return typeof state?.uiPaintedEpochMs === 'number';
},
RENDERER_CAPTURE_STATE_KEY,
@@ -0,0 +1,81 @@
/* eslint-disable playwright/expect-expect -- This is a Node assertion-based performance contract test. */
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import test from 'node:test';
const source = readFileSync(
new URL('./m3u-refresh-main-capture.ts', import.meta.url),
'utf8'
);
function section(startMarker: string, endMarker: string): string {
const start = source.indexOf(startMarker);
const end = source.indexOf(endMarker, start);
assert.ok(start >= 0, `missing start marker: ${startMarker}`);
assert.ok(end > start, `missing end marker: ${endMarker}`);
return source.slice(start, end);
}
test('samples main and worker memory from one shared interval scheduler', () => {
const workerRecord = section(
'interface WorkerRecord',
'interface TimelineRecord'
);
const resetWorker = section(
'const resetWorkerForCapture',
'const startWorker'
);
const startWorker = section(
'const startWorker',
'const stopWorkerSampling'
);
const stopWorker = section(
'const stopWorkerSampling',
'const joinFinalWorkerSample'
);
const joinFinalWorker = section(
'const joinFinalWorkerSample',
'const stopWorkerProfile'
);
const sampleMain = section('const sampleMain', 'const startCapture');
const beginMeasurement = section(
'const beginMeasurement = async',
'const startCapture'
);
const armCapture = section('const startCapture', 'const api =');
const stopCapture = section(
'stop: async (',
'xtreamStatus: (): XtreamMainCaptureStatus'
);
assert.match(workerRecord, /samplingStarted: boolean/);
assert.doesNotMatch(workerRecord, /sampleTimer/);
assert.match(resetWorker, /record\.samplingStarted = false/);
assert.match(startWorker, /if \(record\.samplingStarted\)/);
assert.match(
startWorker,
/record\.samplingStarted = true[\s\S]*const initialSample = sampleWorker\(record\)/
);
assert.doesNotMatch(startWorker, /setInterval/);
assert.match(stopWorker, /record\.samplingStarted = false/);
assert.match(joinFinalWorker, /await sampleWorker\(record\)/);
assert.match(
sampleMain,
/for \(const record of records\.values\(\)\)[\s\S]*record\.samplingStarted &&[\s\S]*isCurrentCaptureRecord\(record\)[\s\S]*void sampleWorker\(record\)/
);
assert.match(
beginMeasurement,
/sampleMain\(\)[\s\S]*state\.sampleTimer = setInterval\(sampleMain, 20\)/
);
assert.doesNotMatch(armCapture, /setInterval\(sampleMain/);
assert.match(
stopCapture,
/clearInterval\(state\.sampleTimer\)[\s\S]*state\.sampleTimer = null[\s\S]*await startCapture\(nextOptions\)/
);
assert.equal(
source.match(/\bsetInterval\s*\(/g)?.length,
1,
'the injected main capture must own exactly one interval timer'
);
});
@@ -0,0 +1,18 @@
/**
* Phase duration and epoch endpoints are read from separate clocks in separate
* calls. The enclosing request/operation window is the causal upper bound.
*/
export function fitsPerformanceDurationEnvelope(
durationMs: number,
envelopeStartEpochMs: number,
envelopeEndEpochMs: number
): boolean {
return (
Number.isFinite(durationMs) &&
durationMs >= 0 &&
Number.isFinite(envelopeStartEpochMs) &&
Number.isFinite(envelopeEndEpochMs) &&
envelopeEndEpochMs >= envelopeStartEpochMs &&
durationMs <= envelopeEndEpochMs - envelopeStartEpochMs
);
}
@@ -2,11 +2,74 @@ import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
createDiagnosticsPerformancePhaseEventParser,
pairPerformancePhaseEvents,
requirePerformancePhase,
} from './performance-phase-events';
describe('performance phase event pairing', () => {
it('restores and invokes the diagnostics parser without module-scoped helpers', () => {
const restore = <T>(source: string): T =>
new Function(`"use strict"; return (${source});`)() as T;
const restored = restore<
typeof createDiagnosticsPerformancePhaseEventParser
>(createDiagnosticsPerformancePhaseEventParser.toString());
const parse = restored({
allowedPhases: ['xtream.network.total'],
timelineType: 'xtream-main-phase',
});
assert.deepEqual(
parse({
boundary: 'start',
durationMs: null,
epochMs: 100,
phase: 'xtream.network.total',
requestId: 'xtream-mock1-1',
}),
{
boundary: 'start',
durationMs: null,
epochMs: 100,
phase: 'xtream.network.total',
requestId: 'xtream-mock1-1',
type: 'xtream-main-phase',
}
);
});
it('keeps the valid M3U diagnostics normalization byte-identical when subscriptions are parameterized', () => {
const parse = createDiagnosticsPerformancePhaseEventParser({
allowedPhases: ['data.acquire', 'parse.m3u', 'normalize'],
timelineType: 'm3u-import-phase',
});
const incoming = {
boundary: 'end',
durationMs: 12.5,
epochMs: 113,
metadata: { byteCount: 2048, itemCount: 10 },
phase: 'data.acquire',
requestId: 'request-1',
};
const legacyNormalized = {
boundary: 'end',
byteCount: 2048,
durationMs: 12.5,
epochMs: 113,
itemCount: 10,
phase: 'data.acquire',
requestId: 'request-1',
type: 'm3u-import-phase',
};
assert.equal(
JSON.stringify(parse(incoming)),
JSON.stringify(legacyNormalized)
);
assert.equal(parse({ ...incoming, secret: 'not allowed' }), null);
assert.equal(parse({ ...incoming, metadata: { itemCount: -1 } }), null);
});
it('pairs request-scoped boundaries and preserves end metadata', () => {
const phases = pairPerformancePhaseEvents([
{
@@ -18,6 +18,107 @@ interface ParsedPerformancePhaseEvent {
readonly requestId: string;
}
export interface DiagnosticsPerformancePhaseEventParserOptions {
readonly allowedPhases: readonly string[];
readonly timelineType: string;
}
export interface DiagnosticsPerformancePhaseTimelineEvent {
readonly boundary: 'end' | 'start';
readonly byteCount?: number;
readonly durationMs: number | null;
readonly epochMs: number;
readonly itemCount?: number;
readonly phase: string;
readonly requestId: string;
readonly type: string;
}
export function createDiagnosticsPerformancePhaseEventParser(
options: DiagnosticsPerformancePhaseEventParserOptions
): (input: unknown) => DiagnosticsPerformancePhaseTimelineEvent | null {
const allowedPhases = new Set(options.allowedPhases);
const eventKeys = new Set([
'boundary',
'durationMs',
'epochMs',
'metadata',
'phase',
'requestId',
]);
const metadataKeys = new Set(['byteCount', 'itemCount']);
const helpers = {
isCount(value: unknown): value is number {
return Number.isSafeInteger(value) && Number(value) >= 0;
},
isRecord(value: unknown): value is Record<string, unknown> {
return (
typeof value === 'object' &&
value !== null &&
!Array.isArray(value)
);
},
};
return (input: unknown) => {
if (
!helpers.isRecord(input) ||
Object.keys(input).some((key) => !eventKeys.has(key))
) {
return null;
}
const boundary = input['boundary'];
const durationMs = input['durationMs'];
const epochMs = input['epochMs'];
const metadata = input['metadata'];
const phase = input['phase'];
const requestId = input['requestId'];
if (
(boundary !== 'start' && boundary !== 'end') ||
typeof epochMs !== 'number' ||
!Number.isFinite(epochMs) ||
epochMs < 0 ||
typeof phase !== 'string' ||
!allowedPhases.has(phase) ||
typeof requestId !== 'string' ||
requestId.length === 0 ||
(boundary === 'start' && durationMs !== null) ||
(boundary === 'end' &&
(typeof durationMs !== 'number' ||
!Number.isFinite(durationMs) ||
durationMs < 0))
) {
return null;
}
if (
metadata !== undefined &&
(!helpers.isRecord(metadata) ||
Object.keys(metadata).some((key) => !metadataKeys.has(key)) ||
Object.values(metadata).some(
(value) => !helpers.isCount(value)
))
) {
return null;
}
const byteCount = helpers.isRecord(metadata)
? metadata['byteCount']
: undefined;
const itemCount = helpers.isRecord(metadata)
? metadata['itemCount']
: undefined;
return {
boundary,
...(helpers.isCount(byteCount) ? { byteCount } : {}),
durationMs: durationMs as number | null,
epochMs,
...(helpers.isCount(itemCount) ? { itemCount } : {}),
phase,
requestId,
type: options.timelineType,
};
};
}
export function pairPerformancePhaseEvents(
input: readonly unknown[]
): readonly PairedPerformancePhase[] {
@@ -0,0 +1,126 @@
import assert from 'node:assert/strict';
import { EventEmitter } from 'node:events';
import { mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, test } from 'node:test';
import {
createRendererArtifactCapture,
startRendererDiagnosticCapture,
stopRendererDiagnosticCapture,
takeRendererHeapSnapshot,
} from './m3u-import-renderer-artifacts';
const directories: string[] = [];
afterEach(async () => {
await Promise.all(
directories
.splice(0)
.map((directory) => rm(directory, { force: true, recursive: true }))
);
});
test('creates renderer raw profiles exclusively with owner-only permissions', async () => {
const directory = await createDirectory();
const session = new FakeCdpSession();
const artifacts = createRendererArtifactCapture({
diagnostic: true,
outputDirectory: directory,
});
await startRendererDiagnosticCapture(session as never, artifacts);
await stopRendererDiagnosticCapture(session as never, artifacts);
await takeRendererHeapSnapshot(
session as never,
artifacts.heapSnapshotPath
);
for (const filename of [
'renderer.cpuprofile',
'renderer.heapsnapshot',
'renderer.trace.json',
]) {
assert.equal(
(await stat(join(directory, filename))).mode & 0o777,
0o600,
filename
);
}
});
test('never replaces an existing renderer CPU profile', async () => {
const directory = await createDirectory();
const profilePath = join(directory, 'renderer.cpuprofile');
await writeFile(profilePath, 'original', 'utf8');
const session = new FakeCdpSession();
const artifacts = createRendererArtifactCapture({
diagnostic: true,
outputDirectory: directory,
});
await startRendererDiagnosticCapture(session as never, artifacts);
await assert.rejects(
stopRendererDiagnosticCapture(session as never, artifacts),
{ code: 'EEXIST' }
);
assert.equal(await readFile(profilePath, 'utf8'), 'original');
});
test('uses exclusive owner-only writes for main and worker raw artifacts', async () => {
const source = await readFile(
new URL('./m3u-refresh-main-capture.ts', import.meta.url),
'utf8'
);
assert.match(
source,
/fs\.writeFileSync\(\s*record\.profilePath,[\s\S]{0,220}flag: 'wx',[\s\S]{0,80}mode: 0o600/
);
assert.match(
source,
/fs\.createWriteStream\(record\.snapshotPath,\s*\{[\s\S]{0,80}flags: 'wx',[\s\S]{0,80}mode: 0o600/
);
assert.match(
source,
/fs\.writeFileSync\(\s*state\.mainProfilePath,[\s\S]{0,220}flag: 'wx',[\s\S]{0,80}mode: 0o600/
);
assert.match(
source,
/fs\.createWriteStream\(\s*state\.mainSnapshotPath,\s*\{[\s\S]{0,80}flags: 'wx',[\s\S]{0,80}mode: 0o600/
);
});
class FakeCdpSession extends EventEmitter {
async send(method: string): Promise<Record<string, unknown>> {
if (method === 'Profiler.stop') {
return {
profile: {
endTime: 2,
nodes: [{ callFrame: {}, hitCount: 1, id: 1 }],
samples: [1],
startTime: 1,
timeDeltas: [1],
},
};
}
if (method === 'Tracing.end') {
this.emit('Tracing.tracingComplete');
}
if (method === 'HeapProfiler.takeHeapSnapshot') {
this.emit('HeapProfiler.addHeapSnapshotChunk', {
chunk: '{"snapshot":{}}',
});
}
return {};
}
}
async function createDirectory(): Promise<string> {
const directory = await mkdtemp(
join(tmpdir(), 'iptvnator-performance-artifact-')
);
directories.push(directory);
return directory;
}
@@ -0,0 +1,53 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
createPerformanceTimelineMergeApi,
type PerformanceTimelineMergeApi,
} from './performance-timeline-merge';
describe('performance timeline merge', () => {
it('restores without module closures for Electron-main injection', () => {
const source = createPerformanceTimelineMergeApi.toString();
assert.doesNotMatch(source, /__name/);
const factory = new Function(
`"use strict"; return (${source});`
)() as typeof createPerformanceTimelineMergeApi;
assert.equal(factory().merge([], []).length, 0);
});
it('inserts Xtream records by epoch without reordering existing M3U JSON', () => {
const api: PerformanceTimelineMergeApi =
createPerformanceTimelineMergeApi();
const baseline = [
{ epochMs: 100, type: 'm3u-a' },
{ epochMs: 300, type: 'm3u-b' },
{ epochMs: 300, type: 'm3u-c' },
];
const additions = [
{ epochMs: 300, type: 'xtream-c' },
{ epochMs: 50, type: 'xtream-a' },
{ epochMs: 200, type: 'xtream-b' },
{ epochMs: 400, type: 'xtream-d' },
];
const merged = api.merge(baseline, additions);
assert.deepEqual(
merged.map(({ type }) => type),
[
'xtream-a',
'm3u-a',
'xtream-b',
'm3u-b',
'm3u-c',
'xtream-c',
'xtream-d',
]
);
assert.equal(
JSON.stringify(merged.filter(({ type }) => type.startsWith('m3u'))),
JSON.stringify(baseline)
);
});
});
@@ -0,0 +1,62 @@
export interface PerformanceTimelineRecord {
readonly epochMs: number;
}
export interface PerformanceTimelineMergeApi {
merge<T extends PerformanceTimelineRecord>(
baseline: readonly T[],
additions: readonly T[]
): T[];
}
export function createPerformanceTimelineMergeApi(): PerformanceTimelineMergeApi {
const helpers = {
compare(
left: {
readonly index: number;
readonly record: PerformanceTimelineRecord;
},
right: {
readonly index: number;
readonly record: PerformanceTimelineRecord;
}
): number {
return (
left.record.epochMs - right.record.epochMs ||
left.index - right.index
);
},
};
const api: PerformanceTimelineMergeApi = {
merge<T extends PerformanceTimelineRecord>(
baseline: readonly T[],
additions: readonly T[]
): T[] {
const indexed: Array<{ index: number; record: T }> = [];
for (let index = 0; index < additions.length; index += 1) {
indexed.push({ index, record: additions[index] as T });
}
indexed.sort(helpers.compare);
const merged: T[] = [];
let additionIndex = 0;
for (const record of baseline) {
while (
additionIndex < indexed.length &&
(indexed[additionIndex]?.record.epochMs ??
Number.POSITIVE_INFINITY) < record.epochMs
) {
merged.push(indexed[additionIndex]?.record as T);
additionIndex += 1;
}
merged.push(record);
}
while (additionIndex < indexed.length) {
merged.push(indexed[additionIndex]?.record as T);
additionIndex += 1;
}
return merged;
},
};
return Object.freeze(api);
}
@@ -0,0 +1,107 @@
/* eslint-disable playwright/expect-expect -- These are Node assertion-based performance contract tests. */
import assert from 'node:assert/strict';
import test from 'node:test';
import { parseWorkerPerformancePhaseEvents } from './worker-performance-phase-events';
import { parseXtreamWorkerPerformancePhaseEvents } from './xtream-worker-phase-events';
function phasePair(
phase: string,
startEpochMs: number,
durationMs: number,
requestId = 'request-1'
) {
return [
{
boundary: 'start',
durationMs: null,
epochMs: startEpochMs,
phase,
requestId,
},
{
boundary: 'end',
durationMs,
epochMs: startEpochMs + 1,
metadata: { itemCount: 1 },
phase,
requestId,
},
];
}
test('accepts producer-shaped worker output when separately read clocks have a wider monotonic duration', () => {
const events = phasePair('sqlite.categories.read', 11, 1.6115);
const parsed = parseXtreamWorkerPerformancePhaseEvents(
'DB_GET_CATEGORIES',
events,
10,
30,
true
);
assert.deepEqual(parsed, events);
assert.equal(Number(events[1]?.epochMs) - Number(events[0]?.epochMs), 1);
});
test('rejects an Xtream worker duration outside its request envelope', () => {
assert.equal(
parseXtreamWorkerPerformancePhaseEvents(
'DB_GET_CATEGORIES',
phasePair('sqlite.categories.read', 11, 999),
10,
30,
true
),
null
);
});
test('rejects an out-of-envelope duration in a failed partial DB_SAVE_CONTENT capture', () => {
const events = [
...phasePair('sqlite.content.category-map-read', 11, 1),
...phasePair('normalize.content', 13, 999),
];
assert.equal(
parseXtreamWorkerPerformancePhaseEvents(
'DB_SAVE_CONTENT',
events,
10,
30,
false
),
null
);
});
test('accepts cross-clock skew but rejects an app-playlist duration outside the request envelope', () => {
const producerShaped = [
...phasePair('sqlite.read', 11, 1.6115),
...phasePair('deserialize.playlist', 13, 1),
];
assert.deepEqual(
parseWorkerPerformancePhaseEvents(
'DB_GET_APP_PLAYLIST',
producerShaped,
10,
30,
true
),
producerShaped
);
const outsideEnvelope = [
...phasePair('sqlite.read', 11, 20.001),
...phasePair('deserialize.playlist', 13, 1),
];
assert.equal(
parseWorkerPerformancePhaseEvents(
'DB_GET_APP_PLAYLIST',
outsideEnvelope,
10,
30,
true
),
null
);
});
@@ -2,9 +2,12 @@ import {
APP_PLAYLIST_GET_PERFORMANCE_PHASE,
APP_PLAYLIST_UPSERT_PERFORMANCE_PHASE,
type AppPlaylistPerformancePhase,
type DatabaseWorkerPerformancePhase,
type PerformancePhaseEvent,
type PerformancePhaseMetadata,
} from '@iptvnator/shared/interfaces';
import { fitsPerformanceDurationEnvelope } from './performance-phase-duration-envelope';
import { parseXtreamWorkerPerformancePhaseEvents } from './xtream-worker-phase-events';
const PHASE_SEQUENCES = {
DB_GET_APP_PLAYLIST: [
@@ -31,8 +34,20 @@ export function parseWorkerPerformancePhaseEvents(
operation: string | null,
input: unknown,
workStartedEpochMs: number,
workEndedEpochMs: number
): readonly PerformancePhaseEvent<AppPlaylistPerformancePhase>[] | null {
workEndedEpochMs: number,
requestSucceeded: boolean
): readonly PerformancePhaseEvent<DatabaseWorkerPerformancePhase>[] | null {
const xtreamEvents = parseXtreamWorkerPerformancePhaseEvents(
operation,
input,
workStartedEpochMs,
workEndedEpochMs,
requestSucceeded
);
if (xtreamEvents !== undefined) {
return xtreamEvents;
}
const phaseSequence = getPhaseSequence(operation);
if (phaseSequence.length === 0) {
return input === undefined ||
@@ -40,15 +55,11 @@ export function parseWorkerPerformancePhaseEvents(
? []
: null;
}
if (
!Array.isArray(input) ||
input.length !== phaseSequence.length * 2
) {
if (!Array.isArray(input) || input.length !== phaseSequence.length * 2) {
return null;
}
const parsed: PerformancePhaseEvent<AppPlaylistPerformancePhase>[] =
[];
const parsed: PerformancePhaseEvent<AppPlaylistPerformancePhase>[] = [];
let lastEpochMs = workStartedEpochMs;
for (let index = 0; index < input.length; index += 1) {
const raw = input[index];
@@ -81,6 +92,18 @@ export function parseWorkerPerformancePhaseEvents(
) {
return null;
}
const phaseStart = parsed[parsed.length - 1];
if (
boundary === 'end' &&
(!phaseStart ||
!fitsPerformanceDurationEnvelope(
Number(durationMs),
workStartedEpochMs,
workEndedEpochMs
))
) {
return null;
}
parsed.push({
boundary: boundary as 'end' | 'start',
@@ -21,10 +21,7 @@ const validCapture = {
workStartedEpochMs: 1_010,
} as const;
function normalizeForOperation(
operation: string,
performanceCapture: unknown
) {
function normalizeForOperation(operation: string, performanceCapture: unknown) {
return normalizeWorkerRequestPerformanceOutcome({
ipcCallId: 2,
operation,
@@ -40,7 +37,7 @@ function normalizeForOperation(
}
function normalize(performanceCapture: unknown) {
return normalizeForOperation('DB_GET_CONTENT', performanceCapture);
return normalizeForOperation('DB_HAS_CONTENT', performanceCapture);
}
function assertClosedCapture(
@@ -313,10 +310,7 @@ test('requires the exact operation-specific worker phase sequence', () => {
);
}
for (const operation of [
'DB_GET_APP_PLAYLIST',
'DB_UPSERT_APP_PLAYLIST',
]) {
for (const operation of ['DB_GET_APP_PLAYLIST', 'DB_UPSERT_APP_PLAYLIST']) {
assertClosedCapture(
normalizeForOperation(operation, validCapture),
'worker-performance-capture-invalid'
@@ -325,3 +319,68 @@ test('requires the exact operation-specific worker phase sequence', () => {
assert.deepEqual(normalize(validCapture).phaseEvents, []);
});
test('routes finalized Xtream phase sequences before the legacy M3U parser', () => {
const xtreamPhaseEvents = [
{
boundary: 'start',
durationMs: null,
epochMs: 1_015,
phase: 'sqlite.content.category-map-read',
requestId: 'request-1',
},
{
boundary: 'end',
durationMs: 2,
epochMs: 1_017,
metadata: { itemCount: 60 },
phase: 'sqlite.content.category-map-read',
requestId: 'request-1',
},
{
boundary: 'start',
durationMs: null,
epochMs: 1_018,
phase: 'normalize.content',
requestId: 'request-1',
},
{
boundary: 'end',
durationMs: 5,
epochMs: 1_023,
metadata: { itemCount: 60_000 },
phase: 'normalize.content',
requestId: 'request-1',
},
{
boundary: 'start',
durationMs: null,
epochMs: 1_024,
phase: 'sqlite.content.write-transactions',
requestId: 'request-1',
},
{
boundary: 'end',
durationMs: 10,
epochMs: 1_034,
metadata: { itemCount: 60_000 },
phase: 'sqlite.content.write-transactions',
requestId: 'request-1',
},
] as const;
assert.deepEqual(
normalizeForOperation('DB_SAVE_CONTENT', {
...validCapture,
phaseEvents: xtreamPhaseEvents,
}).phaseEvents,
xtreamPhaseEvents
);
assertClosedCapture(
normalizeForOperation('DB_SAVE_CONTENT', {
...validCapture,
phaseEvents: xtreamPhaseEvents.slice(0, -2),
}),
'worker-performance-capture-invalid'
);
});
@@ -55,7 +55,7 @@ function requestTransport(
) {
return {
ipcCallId: 7,
operation: 'DB_GET_CONTENT',
operation: 'DB_HAS_CONTENT',
operationId: 'operation-42',
operationIdUnavailableReason: null,
performanceCapture,
@@ -227,7 +227,7 @@ test('main capture retains raw request identity, timestamps, metrics, and reason
assert.match(source, /ipcCallId: request\.identity\.ipcCallId/);
assert.match(source, /identity: request\.identity/);
assert.match(source, /performanceCapture:\s+message\['performance'\]/);
assert.match(source, /sourceEpochMs: request\.identity\.sourceEpochMs/);
assert.match(source, /sourceEpochMs:\s+request\.identity\.sourceEpochMs/);
assert.match(source, /captureGeneration: state\.captureGeneration/);
assert.doesNotMatch(
source,
@@ -152,7 +152,8 @@ function parseEventLoopDelay(
function parseWorkerPerformanceCapture(
input: unknown,
operation: string | null
operation: string | null,
requestSucceeded: boolean
): ParsedWorkerPerformanceCapture | null {
if (!isRecord(input)) {
return null;
@@ -203,7 +204,8 @@ function parseWorkerPerformanceCapture(
operation,
input['phaseEvents'],
workStartedEpochMs,
workEndedEpochMs
workEndedEpochMs,
requestSucceeded
);
if (phaseEvents === null) {
return null;
@@ -318,7 +320,8 @@ export function normalizeWorkerRequestPerformanceOutcome(
const performanceCapture = parseWorkerPerformanceCapture(
input.performanceCapture,
input.operation
input.operation,
input.success
);
if (!performanceCapture) {
return unavailable('worker-performance-capture-invalid');
@@ -0,0 +1,78 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_SCENARIO_ID,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import { attributeXtreamPhases } from './xtream-phase-attribution';
import { scenarioCapture } from './xtream-phase-attribution.fixtures';
import {
expectedXtreamIpc,
expectedXtreamPhases,
XTREAM_ATTRIBUTION_PHASE as PHASE,
XTREAM_PHASE_SEMANTIC_TYPE as SEMANTIC,
} from './xtream-phase-inventory';
const EXPECTED_PROVIDER_CALLS: Readonly<Record<XtreamScenarioId, number>> = {
[XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE]: 8,
[XTREAM_SCENARIO_ID.REFRESH_LARGE]: 8,
[XTREAM_SCENARIO_ID.DELETE_LARGE]: 0,
[XTREAM_SCENARIO_ID.CANCEL_IMPORT]: 6,
[XTREAM_SCENARIO_ID.BACKGROUND_UI]: 8,
};
const EXPECTED_ACCOUNT_CALLS: Readonly<Record<XtreamScenarioId, number>> = {
[XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE]: 2,
[XTREAM_SCENARIO_ID.REFRESH_LARGE]: 2,
[XTREAM_SCENARIO_ID.DELETE_LARGE]: 0,
[XTREAM_SCENARIO_ID.CANCEL_IMPORT]: 2,
[XTREAM_SCENARIO_ID.BACKGROUND_UI]: 2,
};
describe('Xtream account phase inventory', () => {
it('counts every scenario-specific provider IPC and phase lifecycle', () => {
for (const scenarioId of Object.values(XTREAM_SCENARIO_ID)) {
const providerCalls = EXPECTED_PROVIDER_CALLS[scenarioId];
assert.equal(
expectedXtreamPhases(scenarioId).get(PHASE.NETWORK_TOTAL)
?.occurrences,
providerCalls
);
assert.equal(
expectedXtreamIpc(scenarioId).get('xtreamRequest')?.success ??
0,
providerCalls
);
}
});
it('fixtures contain the exact account lifecycle count and remain valid', () => {
for (const scenarioId of Object.values(XTREAM_SCENARIO_ID)) {
const capture = scenarioCapture(scenarioId);
const accounts = capture.events.filter(
({ boundary, phase, semanticType }) =>
boundary === 'start' &&
phase === PHASE.NETWORK_TOTAL &&
semanticType === SEMANTIC.ACCOUNT
);
assert.equal(accounts.length, EXPECTED_ACCOUNT_CALLS[scenarioId]);
assert.doesNotThrow(() => attributeXtreamPhases(capture));
}
});
it('allows the two independent fresh-add account phases to overlap', () => {
const capture = scenarioCapture(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE
);
const events = capture.events.map((event) =>
event.correlationId === 'provider-account-route'
? { ...event, epochMs: event.epochMs - 6.5 }
: event
);
assert.doesNotThrow(() =>
attributeXtreamPhases({ ...capture, events })
);
});
});
@@ -0,0 +1,196 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_MAIN_PERFORMANCE_PHASE,
XTREAM_PRELOAD_PERFORMANCE_METHOD,
XtreamCodeActions,
} from '@iptvnator/shared/interfaces';
import {
createXtreamIpcMarkerCapture,
type XtreamIpcMarkerCapture,
type XtreamIpcMarkerCaptureOptions,
} from './xtream-ipc-marker-events';
const OPTIONS: XtreamIpcMarkerCaptureOptions = {
actions: Object.values(XtreamCodeActions),
mainPhases: Object.values(XTREAM_MAIN_PERFORMANCE_PHASE),
methods: Object.values(XTREAM_PRELOAD_PERFORMANCE_METHOD),
schemaVersion: 1,
};
describe('Xtream account phase correlation', () => {
it('accepts overlapping null-session calls and links main phases FIFO', () => {
const capture = createXtreamIpcMarkerCapture(OPTIONS);
capture.start(42, 90);
assert.equal(
capture.acceptPreload(42, 100, accountMarker(1, 99)),
true
);
assert.equal(
capture.acceptPreload(42, 102, accountMarker(2, 101)),
true
);
acceptAccountMainLifecycle(capture, 1, 103);
assert.equal(
capture.acceptPreload(42, 113, accountMarker(1, 112, 'end')),
true
);
acceptAccountMainLifecycle(capture, 2, 114);
assert.equal(
capture.acceptPreload(42, 124, accountMarker(2, 123, 'end')),
true
);
const snapshot = capture.stop();
assert.deepEqual(snapshot.invalidReasons, []);
assert.equal(snapshot.quarantinedKeyCount, 0);
const phases = snapshot.timeline.filter(
({ type }) => type === 'xtream-main-phase'
);
assert.deepEqual(
phases.map(({ action, ipcCallId }) => ({ action, ipcCallId })),
[
...Array.from({ length: 6 }, () => ({
action: XtreamCodeActions.GetAccountInfo,
ipcCallId: 1,
})),
...Array.from({ length: 6 }, () => ({
action: XtreamCodeActions.GetAccountInfo,
ipcCallId: 2,
})),
]
);
});
it('fails closed for duplicate and malformed preload call IDs', () => {
const capture = createXtreamIpcMarkerCapture(OPTIONS);
capture.start(42, 90);
assert.equal(
capture.acceptPreload(42, 100, accountMarker(1, 99)),
true
);
assert.equal(
capture.acceptPreload(42, 102, accountMarker(1, 101)),
false
);
assert.equal(
capture.acceptPreload(42, 104, accountMarker(0, 103)),
false
);
const snapshot = capture.stop();
assert.equal(snapshot.quarantinedKeyCount, 1);
assert.ok(
snapshot.invalidReasons.includes('preload-marker-duplicate-key')
);
});
});
function acceptAccountMainLifecycle(
capture: XtreamIpcMarkerCapture,
ipcCallId: number,
offset: number
): void {
const requestId = `xtream-account-${ipcCallId}`;
acceptMainBoundary(
capture,
requestId,
'xtream.network.total',
offset + 1,
'start'
);
acceptMainPair(
capture,
requestId,
'xtream.json.transform',
offset + 2,
offset + 3
);
acceptMainBoundary(
capture,
requestId,
'xtream.network.total',
offset + 6,
'end',
5
);
acceptMainPair(
capture,
requestId,
'xtream.response.ready',
offset + 7,
offset + 8
);
}
function acceptMainBoundary(
capture: XtreamIpcMarkerCapture,
requestId: string,
phase: string,
epochMs: number,
boundary: 'end' | 'start',
durationMs: number | null = null
): void {
assert.equal(
capture.acceptMainPhase({
boundary,
durationMs,
epochMs,
phase,
requestId,
}),
true
);
}
function acceptMainPair(
capture: XtreamIpcMarkerCapture,
requestId: string,
phase: string,
startEpochMs: number,
endEpochMs: number
): void {
assert.equal(
capture.acceptMainPhase({
boundary: 'start',
durationMs: null,
epochMs: startEpochMs,
phase,
requestId,
}),
true
);
assert.equal(
capture.acceptMainPhase({
boundary: 'end',
durationMs: endEpochMs - startEpochMs,
epochMs: endEpochMs,
phase,
requestId,
}),
true
);
}
function accountMarker(
ipcCallId: number,
sourceEpochMs: number,
boundary: 'end' | 'start' = 'start'
): Record<string, unknown> {
return {
schemaVersion: 1,
sourceEpochMs,
ipcCallId,
method: 'xtreamRequest',
boundary,
outcome: boundary === 'start' ? null : 'success',
playlistId: null,
operationId: null,
sessionId: null,
action: XtreamCodeActions.GetAccountInfo,
categoryType: null,
contentType: null,
itemCount: null,
};
}
@@ -0,0 +1,15 @@
export function deriveXtreamAcquisitionDurationMs(
networkTotalDurationMs: number,
jsonTransformDurationMs: number
): number {
if (
!Number.isFinite(networkTotalDurationMs) ||
networkTotalDurationMs < 0 ||
!Number.isFinite(jsonTransformDurationMs) ||
jsonTransformDurationMs < 0 ||
jsonTransformDurationMs > networkTotalDurationMs
) {
throw new Error('xtream-acquisition-duration-invalid');
}
return networkTotalDurationMs - jsonTransformDurationMs;
}
@@ -0,0 +1,55 @@
import { join } from 'node:path';
import {
serializeXtreamArtifactForPersistence,
type XtreamDiagnosticArtifactEvidence,
} from './xtream-diagnostic-artifacts';
import { writeXtreamExclusiveArtifact } from './xtream-exclusive-artifact-writer';
import { persistThenValidateXtreamIteration } from './xtream-benchmark-report';
import { XTREAM_SYNTHETIC_CREDENTIALS } from './xtream-scenario-driver';
import type {
XtreamArtifactSafetyContext,
XtreamRawIterationResult,
XtreamValidatedIterationResult,
} from './xtream-summary-contract';
export interface PersistedXtreamIteration {
readonly diagnosticEvidence: XtreamDiagnosticArtifactEvidence | null;
readonly iteration: XtreamValidatedIterationResult;
}
export function createXtreamArtifactSafetyContext(
controlToken: string
): XtreamArtifactSafetyContext {
return Object.freeze({
controlToken,
syntheticCredentials: XTREAM_SYNTHETIC_CREDENTIALS,
});
}
export async function writeXtreamSafeJson(
absolutePath: string,
value: unknown,
safety: XtreamArtifactSafetyContext
): Promise<void> {
const serialized = serializeXtreamArtifactForPersistence(value, safety);
await writeXtreamExclusiveArtifact(absolutePath, serialized);
}
export async function persistXtreamIteration(
iterationDirectory: string,
raw: XtreamRawIterationResult,
diagnosticEvidence: XtreamDiagnosticArtifactEvidence | null,
safety: XtreamArtifactSafetyContext
): Promise<PersistedXtreamIteration> {
const iteration = await persistThenValidateXtreamIteration(
raw,
safety,
(serialized) =>
writeXtreamExclusiveArtifact(
join(iterationDirectory, 'result.json'),
serialized
)
);
return Object.freeze({ diagnosticEvidence, iteration });
}
@@ -0,0 +1,387 @@
import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
import { mkdir, mkdtemp, rm, stat } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
import { afterEach, describe, it } from 'node:test';
import { workspaceRoot } from '../electron-test-fixtures';
import { createXtreamIterationDefinitions } from './xtream-benchmark-contract';
import { BUILD_IDENTITY } from './xtream-benchmark-report.fixtures';
import {
type XtreamBenchmarkConfiguration,
assertXtreamBenchmarkBuildUnchanged,
assertXtreamBenchmarkOutputPathHasNoSymlinks,
createXtreamBenchmarkManifest,
resolveXtreamBenchmarkCdpPort,
resolveXtreamBenchmarkConfiguration,
resolveXtreamBenchmarkOutputLayout,
XTREAM_BENCHMARK_MOCK_ORIGIN,
} from './xtream-benchmark-configuration';
import { XTREAM_MEMORY_ACCOUNTING } from './xtream-summary-contract';
const SOURCE = Object.freeze({
gitCommit: '0123456789abcdef0123456789abcdef01234567',
gitDiffSha256:
'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd',
gitDirty: false,
});
const FIXTURE = Object.freeze({
bytes: 12_345,
catalogSha256:
'1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
counts: {
categories: { live: 60, vod: 20, series: 20, total: 100 },
items: {
live: 60_000,
vod: 20_000,
series: 20_000,
total: 100_000,
},
},
epoch: 1,
scenario: 'performance-100k',
seed: 91_001,
} as const);
const temporaryDirectories: string[] = [];
afterEach(async () => {
await Promise.all(
temporaryDirectories
.splice(0)
.map((directory) => rm(directory, { force: true, recursive: true }))
);
});
describe('Xtream benchmark output configuration', () => {
it('accepts only a fresh timestamp directory directly below dist/performance', async () => {
const repositoryRoot = await createRepositoryRoot();
const performanceRoot = join(repositoryRoot, 'dist', 'performance');
const outputRoot = join(
performanceRoot,
'20260728T123456Z-xtream-smoke'
);
assert.deepEqual(
resolveXtreamBenchmarkOutputLayout(
repositoryRoot,
outputRoot,
'baseline'
),
{
outputDirectory: join(outputRoot, 'baseline'),
outputRoot,
performanceRoot,
}
);
for (const requestedRoot of [
'dist/performance/20260728T123456Z',
performanceRoot,
join(performanceRoot, 'nested', '20260728T123456Z'),
join(performanceRoot, 'not-a-timestamp'),
join(repositoryRoot, 'outside', '20260728T123456Z'),
]) {
assert.throws(
() =>
resolveXtreamBenchmarkOutputLayout(
repositoryRoot,
requestedRoot,
'baseline'
),
/absolute fresh timestamp path below dist\/performance/
);
}
assert.throws(
() =>
resolveXtreamBenchmarkOutputLayout(
repositoryRoot,
outputRoot,
'../after'
),
/safe Xtream variant/
);
});
it('rejects every existing symbolic-link component', async () => {
const repositoryRoot = await createRepositoryRoot();
const realDist = join(repositoryRoot, 'real-dist');
await mkdir(realDist);
await import('node:fs/promises').then(({ symlink }) =>
symlink(realDist, join(repositoryRoot, 'dist'))
);
await assert.rejects(
() =>
assertXtreamBenchmarkOutputPathHasNoSymlinks(
repositoryRoot,
join(
repositoryRoot,
'dist',
'performance',
'20260728T123456Z'
)
),
/contains a symbolic link/
);
});
});
describe('Xtream benchmark mode configuration', () => {
it('pins formal CDP to 9222 and bounds smoke-only alternate ports', () => {
assert.equal(resolveXtreamBenchmarkCdpPort('formal', undefined), 9222);
assert.equal(resolveXtreamBenchmarkCdpPort('smoke', '9322'), 9322);
assert.throws(
() => resolveXtreamBenchmarkCdpPort('formal', '9322'),
/Formal Xtream performance runs require CDP port 9222/
);
for (const requested of ['1023', '65536', '9322.5', '0x246a']) {
assert.throws(
() => resolveXtreamBenchmarkCdpPort('smoke', requested),
/IPTVNATOR_PERF_CDP_PORT is invalid/
);
}
});
it('creates output only after preflight and uses exclusive child mkdir calls', async () => {
const repositoryRoot = await createRepositoryRoot();
const performanceRoot = join(repositoryRoot, 'dist', 'performance');
await mkdir(performanceRoot, { recursive: true });
const outputRoot = join(
performanceRoot,
'20260728T123456Z-xtream-smoke'
);
const calls: string[] = [];
const configuration = await resolveXtreamBenchmarkConfiguration({
dependencies: {
assertCapacity: async () => {
calls.push('preflight');
return {
availableBytes: BigInt(3 * 1_024 ** 3),
checkedPath: performanceRoot,
minimumBytes: BigInt(2 * 1_024 ** 3),
};
},
captureBuildIdentity: async () => BUILD_IDENTITY,
mkdir: async (path, options) => {
calls.push(
`mkdir:${path}:${String(
options?.recursive ?? false
)}:${String(options?.mode ?? 'default')}`
);
await mkdir(path, options);
},
readElectronVersion: async () => '41.0.0',
readGitSourceState: () => SOURCE,
},
environment: {
IPTVNATOR_PERF_CDP_PORT: '9322',
IPTVNATOR_PERF_OUTPUT_DIR: outputRoot,
IPTVNATOR_PERF_SMOKE: '1',
IPTVNATOR_PERF_VARIANT: 'smoke',
IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN: 'a'.repeat(64),
},
workspaceRoot: repositoryRoot,
});
assert.equal(calls[0], 'preflight');
assert.deepEqual(calls.slice(1), [
`mkdir:${performanceRoot}:true:${0o700}`,
`mkdir:${outputRoot}:false:${0o700}`,
`mkdir:${join(outputRoot, 'smoke')}:false:${0o700}`,
]);
assert.equal((await stat(outputRoot)).mode & 0o777, 0o700);
assert.equal(
(await stat(join(outputRoot, 'smoke'))).mode & 0o777,
0o700
);
assert.equal(configuration.mode, 'smoke');
assert.equal(configuration.measuredRuns, 1);
assert.equal(configuration.outputDirectory, join(outputRoot, 'smoke'));
assert.equal(configuration.mockOrigin, XTREAM_BENCHMARK_MOCK_ORIGIN);
assert.equal(
createXtreamIterationDefinitions(configuration.smoke)
.filter((entry) => entry.kind === 'measured')
.every((entry) => !entry.eligibleForComparison),
true
);
});
it('fails formal resolution before preflight when tracked source is dirty', async () => {
const repositoryRoot = await createRepositoryRoot();
let preflightCalled = false;
await assert.rejects(
() =>
resolveXtreamBenchmarkConfiguration({
dependencies: {
assertCapacity: async () => {
preflightCalled = true;
throw new Error('unexpected preflight');
},
captureBuildIdentity: async () => BUILD_IDENTITY,
readElectronVersion: async () => '41.0.0',
readGitSourceState: () => ({
...SOURCE,
gitDirty: true,
}),
},
environment: {
IPTVNATOR_PERF_OUTPUT_DIR: join(
repositoryRoot,
'dist',
'performance',
'20260728T123456Z-xtream'
),
IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN: 'b'.repeat(64),
},
workspaceRoot: repositoryRoot,
}),
/Formal Xtream performance runs require a clean Git worktree/
);
assert.equal(preflightCalled, false);
});
});
describe('Xtream benchmark manifest provenance', () => {
it('creates an exact manifest from the canonical prepared mock fixture only', () => {
const configuration = configurationFixture();
const manifest = createXtreamBenchmarkManifest(configuration, FIXTURE);
assert.equal(manifest.fixture.categories, 100);
assert.equal(manifest.fixture.items, 100_000);
assert.deepEqual(manifest.build, BUILD_IDENTITY);
assert.deepEqual(manifest.source, SOURCE);
assert.deepEqual(manifest.memoryAccounting, XTREAM_MEMORY_ACCOUNTING);
assert.equal(
JSON.stringify(manifest).includes(configuration.controlToken),
false
);
assert.throws(
() =>
createXtreamBenchmarkManifest(configuration, {
...FIXTURE,
scenario: 'large',
}),
/invalid Xtream performance fixture/
);
});
it('recaptures and requires byte-identical build identity at suite end', async () => {
const configuration = configurationFixture();
await assert.doesNotReject(() =>
assertXtreamBenchmarkBuildUnchanged(configuration, async () =>
structuredClone(BUILD_IDENTITY)
)
);
await assert.rejects(
() =>
assertXtreamBenchmarkBuildUnchanged(
configuration,
async () => ({
...BUILD_IDENTITY,
renderer: {
...BUILD_IDENTITY.renderer,
aggregateSha256: 'f'.repeat(64),
},
})
),
/Xtream performance build changed during the suite/
);
});
});
describe('Xtream Playwright and Nx plumbing', () => {
it('uses one isolated control-enabled mock and one no-retry 30-minute test', async () => {
const configPath = join(
workspaceRoot,
'apps/electron-backend-e2e/playwright.xtream-performance.config.ts'
);
const source = await readFile(configPath, 'utf8');
assert.match(source, /randomBytes\(32\)/);
assert.match(
source,
/process\.env\['IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN'\]\s*\?\?/
);
assert.match(source, /http:\/\/127\.0\.0\.1:3221\/health/);
assert.match(source, /reuseExistingServer:\s*false/);
assert.match(source, /IPTVNATOR_XTREAM_MOCK_CONTROL:\s*'1'/);
assert.match(
source,
/IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN:\s*controlToken/
);
assert.match(source, /HOST:\s*'127\.0\.0\.1'/);
assert.match(source, /PORT:\s*'3221'/);
assert.match(source, /retries:\s*0/);
assert.match(source, /workers:\s*1/);
assert.match(source, /timeout:\s*30\s*\*\s*60\s*\*\s*1_000/);
});
it('pins the Nx target and keeps the entrypoint to one orchestrator call', async () => {
const [project, entrypoint] = await Promise.all([
readFile(
join(workspaceRoot, 'apps/electron-backend-e2e/project.json'),
'utf8'
).then(
(value) =>
JSON.parse(value) as {
targets: Record<string, Record<string, unknown>>;
}
),
readFile(
join(
workspaceRoot,
'apps/electron-backend-e2e/src/xtream.performance.ts'
),
'utf8'
),
]);
const target = project.targets['benchmark-xtream'];
assert.deepEqual(target?.['dependsOn'], [
'electron-backend:build-performance',
]);
assert.equal(target?.['cache'], false);
assert.equal(target?.['parallelism'], false);
assert.equal(
(target?.['options'] as Record<string, unknown>)?.['command'],
'pnpm exec playwright test --config=playwright.xtream-performance.config.ts src/xtream.performance.ts'
);
assert.equal(
(entrypoint.match(/runXtreamBenchmark\(\)/g) ?? []).length,
1
);
assert.equal((entrypoint.match(/\btest\(/g) ?? []).length, 1);
});
});
async function createRepositoryRoot(): Promise<string> {
const directory = await mkdtemp(join(tmpdir(), 'iptvnator-xtream-config-'));
temporaryDirectories.push(directory);
return directory;
}
function configurationFixture(): XtreamBenchmarkConfiguration {
return {
build: BUILD_IDENTITY,
cdpPort: 9222,
controlToken: 'c'.repeat(64),
electronVersion: '41.0.0',
measuredRuns: 5,
mockOrigin: XTREAM_BENCHMARK_MOCK_ORIGIN,
mode: 'formal' as const,
outputDirectory: resolve('/tmp/xtream/baseline'),
outputRoot: resolve('/tmp/xtream'),
runtime: {
arch: 'arm64',
electronVersion: '41.0.0',
harnessNodeVersion: '22.0.0',
platform: 'darwin',
},
smoke: false,
source: SOURCE,
variant: 'baseline',
workspaceRoot: resolve('/repository'),
};
}
@@ -0,0 +1,278 @@
import { execFileSync } from 'node:child_process';
import { createHash } from 'node:crypto';
import { isDeepStrictEqual } from 'node:util';
import { mkdir, readFile } from 'node:fs/promises';
import { join, resolve } from 'node:path';
import { workspaceRoot as defaultWorkspaceRoot } from '../electron-test-fixtures';
import type {
XtreamBenchmarkManifest,
XtreamBenchmarkRuntime,
XtreamBenchmarkSource,
XtreamPerformanceManifest,
} from './xtream-benchmark-contract';
import { parseXtreamBenchmarkManifest } from './xtream-benchmark-manifest-schema';
import {
captureXtreamBuildIdentity,
type XtreamBenchmarkBuildIdentity,
} from './xtream-build-identity';
import { parseXtreamBenchmarkBuildIdentity } from './xtream-build-identity-schema';
import { parseXtreamManifest } from './xtream-control-state-schema';
import {
assertXtreamBenchmarkOutputPathHasNoSymlinks,
createExclusiveXtreamBenchmarkOutputLayout,
resolveXtreamBenchmarkCdpPort,
resolveXtreamBenchmarkOutputLayout,
type XtreamMkdir,
} from './xtream-benchmark-output-configuration';
import {
assertPerformanceArtifactCapacity,
type PerformanceArtifactCapacity,
} from './performance-artifact-preflight';
import { XTREAM_MEMORY_ACCOUNTING } from './xtream-summary-contract';
export const XTREAM_BENCHMARK_MOCK_ORIGIN = 'http://127.0.0.1:3221';
const CONTROL_TOKEN = /^[A-Za-z0-9_-]{43,128}$/u;
export {
assertXtreamBenchmarkOutputPathHasNoSymlinks,
resolveXtreamBenchmarkCdpPort,
resolveXtreamBenchmarkOutputLayout,
XTREAM_BENCHMARK_FORMAL_CDP_PORT,
} from './xtream-benchmark-output-configuration';
export interface XtreamBenchmarkConfiguration {
readonly build: XtreamBenchmarkBuildIdentity;
readonly cdpPort: number;
/** Control-plane secret. Never serialize or log this field. */
readonly controlToken: string;
readonly electronVersion: string;
readonly measuredRuns: 1 | 5;
readonly mockOrigin: typeof XTREAM_BENCHMARK_MOCK_ORIGIN;
readonly mode: 'formal' | 'smoke';
readonly outputDirectory: string;
readonly outputRoot: string;
readonly runtime: XtreamBenchmarkRuntime;
readonly smoke: boolean;
readonly source: XtreamBenchmarkSource;
readonly variant: string;
readonly workspaceRoot: string;
}
type XtreamGitSourceState = XtreamBenchmarkSource;
interface XtreamConfigurationDependencies {
readonly assertCapacity?: (
targetPath: string
) => Promise<PerformanceArtifactCapacity>;
readonly captureBuildIdentity?: (
workspaceRoot: string
) => Promise<XtreamBenchmarkBuildIdentity>;
readonly mkdir?: XtreamMkdir;
readonly readElectronVersion?: (workspaceRoot: string) => Promise<string>;
readonly readGitSourceState?: (
workspaceRoot: string
) => XtreamGitSourceState;
}
export interface ResolveXtreamBenchmarkConfigurationOptions {
readonly dependencies?: XtreamConfigurationDependencies;
readonly environment?: NodeJS.ProcessEnv;
readonly workspaceRoot?: string;
}
export async function resolveXtreamBenchmarkConfiguration(
options: ResolveXtreamBenchmarkConfigurationOptions = {}
): Promise<XtreamBenchmarkConfiguration> {
const environment = options.environment ?? process.env;
const repositoryRoot = resolve(
options.workspaceRoot ?? defaultWorkspaceRoot
);
const requestedRoot = environment['IPTVNATOR_PERF_OUTPUT_DIR'];
if (!requestedRoot) {
throw new Error('IPTVNATOR_PERF_OUTPUT_DIR is required');
}
const smoke = resolveSmokeMode(environment['IPTVNATOR_PERF_SMOKE']);
const mode = smoke ? 'smoke' : 'formal';
const variant = environment['IPTVNATOR_PERF_VARIANT'] ?? 'baseline';
const layout = resolveXtreamBenchmarkOutputLayout(
repositoryRoot,
requestedRoot,
variant
);
const cdpPort = resolveXtreamBenchmarkCdpPort(
mode,
environment['IPTVNATOR_PERF_CDP_PORT']
);
const controlToken =
environment['IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN'] ?? '';
if (!CONTROL_TOKEN.test(controlToken)) {
throw new Error(
'Xtream benchmark requires a high-entropy mock control token'
);
}
const dependencies = options.dependencies ?? {};
const readSource = dependencies.readGitSourceState ?? readGitSourceState;
const source = Object.freeze(readSource(repositoryRoot));
assertSourceState(mode, source);
const captureBuild =
dependencies.captureBuildIdentity ?? captureXtreamBuildIdentity;
const build = parseXtreamBenchmarkBuildIdentity(
await captureBuild(repositoryRoot)
);
const electronVersion = await (
dependencies.readElectronVersion ?? readElectronRuntimeVersion
)(repositoryRoot);
if (!electronVersion.trim()) {
throw new Error('Unable to resolve the Electron runtime version');
}
await assertXtreamBenchmarkOutputPathHasNoSymlinks(
repositoryRoot,
layout.outputRoot
);
await (dependencies.assertCapacity ?? assertPerformanceArtifactCapacity)(
layout.outputDirectory
);
await createExclusiveXtreamBenchmarkOutputLayout(
repositoryRoot,
layout,
dependencies.mkdir ?? mkdir
);
const runtime = Object.freeze({
arch: process.arch,
electronVersion,
harnessNodeVersion: process.versions.node,
platform: process.platform,
});
return Object.freeze({
build,
cdpPort,
controlToken,
electronVersion,
measuredRuns: smoke ? 1 : 5,
mockOrigin: XTREAM_BENCHMARK_MOCK_ORIGIN,
mode,
outputDirectory: layout.outputDirectory,
outputRoot: layout.outputRoot,
runtime,
smoke,
source,
variant,
workspaceRoot: repositoryRoot,
});
}
export function createXtreamBenchmarkManifest(
configuration: XtreamBenchmarkConfiguration,
preparedFixture: unknown
): XtreamBenchmarkManifest {
let fixture: XtreamPerformanceManifest;
try {
fixture = parseXtreamManifest(preparedFixture);
} catch {
throw new Error('invalid Xtream performance fixture');
}
return parseXtreamBenchmarkManifest({
build: configuration.build,
environment: {
cdpAddress: '127.0.0.1',
cdpPort: configuration.cdpPort,
databaseWorkerBatchDelayMs: 0,
exposeGc: true,
freshUserDataPerIteration: true,
perfCapture: '1',
perfWorkerProfiling: '1',
traceRendererConsole: '0',
},
fixture: {
bytes: fixture.bytes,
catalogSha256: fixture.catalogSha256,
categories: fixture.counts.categories.total,
items: fixture.counts.items.total,
scenario: fixture.scenario,
seed: fixture.seed,
},
memoryAccounting: XTREAM_MEMORY_ACCOUNTING,
mode: configuration.mode,
runtime: configuration.runtime,
source: configuration.source,
suite: 'xtream-performance-100k',
variant: configuration.variant,
});
}
export async function assertXtreamBenchmarkBuildUnchanged(
configuration: XtreamBenchmarkConfiguration,
capture: (
workspaceRoot: string
) => Promise<XtreamBenchmarkBuildIdentity> = captureXtreamBuildIdentity
): Promise<void> {
let current: XtreamBenchmarkBuildIdentity;
try {
current = parseXtreamBenchmarkBuildIdentity(
await capture(configuration.workspaceRoot)
);
} catch {
throw new Error('Xtream performance build changed during the suite');
}
if (!isDeepStrictEqual(configuration.build, current)) {
throw new Error('Xtream performance build changed during the suite');
}
}
function resolveSmokeMode(value: string | undefined): boolean {
if (value === undefined) return false;
if (value === '1') return true;
throw new Error('IPTVNATOR_PERF_SMOKE is invalid');
}
function assertSourceState(
mode: 'formal' | 'smoke',
source: XtreamGitSourceState
): void {
if (mode === 'formal' && source.gitDirty) {
throw new Error(
'Formal Xtream performance runs require a clean Git worktree'
);
}
}
function readGitSourceState(repositoryRoot: string): XtreamGitSourceState {
const git = (arguments_: readonly string[]): string =>
execFileSync('git', [...arguments_], {
cwd: repositoryRoot,
encoding: 'utf8',
});
const gitCommit = git(['rev-parse', 'HEAD']).trim();
const status = git(['status', '--porcelain=v1', '--untracked-files=all']);
const gitDiffSha256 = createHash('sha256')
.update(status)
.update('\0')
.update(git(['diff', '--binary', 'HEAD']))
.update('\0')
.update(git(['diff', '--binary', '--cached', 'HEAD']))
.digest('hex');
return Object.freeze({
gitCommit,
gitDiffSha256,
gitDirty: status.trim().length > 0,
});
}
async function readElectronRuntimeVersion(
repositoryRoot: string
): Promise<string> {
const value = JSON.parse(
await readFile(
join(repositoryRoot, 'node_modules', 'electron', 'package.json'),
'utf8'
)
) as { version?: unknown };
if (typeof value.version !== 'string' || !value.version.trim()) {
throw new Error('Unable to resolve the Electron runtime version');
}
return value.version;
}
@@ -0,0 +1,361 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
assertXtreamArtifactRedacted,
assertXtreamControlReadyAfterObservationReset,
assertXtreamControlStateForScenario,
assertXtreamManifest,
assertXtreamManifestIdentity,
assertXtreamMockOrigin,
createXtreamIterationDefinitions,
listXtreamBenchmarkScenarios,
XTREAM_ITERATION_KIND,
XTREAM_SCENARIO_ID,
type XtreamControlState,
type XtreamPerformanceManifest,
} from './xtream-benchmark-contract';
const MANIFEST: XtreamPerformanceManifest = {
epoch: 1,
scenario: 'performance-100k',
seed: 91_001,
counts: {
categories: { live: 60, vod: 20, series: 20, total: 100 },
items: {
live: 60_000,
vod: 20_000,
series: 20_000,
total: 100_000,
},
},
bytes: 12_345_678,
catalogSha256:
'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
};
describe('Xtream benchmark contract', () => {
it('defines exactly the five requested scenarios', () => {
assert.deepEqual(
listXtreamBenchmarkScenarios().map(({ id }) => id),
[
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
XTREAM_SCENARIO_ID.REFRESH_LARGE,
XTREAM_SCENARIO_ID.DELETE_LARGE,
XTREAM_SCENARIO_ID.CANCEL_IMPORT,
XTREAM_SCENARIO_ID.BACKGROUND_UI,
]
);
});
it('schedules warm-up, five comparable measurements, and one diagnostic', () => {
const definitions = createXtreamIterationDefinitions(false);
assert.equal(definitions.length, 35);
for (const { id } of listXtreamBenchmarkScenarios()) {
const runs = definitions.filter(
(definition) => definition.scenarioId === id
);
assert.deepEqual(
runs.map(({ eligibleForComparison, kind, runId }) => ({
eligibleForComparison,
kind,
runId,
})),
[
{
eligibleForComparison: false,
kind: XTREAM_ITERATION_KIND.WARMUP,
runId: 'warmup-01',
},
...Array.from({ length: 5 }, (_, index) => ({
eligibleForComparison: true,
kind: XTREAM_ITERATION_KIND.MEASURED,
runId: `run-${String(index + 1).padStart(2, '0')}`,
})),
{
eligibleForComparison: false,
kind: XTREAM_ITERATION_KIND.DIAGNOSTIC,
runId: 'diagnostic',
},
]
);
}
});
it('keeps smoke measurements ineligible for formal comparison', () => {
const definitions = createXtreamIterationDefinitions(true);
assert.equal(definitions.length, 15);
assert.ok(
definitions.every((definition) => !definition.eligibleForComparison)
);
for (const { id } of listXtreamBenchmarkScenarios()) {
assert.deepEqual(
definitions
.filter((definition) => definition.scenarioId === id)
.map(({ kind, runId }) => ({ kind, runId })),
[
{
kind: XTREAM_ITERATION_KIND.WARMUP,
runId: 'warmup-01',
},
{
kind: XTREAM_ITERATION_KIND.MEASURED,
runId: 'run-01',
},
{
kind: XTREAM_ITERATION_KIND.DIAGNOSTIC,
runId: 'diagnostic',
},
]
);
}
});
it('accepts only an exact credential-free HTTP loopback origin', () => {
assert.doesNotThrow(() =>
assertXtreamMockOrigin('http://127.0.0.1:43123')
);
for (const unsafe of [
'https://127.0.0.1:43123',
'http://localhost:43123',
'http://127.0.0.1',
'http://127.0.0.1:43123/',
'http://user:pass@127.0.0.1:43123',
'http://127.0.0.1:43123/player_api.php',
'http://127.0.0.1:43123?token=secret',
'http://127.0.0.1:43123#fragment',
]) {
assert.throws(
() => assertXtreamMockOrigin(unsafe),
/exact Xtream HTTP loopback origin/
);
}
});
it('rejects unexpected fixture names, counts, hashes, and identity drift', () => {
assert.doesNotThrow(() => assertXtreamManifest(MANIFEST));
for (const invalid of [
{ ...MANIFEST, scenario: 'provider-data' },
{ ...MANIFEST, seed: 42 },
{
...MANIFEST,
counts: {
...MANIFEST.counts,
items: { ...MANIFEST.counts.items, total: 99_999 },
},
},
{ ...MANIFEST, catalogSha256: 'not-a-hash' },
{ ...MANIFEST, username: 'performance' },
]) {
assert.throws(
() => assertXtreamManifest(invalid),
/invalid Xtream performance manifest/
);
}
assert.doesNotThrow(() =>
assertXtreamManifestIdentity(MANIFEST, {
...MANIFEST,
epoch: 2,
})
);
assert.throws(
() =>
assertXtreamManifestIdentity(MANIFEST, {
...MANIFEST,
epoch: 2,
bytes: MANIFEST.bytes + 1,
}),
/fixture identity changed/
);
});
it('requires a clean, same-epoch pre-trigger state after observation reset', () => {
const ready = controlState([]);
assert.doesNotThrow(() =>
assertXtreamControlReadyAfterObservationReset(ready, MANIFEST)
);
for (const invalid of [
{ ...ready, epoch: 2 },
{ ...ready, rules: [{ kind: 'barrier' }] },
{ ...ready, heldCount: 1, heldIds: ['leftover'] },
controlState([['get_account_info', 'all', 1]]),
]) {
assert.throws(
() =>
assertXtreamControlReadyAfterObservationReset(
invalid,
MANIFEST
),
/invalid Xtream mock readiness/
);
}
});
it('allows category requests to arrive in any parallel order', () => {
assert.doesNotThrow(() =>
assertXtreamControlStateForScenario(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
controlState(
[
['get_account_info', 'all', 1],
['get_series_categories', 'all', 2],
['get_vod_categories', 'all', 3],
['get_live_categories', 'all', 4],
['get_live_streams', 'all', 5],
['get_vod_streams', 'all', 6],
['get_series', 'all', 7],
],
2
),
MANIFEST
)
);
});
it('fails closed on action drift, proxy traffic, residue, and ordering drift', () => {
const cases: XtreamControlState[] = [
controlState(fullActions().slice(0, -1), 2),
controlState([...fullActions(), ['get_vod_info', 'all', 8]], 2),
{
...controlState(fullActions(), 2),
occurrences: controlState(fullActions(), 2).occurrences.map(
(entry, index) =>
index === 0 ? { ...entry, transport: 'proxy' } : entry
),
},
{
...controlState(fullActions(), 2),
rules: [{ kind: 'delay' }],
},
{
...controlState(fullActions(), 2),
heldCount: 1,
heldIds: ['leftover'],
},
controlState(
[
['get_account_info', 'all', 1],
['get_live_streams', 'all', 2],
['get_live_categories', 'all', 3],
['get_vod_categories', 'all', 4],
['get_series_categories', 'all', 5],
['get_vod_streams', 'all', 6],
['get_series', 'all', 7],
],
2
),
];
for (const invalid of cases) {
assert.throws(
() =>
assertXtreamControlStateForScenario(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
invalid,
MANIFEST
),
/invalid Xtream mock observations/
);
}
});
it('rejects credential keys and secret values from persisted artifacts', () => {
assert.doesNotThrow(() =>
assertXtreamArtifactRedacted({
fixture: {
bytes: MANIFEST.bytes,
catalogSha256: MANIFEST.catalogSha256,
},
})
);
for (const unsafe of [
{ username: 'performance' },
{ nested: { password: 'performance' } },
{ serverUrl: 'http://127.0.0.1:43123' },
{ note: 'leaked benchmark-control-token' },
]) {
assert.throws(
() =>
assertXtreamArtifactRedacted(unsafe, [
'benchmark-control-token',
]),
/credential-safe/
);
}
});
});
type Action = readonly [string, string, number];
function fullActions(): readonly Action[] {
return [
['get_account_info', 'all', 1],
['get_live_categories', 'all', 2],
['get_vod_categories', 'all', 3],
['get_series_categories', 'all', 4],
['get_live_streams', 'all', 5],
['get_vod_streams', 'all', 6],
['get_series', 'all', 7],
];
}
function controlState(
actions: readonly Action[],
accountCount = 1
): XtreamControlState {
return {
epoch: MANIFEST.epoch,
prepared: MANIFEST,
rules: [],
heldIds: [],
heldCount: 0,
occurrences: actions.map(([action, categoryId]) => ({
scenario: 'performance-100k',
transport: 'direct',
action,
categoryId,
count: action === 'get_account_info' ? accountCount : 1,
})),
ledger: actions.flatMap(([action, categoryId, order]) =>
Array.from(
{
length: action === 'get_account_info' ? accountCount : 1,
},
(_, index) => {
const shiftedOrder =
order +
index +
(action === 'get_account_info' ? 0 : accountCount - 1);
return [
{
epoch: MANIFEST.epoch,
scenario: 'performance-100k',
transport: 'direct' as const,
action,
categoryId,
occurrence: index + 1,
status: 'arrived' as const,
atMs: shiftedOrder * 10,
},
{
epoch: MANIFEST.epoch,
scenario: 'performance-100k',
transport: 'direct' as const,
action,
categoryId,
occurrence: index + 1,
status: 'responded' as const,
atMs: shiftedOrder * 10 + 1,
},
];
}
).flat()
),
};
}
@@ -0,0 +1,399 @@
import type { XTREAM_MEMORY_ACCOUNTING } from './xtream-summary-contract';
import type { XtreamBenchmarkBuildIdentity } from './xtream-build-identity';
export const XTREAM_SCENARIO_ID = {
INITIAL_IMPORT_LARGE: 'xtream-initial-import-large',
REFRESH_LARGE: 'xtream-refresh-large',
DELETE_LARGE: 'xtream-delete-large',
CANCEL_IMPORT: 'xtream-cancel-import',
BACKGROUND_UI: 'xtream-background-ui',
} as const;
export type XtreamScenarioId =
(typeof XTREAM_SCENARIO_ID)[keyof typeof XTREAM_SCENARIO_ID];
export const XTREAM_ITERATION_KIND = {
DIAGNOSTIC: 'diagnostic',
MEASURED: 'measured',
WARMUP: 'warmup',
} as const;
export type XtreamIterationKind =
(typeof XTREAM_ITERATION_KIND)[keyof typeof XTREAM_ITERATION_KIND];
export interface XtreamScenario {
readonly id: XtreamScenarioId;
}
export interface XtreamWorkerRequestInventoryEntry {
readonly count: number;
readonly operation: string;
readonly phases: readonly string[];
readonly success: boolean;
}
export interface XtreamIterationDefinition {
readonly eligibleForComparison: boolean;
readonly kind: XtreamIterationKind;
readonly runId: string;
readonly scenarioId: XtreamScenarioId;
}
export interface XtreamPerformanceManifest {
readonly bytes: number;
readonly catalogSha256: string;
readonly counts: {
readonly categories: XtreamCatalogCounts;
readonly items: XtreamCatalogCounts;
};
readonly epoch: number;
readonly scenario: 'performance-100k';
readonly seed: 91_001;
}
export interface XtreamCatalogCounts {
readonly live: number;
readonly series: number;
readonly total: number;
readonly vod: number;
}
export interface XtreamOccurrence {
readonly action: string;
readonly categoryId: string;
readonly count: number;
readonly scenario: string;
readonly transport: string;
}
export interface XtreamLedgerEntry {
readonly action: string;
readonly atMs: number;
readonly categoryId: string;
readonly epoch: number;
readonly occurrence: number;
readonly scenario: string;
readonly status: string;
readonly transport: string;
}
export interface XtreamControlState {
readonly epoch: number;
readonly heldCount: number;
readonly heldIds: readonly string[];
readonly ledger: readonly XtreamLedgerEntry[];
readonly occurrences: readonly XtreamOccurrence[];
readonly prepared: XtreamPerformanceManifest | null;
readonly rules: readonly unknown[];
}
export interface XtreamBenchmarkManifest {
readonly build: XtreamBenchmarkBuildIdentity;
readonly environment: XtreamBenchmarkEnvironment;
readonly fixture: XtreamBenchmarkFixture;
readonly memoryAccounting: typeof XTREAM_MEMORY_ACCOUNTING;
readonly mode: 'formal' | 'smoke';
readonly runtime: XtreamBenchmarkRuntime;
readonly source: XtreamBenchmarkSource;
readonly suite: 'xtream-performance-100k';
readonly variant: string;
}
export interface XtreamBenchmarkEnvironment {
readonly cdpAddress: '127.0.0.1';
readonly cdpPort: number;
readonly databaseWorkerBatchDelayMs: 0;
readonly exposeGc: true;
readonly freshUserDataPerIteration: true;
readonly perfCapture: '1';
readonly perfWorkerProfiling: '1';
readonly traceRendererConsole: '0';
}
export interface XtreamBenchmarkFixture {
readonly bytes: number;
readonly catalogSha256: string;
readonly categories: 100;
readonly items: 100_000;
readonly scenario: 'performance-100k';
readonly seed: 91_001;
}
export interface XtreamBenchmarkRuntime {
readonly arch: string;
readonly electronVersion: string;
readonly harnessNodeVersion: string;
readonly platform: string;
}
export interface XtreamBenchmarkSource {
readonly gitCommit: string;
readonly gitDiffSha256: string;
readonly gitDirty: boolean;
}
export interface NumericDistribution {
readonly count: number;
readonly max: number | null;
readonly mean: number | null;
readonly median: number | null;
readonly min: number | null;
readonly p95: number | null;
readonly p99: number | null;
}
export function summarizeXtreamNumbers(
values: readonly number[]
): NumericDistribution {
const samples = [...values].sort((left, right) => left - right);
const total = samples.reduce((sum, value) => sum + value, 0);
const percentile = (rank: number): number => {
if (samples.length === 1) return samples[0] ?? 0;
const position = ((samples.length - 1) * rank) / 100;
const lowerIndex = Math.floor(position);
const upperIndex = Math.ceil(position);
const lower = samples[lowerIndex] ?? 0;
const upper = samples[upperIndex] ?? lower;
return lower + (upper - lower) * (position - lowerIndex);
};
return {
count: samples.length,
max: samples.at(-1) ?? null,
mean: total / samples.length,
median: percentile(50),
min: samples[0] ?? null,
p95: percentile(95),
p99: percentile(99),
};
}
export interface XtreamScenarioMetrics {
readonly angularRenderingMs: NumericDistribution;
readonly cancelAcknowledgementLatencyMs: NumericDistribution | null;
readonly dataAcquisitionMs: NumericDistribution;
readonly deserializationMs: NumericDistribution;
readonly databaseWorkerCpuSystemMicros: NumericDistribution;
readonly databaseWorkerCpuUserMicros: NumericDistribution;
readonly databaseWorkerEventLoopDelayMaxMs: NumericDistribution;
readonly databaseWorkerEventLoopDelayP95Ms: NumericDistribution;
readonly databaseWorkerEventLoopDelayP99Ms: NumericDistribution;
readonly databaseWorkerEventLoopUtilization: NumericDistribution;
readonly databaseWorkerPeakExternalBytes: NumericDistribution;
readonly databaseWorkerPeakHeapBytes: NumericDistribution;
readonly databaseWorkerPostGcHeapBytes: NumericDistribution;
readonly databaseWorkerRequestInvalidSampleCount: NumericDistribution;
readonly databaseWorkerRequestEventLoopDelayMaxMs: NumericDistribution;
readonly databaseWorkerRequestEventLoopDelayP95Ms: NumericDistribution;
readonly databaseWorkerRequestEventLoopDelayP99Ms: NumericDistribution;
readonly databaseWorkerRequestEventLoopUtilization: NumericDistribution;
readonly databaseWorkerRequestTotalCount: NumericDistribution;
readonly databaseWorkerRequestValidSampleCount: NumericDistribution;
readonly jsonParsingMs: NumericDistribution;
readonly mainCpuSystemMicros: NumericDistribution;
readonly mainCpuUserMicros: NumericDistribution;
readonly mainEventLoopDelayMaxMs: NumericDistribution;
readonly mainEventLoopDelayP95Ms: NumericDistribution;
readonly mainEventLoopDelayP99Ms: NumericDistribution;
readonly mainPeakHeapBytes: NumericDistribution;
readonly mainPeakRssBytes: NumericDistribution;
readonly mainPostGcHeapBytes: NumericDistribution;
readonly normalizationMs: NumericDistribution;
readonly rendererActionLatencyMs: NumericDistribution | null;
readonly rendererFrameGapMaxMs: NumericDistribution;
readonly rendererFrameGapP95Ms: NumericDistribution;
readonly rendererHeartbeatMaxMs: NumericDistribution;
readonly rendererHeartbeatP95Ms: NumericDistribution;
readonly rendererLongTaskCount: NumericDistribution;
readonly rendererLongTaskMaxMs: NumericDistribution;
readonly rendererNavigationLatencyMs: NumericDistribution | null;
readonly rendererPeakHeapBytes: NumericDistribution;
readonly rendererPeakRssBytes: NumericDistribution;
readonly rendererPostGcHeapBytes: NumericDistribution;
readonly rendererSearchLatencyMs: NumericDistribution | null;
readonly serializationMs: NumericDistribution;
readonly sqliteReadMs: NumericDistribution;
readonly sqliteWriteMs: NumericDistribution;
readonly storeUpdateMs: NumericDistribution;
readonly structuredCloneProxyMs: NumericDistribution;
readonly totalMs: NumericDistribution;
}
const SCENARIOS: readonly XtreamScenario[] = Object.freeze([
Object.freeze({ id: XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE }),
Object.freeze({ id: XTREAM_SCENARIO_ID.REFRESH_LARGE }),
Object.freeze({ id: XTREAM_SCENARIO_ID.DELETE_LARGE }),
Object.freeze({ id: XTREAM_SCENARIO_ID.CANCEL_IMPORT }),
Object.freeze({ id: XTREAM_SCENARIO_ID.BACKGROUND_UI }),
]);
export function listXtreamBenchmarkScenarios(): readonly XtreamScenario[] {
return SCENARIOS;
}
export function createXtreamIterationDefinitions(
smoke: boolean
): readonly XtreamIterationDefinition[] {
const definitions: XtreamIterationDefinition[] = [];
for (const scenario of SCENARIOS) {
definitions.push(iteration(scenario.id, 'warmup-01', 'warmup', false));
for (let index = 1; index <= (smoke ? 1 : 5); index += 1) {
definitions.push(
iteration(
scenario.id,
`run-${String(index).padStart(2, '0')}`,
'measured',
!smoke
)
);
}
definitions.push(
iteration(scenario.id, 'diagnostic', 'diagnostic', false)
);
}
return Object.freeze(definitions);
}
export function expectedXtreamWorkerRequestInventory(
scenarioId: XtreamScenarioId
): readonly XtreamWorkerRequestInventoryEntry[] {
return WORKER_REQUEST_INVENTORY[scenarioId];
}
const PHASES = Object.freeze({
categoriesRead: ['sqlite.categories.read'],
categoriesWrite: [
'normalize.categories',
'sqlite.categories.write-transactions',
],
contentRead: ['sqlite.content.read'],
contentWrite: [
'sqlite.content.category-map-read',
'normalize.content',
'sqlite.content.write-transactions',
],
playlistDelete: [
'sqlite.playlist-delete.collect-ids',
'sqlite.playlist-delete.write-transactions',
],
playlistGet: ['sqlite.read', 'deserialize.playlist'],
playlistUpsert: ['serialize.playlist', 'sqlite.write'],
xtreamCacheClear: ['sqlite.xtream-cache-clear.write-transactions'],
xtreamDelete: [
'sqlite.xtream-delete.collect-user-data',
'sqlite.xtream-delete.write-transactions',
],
});
const WORKER_REQUEST_INVENTORY: Readonly<
Record<XtreamScenarioId, readonly XtreamWorkerRequestInventoryEntry[]>
> = Object.freeze({
[XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE]: inventory(
request('DB_UPSERT_APP_PLAYLIST', 1, PHASES.playlistUpsert),
request('DB_GET_PLAYLIST', 1),
request('DB_GET_ALL_PLAYBACK_POSITIONS', 1),
...fullImportRequests()
),
[XTREAM_SCENARIO_ID.REFRESH_LARGE]: refreshRequests(),
[XTREAM_SCENARIO_ID.DELETE_LARGE]: inventory(
request('DB_DELETE_PLAYLIST', 2, PHASES.playlistDelete)
),
[XTREAM_SCENARIO_ID.CANCEL_IMPORT]: inventory(
request('DB_UPSERT_APP_PLAYLIST', 1, PHASES.playlistUpsert),
request('DB_GET_PLAYLIST', 1),
request('DB_GET_ALL_PLAYBACK_POSITIONS', 1),
request('DB_GET_APP_STATE', 4),
request('DB_GET_CATEGORIES', 6, PHASES.categoriesRead),
request('DB_SAVE_CATEGORIES', 3, PHASES.categoriesWrite),
request('DB_GET_CONTENT', 1, PHASES.contentRead),
request('DB_SAVE_CONTENT', 1, PHASES.contentWrite, false),
request('DB_SET_APP_STATE', 3),
request('DB_CLEAR_XTREAM_IMPORT_CACHE', 3, PHASES.xtreamCacheClear)
),
[XTREAM_SCENARIO_ID.BACKGROUND_UI]: inventory(
...refreshRequests(),
request('DB_GET_RECENTLY_VIEWED', 1),
request('DB_GET_ALL_GLOBAL_FAVORITES', 1),
request('DB_GET_GLOBAL_RECENTLY_ADDED', 1)
),
});
function fullImportRequests(
reads: Readonly<{
appState: number;
categories: number;
content: number;
setAppState: number;
}> = { appState: 6, categories: 6, content: 6, setAppState: 3 }
): readonly XtreamWorkerRequestInventoryEntry[] {
return inventory(
request('DB_GET_APP_STATE', reads.appState),
request('DB_GET_CATEGORIES', reads.categories, PHASES.categoriesRead),
request('DB_SAVE_CATEGORIES', 3, PHASES.categoriesWrite),
request('DB_GET_CONTENT', reads.content, PHASES.contentRead),
request('DB_SAVE_CONTENT', 3, PHASES.contentWrite),
request('DB_SET_APP_STATE', reads.setAppState)
);
}
function refreshRequests(): readonly XtreamWorkerRequestInventoryEntry[] {
return inventory(
request('DB_DELETE_XTREAM_CONTENT', 1, PHASES.xtreamDelete),
request('DB_GET_ALL_PLAYBACK_POSITIONS', 1),
request('DB_UPDATE_PLAYLIST', 1),
request('DB_GET_APP_PLAYLIST', 1, PHASES.playlistGet),
request('DB_GET_PLAYLIST', 2),
request('DB_UPSERT_APP_PLAYLIST', 1, PHASES.playlistUpsert),
...fullImportRequests({
appState: 12,
categories: 9,
content: 9,
setAppState: 6,
}),
request('DB_RESTORE_XTREAM_USER_DATA', 1),
request('DB_CLEAR_ALL_PLAYBACK_POSITIONS', 1)
);
}
function inventory(
...entries: readonly XtreamWorkerRequestInventoryEntry[]
): readonly XtreamWorkerRequestInventoryEntry[] {
return Object.freeze(entries);
}
function request(
operation: string,
count: number,
phases: readonly string[] = [],
success = true
): XtreamWorkerRequestInventoryEntry {
return Object.freeze({
count,
operation,
phases: Object.freeze([...phases]),
success,
});
}
function iteration(
scenarioId: XtreamScenarioId,
runId: string,
kind: XtreamIterationKind,
eligibleForComparison: boolean
): XtreamIterationDefinition {
return Object.freeze({
eligibleForComparison,
kind,
runId,
scenarioId,
});
}
export {
assertXtreamArtifactRedacted,
assertXtreamControlReadyAfterObservationReset,
assertXtreamControlStateForScenario,
assertXtreamManifest,
assertXtreamManifestIdentity,
assertXtreamMockOrigin,
parseXtreamControlState,
} from './xtream-control-client';
@@ -0,0 +1,62 @@
import assert from 'node:assert/strict';
import { afterEach, describe, it } from 'node:test';
import type { XtreamBenchmarkManifest } from './xtream-benchmark-contract';
import { createXtreamBenchmarkSummary } from './xtream-benchmark-report';
import {
MANIFEST,
clearXtreamReportFixtureDirectories,
} from './xtream-benchmark-report.fixtures';
import {
clearXtreamProvenanceFixtureDirectories,
smokeReportFixture,
} from './xtream-benchmark-report-provenance.fixtures';
import { assertXtreamBenchmarkManifest } from './xtream-exact-schema';
afterEach(async () => {
await Promise.all([
clearXtreamReportFixtureDirectories(),
clearXtreamProvenanceFixtureDirectories(),
]);
});
describe('Xtream benchmark CDP environment', () => {
it('allows a bounded alternate smoke port but keeps formal capture on 9222', async () => {
const smokeManifest: XtreamBenchmarkManifest = {
...MANIFEST,
environment: { ...MANIFEST.environment, cdpPort: 9322 },
mode: 'smoke',
};
assert.doesNotThrow(() => assertXtreamBenchmarkManifest(smokeManifest));
assert.throws(
() =>
assertXtreamBenchmarkManifest({
...smokeManifest,
mode: 'formal',
}),
/invalid Xtream benchmark manifest/
);
const { diagnosticEvidence, iterations } = await smokeReportFixture();
const summary = createXtreamBenchmarkSummary(
smokeManifest,
iterations,
diagnosticEvidence
);
assert.equal(summary.validForComparison, false);
});
it('requires an integer CDP port from 1024 through 65535', () => {
for (const cdpPort of [1023, 65536, 9322.5, Number.NaN]) {
assert.throws(
() =>
assertXtreamBenchmarkManifest({
...MANIFEST,
environment: { ...MANIFEST.environment, cdpPort },
mode: 'smoke',
}),
/invalid Xtream benchmark manifest/
);
}
});
});
@@ -0,0 +1,274 @@
import assert from 'node:assert/strict';
import { mkdtemp, rm, symlink, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { describe, it } from 'node:test';
import { createXtreamIterationDefinitions } from './xtream-benchmark-contract';
import { createXtreamBenchmarkSummary } from './xtream-benchmark-report';
import {
MANIFEST,
clearXtreamReportFixtureDirectories,
iteration,
persist,
persistWith,
sha256,
} from './xtream-benchmark-report.fixtures';
import { toXtreamRawIteration } from './xtream-exact-schema';
import {
clearXtreamProvenanceFixtureDirectories,
formalReportFixture,
} from './xtream-benchmark-report-provenance.fixtures';
import type {
XtreamBenchmarkManifest,
XtreamPersistenceReceipt,
} from './xtream-summary-contract';
describe('Xtream benchmark integrity boundaries', () => {
it('uses one intrinsic snapshot instead of caller-owned array methods', async () => {
const { diagnosticEvidence, iterations } = await formalReportFixture();
const adversarial = [...iterations];
const invoked: string[] = [];
for (const method of ['filter', 'find', 'map'] as const) {
Object.defineProperty(adversarial, method, {
value() {
invoked.push(method);
throw new Error(`caller-owned-${method}`);
},
});
}
Object.defineProperty(adversarial, Symbol.iterator, {
value() {
invoked.push('iterator');
throw new Error('caller-owned-iterator');
},
});
try {
assert.doesNotThrow(() =>
createXtreamBenchmarkSummary(
MANIFEST,
adversarial,
diagnosticEvidence
)
);
assert.deepEqual(invoked, []);
} finally {
await clearXtreamProvenanceFixtureDirectories();
}
});
it('cannot hide a reused process identity behind caller-owned map', async () => {
const fixture = await formalReportFixture();
const definitions = createXtreamIterationDefinitions(false);
const iterations = [...fixture.iterations];
const sourceDuplicate = iteration(required(definitions, 1), 9_999);
const duplicate = {
...sourceDuplicate,
processIdentity: {
...sourceDuplicate.processIdentity,
electronPid: required(iterations, 0).processIdentity
.electronPid,
},
};
iterations[1] = await persist(duplicate, 9_999);
Object.defineProperty(iterations, 'map', {
value() {
return Array.from(
{ length: iterations.length },
(_, index) => index
);
},
});
try {
assert.throws(
() =>
createXtreamBenchmarkSummary(
MANIFEST,
iterations,
fixture.diagnosticEvidence
),
/fresh process identity/
);
} finally {
await Promise.all([
clearXtreamReportFixtureDirectories(),
clearXtreamProvenanceFixtureDirectories(),
]);
}
});
it('uses native Map entries after validating diagnostic evidence', async () => {
const { diagnosticEvidence, iterations } = await formalReportFixture();
const entries = [...diagnosticEvidence.entries()];
const [firstIteration, firstEvidence] = required(entries, 0);
const [, secondEvidence] = required(entries, 1);
const adversarial = new Map(entries);
Object.defineProperty(adversarial, 'get', {
value(key: (typeof entries)[number][0]) {
return key === firstIteration
? secondEvidence
: Map.prototype.get.call(this, key);
},
});
try {
const summary = createXtreamBenchmarkSummary(
MANIFEST,
iterations,
adversarial
);
const scenario = summary.scenarios.find(
({ scenarioId }) => scenarioId === firstIteration.scenarioId
);
assert.equal(
scenario?.diagnosticProfiles.artifactProvenance.directorySha256,
firstEvidence.directorySha256
);
} finally {
await clearXtreamProvenanceFixtureDirectories();
}
});
it('snapshots every persistence receipt accessor exactly once', async () => {
const definition = required(createXtreamIterationDefinitions(false), 1);
const raw = iteration(definition, 1);
const directory = await mkdtemp(
join(tmpdir(), 'iptvnator-xtream-receipt-accessor-')
);
const regularPath = join(directory, 'raw.json');
const symlinkPath = join(directory, 'raw-link.json');
try {
await assert.rejects(
() =>
persistWith(raw, async (serialized) => {
await writeFile(regularPath, serialized);
await symlink(regularPath, symlinkPath);
let pathReads = 0;
return {
get absolutePath() {
pathReads += 1;
return pathReads === 1
? symlinkPath
: regularPath;
},
bytes: Buffer.byteLength(serialized),
sha256: sha256(serialized),
} as XtreamPersistenceReceipt;
}),
/persistence receipt/
);
let stablePathReads = 0;
await persistWith(raw, async (serialized) => ({
get absolutePath() {
stablePathReads += 1;
return regularPath;
},
bytes: Buffer.byteLength(serialized),
sha256: sha256(serialized),
}));
assert.equal(stablePathReads, 1);
} finally {
await rm(directory, { force: true, recursive: true });
}
});
it('uses one canonical manifest snapshot for validation and output', async () => {
const { diagnosticEvidence, iterations } = await formalReportFixture();
let variantReads = 0;
const manifest = {
...MANIFEST,
get variant() {
variantReads += 1;
return variantReads <= 3 ? 'baseline' : 'CON.json';
},
} as XtreamBenchmarkManifest;
try {
const summary = createXtreamBenchmarkSummary(
manifest,
iterations,
diagnosticEvidence
);
assert.equal(summary.manifest.variant, 'baseline');
assert.equal(variantReads, 1);
} finally {
await clearXtreamProvenanceFixtureDirectories();
}
});
it('binds diagnostic profile durations and worker ordinal to artifact evidence', async () => {
const fixture = await formalReportFixture();
const [diagnostic, evidence] = required(
[...fixture.diagnosticEvidence.entries()],
0
);
const diagnosticIndex = fixture.iterations.indexOf(diagnostic);
assert.notEqual(diagnosticIndex, -1);
const raw = toXtreamRawIteration(diagnostic);
const mismatches = [
{
...raw,
renderer: {
...raw.renderer,
cpuProfileDurationMicros: 2_001,
},
},
{
...raw,
main: {
...raw.main,
cpuProfileDurationMicros: 2_001,
},
},
{
...raw,
databaseWorker: {
...raw.databaseWorker,
cpuProfileDurationMicros: 2_001,
},
},
{
...raw,
databaseWorker: {
...raw.databaseWorker,
ordinal: raw.databaseWorker.ordinal + 1,
},
},
];
try {
for (const [index, mismatch] of mismatches.entries()) {
const replacement = await persist(mismatch, 20_000 + index);
const iterations = [...fixture.iterations];
iterations[diagnosticIndex] = replacement;
const diagnosticEvidence = new Map(fixture.diagnosticEvidence);
diagnosticEvidence.delete(diagnostic);
diagnosticEvidence.set(replacement, evidence);
assert.throws(
() =>
createXtreamBenchmarkSummary(
MANIFEST,
iterations,
diagnosticEvidence
),
/diagnostic artifact evidence binding/
);
}
} finally {
await Promise.all([
clearXtreamReportFixtureDirectories(),
clearXtreamProvenanceFixtureDirectories(),
]);
}
});
});
function required<T>(values: readonly T[], index: number): T {
const value = values[index];
assert.ok(value);
return value;
}
@@ -0,0 +1,262 @@
import { join } from 'node:path';
import {
ELECTRON_RUNTIME_ENVIRONMENT_KEYS,
type LaunchedElectronApp,
} from '../electron-test-fixtures';
import {
XTREAM_SCENARIO_ID,
type XtreamIterationDefinition,
type XtreamPerformanceManifest,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import { writeXtreamSafeJson } from './xtream-benchmark-artifacts';
import type { XtreamControlClient } from './xtream-control-client';
import { assertXtreamControlStateForScenario } from './xtream-control-client';
import {
validateXtreamDiagnosticArtifacts,
type XtreamDiagnosticArtifactEvidence,
} from './xtream-diagnostic-artifacts';
import {
readXtreamMainCaptureStatus,
startMainCapture,
type MainCaptureStartOptions,
type XtreamMainCaptureResult,
type XtreamMainCaptureStatus,
} from './m3u-refresh-main-capture';
import { isXtreamMainCaptureSettled } from './xtream-main-settlement';
import type { XtreamRendererCaptureMetrics } from './xtream-renderer-capture';
import {
assertCompleteXtreamRendererProbe,
beginXtreamRendererOperation,
stopXtreamRendererProbe,
waitForXtreamRendererTerminal,
} from './xtream-renderer-probe-control';
import { installXtreamRendererProbe } from './xtream-renderer-probe';
import { prepareXtreamScenario } from './xtream-scenario-driver';
import type { XtreamArtifactSafetyContext } from './xtream-summary-contract';
export interface SeedXtreamExistingPortalOptions {
readonly app: LaunchedElectronApp;
readonly captureOptions: MainCaptureStartOptions;
readonly control: XtreamControlClient;
readonly fixture: XtreamPerformanceManifest;
readonly iterationDirectory: string;
readonly safety: XtreamArtifactSafetyContext;
readonly serverUrl: string;
readonly sourceTitle: string;
}
export async function prearmXtreamDatabaseWorker(
app: LaunchedElectronApp
): Promise<void> {
const playlists = await app.mainWindow.evaluate(() =>
window.electron.dbGetAppPlaylists()
);
if (!Array.isArray(playlists)) {
throw new Error('xtream-database-worker-prearm-invalid');
}
}
export async function seedXtreamExistingPortal(
options: SeedXtreamExistingPortalOptions
): Promise<void> {
const seed = await prepareXtreamScenario(options.app.mainWindow, {
scenarioId: XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
serverUrl: options.serverUrl,
sourceTitle: options.sourceTitle,
});
let rendererProbeInstalled = false;
try {
await installXtreamRendererProbe(options.app.mainWindow, {
scenarioId: XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
sourceTitle: options.sourceTitle,
});
rendererProbeInstalled = true;
await startMainCapture(options.app.electronApp, {
...options.captureOptions,
deferMeasurement: false,
diagnostic: false,
});
const captureGeneration = (
await readXtreamMainCaptureStatus(options.app.electronApp)
).captureGeneration;
await beginXtreamRendererOperation(options.app.mainWindow);
await seed.trigger();
const driverTerminal = seed.waitForTerminal();
await waitForXtreamRendererTerminal(options.app.mainWindow);
const rendererProbe = await stopXtreamRendererProbe(
options.app.mainWindow
);
rendererProbeInstalled = false;
assertCompleteXtreamRendererProbe(rendererProbe);
await assertXtreamSettlementAfterTerminal({
captureGeneration,
readStatus: () =>
readXtreamMainCaptureStatus(options.app.electronApp),
scenarioId: XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
terminal: driverTerminal,
});
const state = await options.control.state();
await writeXtreamSafeJson(
join(options.iterationDirectory, 'seed-control-state.json'),
state,
options.safety
);
assertXtreamControlStateForScenario(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
state,
options.fixture
);
} finally {
await Promise.allSettled([
rendererProbeInstalled
? stopXtreamRendererProbe(options.app.mainWindow)
: Promise.resolve(),
seed.dispose(),
]);
}
}
export interface AssertXtreamSettlementAfterTerminalOptions {
readonly captureGeneration: number;
readonly readStatus: () => Promise<XtreamMainCaptureStatus>;
readonly scenarioId: XtreamScenarioId;
readonly terminal: Promise<unknown>;
}
export async function assertXtreamSettlementAfterTerminal(
options: AssertXtreamSettlementAfterTerminalOptions
): Promise<void> {
await options.terminal;
const status = await options.readStatus();
if (status.captureGeneration !== options.captureGeneration) {
throw new Error('xtream-measured-capture-generation-changed');
}
if (!isXtreamMainCaptureSettled(status, options.scenarioId)) {
throw new Error('xtream-main-not-settled-after-terminal');
}
}
export interface FinalizeXtreamCaptureAfterRendererTerminalOptions<
DriverTerminal,
MainCapture,
RendererCapture,
> extends Omit<AssertXtreamSettlementAfterTerminalOptions, 'terminal'> {
readonly driverTerminal: Promise<DriverTerminal>;
readonly rendererTerminal: Promise<unknown>;
readonly stopMain: () => Promise<MainCapture>;
readonly stopRenderer: () => Promise<RendererCapture>;
}
export interface FinalizedXtreamCapture<
DriverTerminal,
MainCapture,
RendererCapture,
> {
readonly driverTerminal: DriverTerminal;
readonly mainCapture: MainCapture;
readonly rendererCapture: RendererCapture;
}
export async function finalizeXtreamCaptureAfterRendererTerminal<
DriverTerminal,
MainCapture,
RendererCapture,
>(
options: FinalizeXtreamCaptureAfterRendererTerminalOptions<
DriverTerminal,
MainCapture,
RendererCapture
>
): Promise<
FinalizedXtreamCapture<DriverTerminal, MainCapture, RendererCapture>
> {
await assertXtreamSettlementAfterTerminal({
captureGeneration: options.captureGeneration,
readStatus: options.readStatus,
scenarioId: options.scenarioId,
terminal: options.rendererTerminal,
});
const rendererCapture = options.stopRenderer();
const mainCapture = options.stopMain();
const [resolvedRenderer, resolvedMain, driverTerminal] = await Promise.all([
rendererCapture,
mainCapture,
options.driverTerminal,
]);
return Object.freeze({
driverTerminal,
mainCapture: resolvedMain,
rendererCapture: resolvedRenderer,
});
}
export async function assertXtreamBenchmarkEnvironmentIsolated(
app: LaunchedElectronApp
): Promise<void> {
const keys = await app.electronApp.evaluate(() => Object.keys(process.env));
const allowed = new Set(
[
...ELECTRON_RUNTIME_ENVIRONMENT_KEYS,
'ELECTRON_IS_DEV',
'IPTVNATOR_ALLOW_PRIVATE_NETWORK_URLS',
'IPTVNATOR_DB_WORKER_BATCH_DELAY_MS',
'IPTVNATOR_E2E_DATA_DIR',
'IPTVNATOR_PERF_CAPTURE',
'IPTVNATOR_PERF_WORKER_PROFILING',
'IPTVNATOR_TRACE_RENDERER_CONSOLE',
'NODE_ENV',
].map((key) => key.toUpperCase())
);
if (
!Array.isArray(keys) ||
keys.some(
(key) => typeof key !== 'string' || !allowed.has(key.toUpperCase())
)
) {
throw new Error('xtream-benchmark-environment-reached-electron');
}
}
export function createXtreamSourceTitle(
definition: XtreamIterationDefinition
): string {
return `Synthetic Xtream 100k ${definition.scenarioId} ${definition.runId}`;
}
export async function createXtreamDiagnosticEvidence(
kind: XtreamIterationDefinition['kind'],
main: XtreamMainCaptureResult,
renderer: XtreamRendererCaptureMetrics,
iterationDirectory: string
): Promise<XtreamDiagnosticArtifactEvidence | null> {
if (kind !== 'diagnostic') return null;
return validateXtreamDiagnosticArtifacts(
{
main: {
cpuProfilePath: main.capture.cpuProfilePath,
heapSnapshotPath: main.capture.heapSnapshotPath,
workers: main.workers.map(
({
kind: workerKind,
ordinal,
profilePath,
snapshotPath,
}) => ({
kind: workerKind,
ordinal,
profilePath,
snapshotPath,
})
),
},
renderer: {
cpuProfilePath: renderer.cpuProfilePath,
heapSnapshotPath: renderer.heapSnapshotPath,
tracePath: renderer.tracePath,
},
},
iterationDirectory
);
}
@@ -0,0 +1,399 @@
import { mkdir, mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import {
closeElectronApp,
launchElectronApp,
type LaunchedElectronApp,
} from '../electron-test-fixtures';
import {
type XtreamIterationDefinition,
type XtreamPerformanceManifest,
XTREAM_SCENARIO_ID,
} from './xtream-benchmark-contract';
import type { XtreamBenchmarkConfiguration } from './xtream-benchmark-configuration';
import type { XtreamControlClient } from './xtream-control-client';
import {
assertXtreamControlReadyAfterObservationReset,
assertXtreamControlStateForScenario,
assertXtreamManifestIdentity,
} from './xtream-control-client';
import { createXtreamCatalogVerification } from './xtream-catalog-database-verification';
import { readXtreamCatalogDatabaseSnapshot } from './xtream-catalog-database-reader';
import { assembleXtreamRawIteration } from './xtream-iteration-assembler';
import {
beginXtreamMainMeasurement,
installMainCapture,
readXtreamMainCaptureStatus,
rolloverXtreamMainCapture,
startMainCapture,
stopXtreamMainCapture,
type MainCaptureStartOptions,
} from './m3u-refresh-main-capture';
import {
assertRendererCdpTarget,
assertTcpPortAvailable,
resolveRendererWindowIdentity,
} from './m3u-import-benchmark-support';
import { assertPerformanceArtifactCapacity } from './performance-artifact-preflight';
import {
createXtreamArtifactSafetyContext,
persistXtreamIteration,
writeXtreamSafeJson,
type PersistedXtreamIteration,
} from './xtream-benchmark-artifacts';
import {
createXtreamSingleAttemptCapture,
persistXtreamIterationFailureEvidenceAndThrow,
type XtreamBenchmarkFailureStage,
} from './xtream-benchmark-lifecycle';
import {
assertXtreamBenchmarkEnvironmentIsolated,
createXtreamDiagnosticEvidence,
createXtreamSourceTitle,
finalizeXtreamCaptureAfterRendererTerminal,
prearmXtreamDatabaseWorker,
seedXtreamExistingPortal,
} from './xtream-benchmark-iteration-support';
import {
deriveXtreamMeasuredPlaylistId,
disableGenericElectronFixtureProbes,
xtreamScenarioRequiresSeed,
} from './xtream-benchmark-runtime';
import {
captureXtreamLaunchIdentity,
createXtreamIterationProcessEvidence,
} from './xtream-process-evidence';
import {
startXtreamRendererCapture,
type RunningXtreamRendererCapture,
} from './xtream-renderer-capture';
import {
prepareXtreamScenario,
type PreparedXtreamScenario,
type XtreamScenarioTerminalEvidence,
type XtreamScenarioTriggerEvidence,
} from './xtream-scenario-driver';
import { runXtreamBackgroundUiActions } from './xtream-ui-action-probe';
export interface XtreamBenchmarkIterationContext {
readonly configuration: XtreamBenchmarkConfiguration;
readonly control: XtreamControlClient;
readonly definition: XtreamIterationDefinition;
readonly expectedFixture: XtreamPerformanceManifest;
readonly scenarioDirectory: string;
readonly seenElectronPids: Set<number>;
}
export async function runXtreamBenchmarkIteration(
context: XtreamBenchmarkIterationContext
): Promise<PersistedXtreamIteration> {
const { configuration, control, definition, scenarioDirectory } = context;
const iterationDirectory = join(scenarioDirectory, definition.runId);
await assertPerformanceArtifactCapacity(iterationDirectory);
await mkdir(iterationDirectory, {
mode: 0o700,
recursive: false,
});
const dataDirectory = await mkdtemp(
join(tmpdir(), 'iptvnator-xtream-performance-')
);
const safety = createXtreamArtifactSafetyContext(
configuration.controlToken
);
let app: LaunchedElectronApp | null = null;
let renderer: RunningXtreamRendererCapture | null = null;
let prepared: PreparedXtreamScenario | null = null;
let controlState: Awaited<ReturnType<XtreamControlClient['state']>> | null =
null;
let failureStage: XtreamBenchmarkFailureStage = 'capture-setup';
let stopMainCaptureOnce:
(() => ReturnType<typeof stopXtreamMainCapture>) | null = null;
let stopRendererCaptureOnce: RunningXtreamRendererCapture['stop'] | null =
null;
let terminal: XtreamScenarioTerminalEvidence | null = null;
let trigger: XtreamScenarioTriggerEvidence | null = null;
try {
await control.resetAll();
const fixture = await control.prepare();
assertXtreamManifestIdentity(context.expectedFixture, fixture);
await assertTcpPortAvailable(configuration.cdpPort);
app = await launchElectronApp(dataDirectory, {
args: [
'--js-flags=--expose-gc',
'--remote-debugging-address=127.0.0.1',
`--remote-debugging-port=${configuration.cdpPort}`,
`--user-data-dir=${join(dataDirectory, 'user-data')}`,
],
environmentInheritance: 'runtime-only',
env: {
IPTVNATOR_DB_WORKER_BATCH_DELAY_MS: '0',
IPTVNATOR_PERF_CAPTURE: '1',
IPTVNATOR_PERF_WORKER_PROFILING: '1',
IPTVNATOR_TRACE_RENDERER_CONSOLE: '0',
},
omitEnvKeys: [
'IPTVNATOR_XTREAM_MOCK_CONTROL',
'IPTVNATOR_XTREAM_MOCK_CONTROL_TOKEN',
],
});
app.mainWindow.setDefaultTimeout(10 * 60 * 1_000);
await assertXtreamBenchmarkEnvironmentIsolated(app);
await disableGenericElectronFixtureProbes(app.mainWindow);
await assertRendererCdpTarget(app.mainWindow, configuration.cdpPort);
await installMainCapture(app.electronApp);
await prearmXtreamDatabaseWorker(app);
const electronApp = app.electronApp;
const launch = await captureXtreamLaunchIdentity(
app.electronApp,
app.electronApp.process().pid,
context.seenElectronPids
);
const rendererWindowIdentity = await resolveRendererWindowIdentity(app);
const captureOptions: MainCaptureStartOptions = {
deferMeasurement: true,
diagnostic: definition.kind === 'diagnostic',
outputDirectory: iterationDirectory,
rendererWindowIdentity,
};
const sourceTitle = createXtreamSourceTitle(definition);
const seeded = xtreamScenarioRequiresSeed(definition.scenarioId);
if (seeded) {
failureStage = 'seed';
stopMainCaptureOnce = createXtreamSingleAttemptCapture(() =>
stopXtreamMainCapture(electronApp)
);
await seedXtreamExistingPortal({
app,
captureOptions,
control,
fixture,
iterationDirectory,
safety,
serverUrl: configuration.mockOrigin,
sourceTitle,
});
}
failureStage = 'scenario-preparation';
prepared = await prepareXtreamScenario(app.mainWindow, {
scenarioId: definition.scenarioId,
serverUrl: configuration.mockOrigin,
sourceTitle,
});
await control.resetObservations();
assertXtreamControlReadyAfterObservationReset(
await control.state(),
fixture
);
let captureGeneration: number;
failureStage = 'measured-capture-start';
if (seeded) {
const rolloverOnce = createXtreamSingleAttemptCapture(() =>
rolloverXtreamMainCapture(electronApp, captureOptions)
);
stopMainCaptureOnce = rolloverOnce;
const rollover = await rolloverOnce();
stopMainCaptureOnce = createXtreamSingleAttemptCapture(() =>
stopXtreamMainCapture(electronApp)
);
if (
!rollover.rollover?.nextCaptureStarted ||
rollover.rollover.nextCaptureUnavailableReason !== null
) {
throw new Error('xtream-measured-capture-rollover-failed');
}
await writeXtreamSafeJson(
join(iterationDirectory, 'seed-main-capture.json'),
rollover,
safety
);
captureGeneration = rollover.captureGeneration + 1;
if (
(await readXtreamMainCaptureStatus(app.electronApp))
.captureGeneration !== captureGeneration
) {
throw new Error('xtream-measured-capture-generation-changed');
}
} else {
stopMainCaptureOnce = createXtreamSingleAttemptCapture(() =>
stopXtreamMainCapture(electronApp)
);
await startMainCapture(app.electronApp, captureOptions);
captureGeneration = (
await readXtreamMainCaptureStatus(app.electronApp)
).captureGeneration;
}
failureStage = 'renderer-capture-start';
renderer = await startXtreamRendererCapture(app.mainWindow, {
diagnostic: definition.kind === 'diagnostic',
outputDirectory: iterationDirectory,
scenarioId: definition.scenarioId,
sourceTitle,
});
const runningRenderer = renderer;
stopRendererCaptureOnce = createXtreamSingleAttemptCapture(() =>
runningRenderer.stop()
);
await beginXtreamMainMeasurement(app.electronApp);
await renderer.beginOperation();
failureStage = 'operation-trigger';
trigger = await prepared.trigger();
if (definition.scenarioId === XTREAM_SCENARIO_ID.BACKGROUND_UI) {
failureStage = 'background-ui';
await prepared.runBackgroundProbe(
({ operationId, page, playlistId }) =>
runXtreamBackgroundUiActions(page, {
operationId,
playlistId,
searchTerm: 'Performance',
})
);
}
failureStage = 'terminal-settlement';
const terminalPromise = prepared.waitForTerminal().then((value) => {
terminal = value;
return value;
});
if (!stopRendererCaptureOnce || !stopMainCaptureOnce) {
throw new Error('xtream-measured-capture-lifecycle-invalid');
}
const finalized = await finalizeXtreamCaptureAfterRendererTerminal({
captureGeneration,
driverTerminal: terminalPromise,
readStatus: () => readXtreamMainCaptureStatus(app.electronApp),
rendererTerminal: renderer.waitForTerminal(),
scenarioId: definition.scenarioId,
stopMain: stopMainCaptureOnce,
stopRenderer: stopRendererCaptureOnce,
});
terminal = finalized.driverTerminal;
const { mainCapture, rendererCapture } = finalized;
if (!terminal) {
throw new Error('xtream-measured-capture-lifecycle-invalid');
}
if (mainCapture.captureGeneration !== captureGeneration) {
throw new Error('xtream-measured-capture-generation-changed');
}
controlState = await control.state();
failureStage = 'evidence-validation';
await Promise.all([
writeXtreamSafeJson(
join(iterationDirectory, 'main-capture.json'),
mainCapture,
safety
),
writeXtreamSafeJson(
join(iterationDirectory, 'renderer-capture.json'),
rendererCapture,
safety
),
writeXtreamSafeJson(
join(iterationDirectory, 'terminal-evidence.json'),
terminal,
safety
),
writeXtreamSafeJson(
join(iterationDirectory, 'trigger-evidence.json'),
trigger,
safety
),
writeXtreamSafeJson(
join(iterationDirectory, 'control-state.json'),
controlState,
safety
),
]);
assertXtreamControlStateForScenario(
definition.scenarioId,
controlState,
fixture
);
const playlistId = deriveXtreamMeasuredPlaylistId(mainCapture.requests);
const catalogSnapshot = await readXtreamCatalogDatabaseSnapshot(
app.electronApp,
{
captureStoppedEpochMs: mainCapture.captureStoppedEpochMs,
dataDirectory,
playlistId,
requireFromPath: join(
configuration.workspaceRoot,
'dist/apps/electron-backend/main.js'
),
}
);
await writeXtreamSafeJson(
join(iterationDirectory, 'catalog-snapshot.json'),
catalogSnapshot,
safety
);
const catalogVerification = createXtreamCatalogVerification(
catalogSnapshot,
fixture,
definition.scenarioId
);
const diagnosticEvidence = await createXtreamDiagnosticEvidence(
definition.kind,
mainCapture,
rendererCapture,
iterationDirectory
);
const processEvidence = await createXtreamIterationProcessEvidence({
...launch,
diagnosticDirectorySha256:
diagnosticEvidence?.directorySha256 ?? null,
iterationDirectory,
});
const raw = assembleXtreamRawIteration({
catalogVerification,
definition,
diagnosticArtifacts: diagnosticEvidence,
mainCapture,
process: processEvidence,
rendererCapture,
terminal,
trigger,
});
failureStage = 'result-persistence';
return persistXtreamIteration(
iterationDirectory,
raw,
diagnosticEvidence,
safety
);
} catch (failure) {
const electronApp = app?.electronApp;
await persistXtreamIterationFailureEvidenceAndThrow(failure, {
evidence: {
control: async () => controlState ?? control.state(),
...(electronApp
? {
mainStatus: () =>
readXtreamMainCaptureStatus(electronApp),
}
: {}),
...(stopMainCaptureOnce
? { mainCapture: stopMainCaptureOnce }
: {}),
...(stopRendererCaptureOnce
? { rendererCapture: stopRendererCaptureOnce }
: {}),
...(terminal ? { terminal: async () => terminal } : {}),
...(trigger ? { trigger: async () => trigger } : {}),
},
persist: (filename, value) =>
writeXtreamSafeJson(
join(iterationDirectory, filename),
value,
safety
),
stage: failureStage,
});
} finally {
await prepared?.dispose().catch(() => undefined);
await renderer?.dispose().catch(() => undefined);
if (app) await closeElectronApp(app);
await rm(dataDirectory, { force: true, recursive: true }).catch(
() => undefined
);
}
}
@@ -0,0 +1,250 @@
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import { describe, it } from 'node:test';
import {
createXtreamSingleAttemptCapture,
persistXtreamIterationFailureEvidence,
persistXtreamIterationFailureEvidenceAndThrow,
} from './xtream-benchmark-lifecycle';
const performanceDirectory = resolve(process.cwd(), 'src/performance');
describe('Xtream benchmark failure lifecycle', () => {
it('memoizes capture finalization across success and failure paths', async () => {
let attempts = 0;
const capture = createXtreamSingleAttemptCapture(async () => {
attempts += 1;
return Object.freeze({ capture: 'complete' });
});
const [first, second] = await Promise.all([capture(), capture()]);
const third = await capture();
assert.equal(attempts, 1);
assert.strictEqual(first, second);
assert.strictEqual(second, third);
let failedAttempts = 0;
const failedCapture = createXtreamSingleAttemptCapture(async () => {
failedAttempts += 1;
throw new Error('fixed-test-failure');
});
await assert.rejects(failedCapture, /fixed-test-failure/);
await assert.rejects(failedCapture, /fixed-test-failure/);
assert.equal(failedAttempts, 1);
});
it('persists all available evidence and only fixed failure metadata', async () => {
const persisted = new Map<string, unknown>();
const attempts: string[] = [];
await persistXtreamIterationFailureEvidence({
evidence: {
control: async () => {
attempts.push('control');
return { epoch: 11 };
},
mainCapture: async () => {
attempts.push('mainCapture');
return { captureGeneration: 3 };
},
mainStatus: async () => {
attempts.push('mainStatus');
return { captureGeneration: 3, pending: 1 };
},
rendererCapture: async () => {
attempts.push('rendererCapture');
throw new Error(
'https://performance:performance@example.invalid?token=secret'
);
},
terminal: async () => {
attempts.push('terminal');
return { terminalEpochMs: 42 };
},
},
persist: async (filename, value) => {
persisted.set(filename, value);
},
stage: 'terminal-settlement',
});
assert.deepEqual(attempts.sort(), [
'control',
'mainCapture',
'mainStatus',
'rendererCapture',
'terminal',
]);
assert.deepEqual([...persisted.keys()].sort(), [
'failure-control-state.json',
'failure-main-capture.json',
'failure-main-status.json',
'failure-terminal-evidence.json',
'failure.json',
]);
const metadata = persisted.get('failure.json');
assert.deepEqual(metadata, {
evidence: {
control: 'captured',
mainCapture: 'captured',
mainStatus: 'captured',
rendererCapture: 'capture-failed',
terminal: 'captured',
trigger: 'not-available',
},
reason: 'xtream-benchmark-iteration-failed',
stage: 'terminal-settlement',
status: 'failed',
validForComparison: false,
});
const serialized = JSON.stringify([...persisted.values()]);
assert.doesNotMatch(serialized, /performance:performance|secret/iu);
assert.doesNotMatch(serialized, /message|stack/iu);
});
it('persists fixed failure metadata when capture setup never completed', async () => {
const persisted = new Map<string, unknown>();
await persistXtreamIterationFailureEvidence({
evidence: {},
persist: async (filename, value) => {
persisted.set(filename, value);
},
stage: 'capture-setup',
});
assert.deepEqual([...persisted.keys()], ['failure.json']);
assert.deepEqual(persisted.get('failure.json'), {
evidence: {
control: 'not-available',
mainCapture: 'not-available',
mainStatus: 'not-available',
rendererCapture: 'not-available',
terminal: 'not-available',
trigger: 'not-available',
},
reason: 'xtream-benchmark-iteration-failed',
stage: 'capture-setup',
status: 'failed',
validForComparison: false,
});
});
it('fails when aggregate failure evidence cannot be persisted', async () => {
await assert.rejects(
persistXtreamIterationFailureEvidence({
evidence: {},
persist: async (filename) => {
if (filename === 'failure.json') {
throw new Error('fixed-persistence-failure');
}
},
stage: 'capture-setup',
}),
/fixed-persistence-failure/
);
});
it('rethrows the original iteration failure after evidence persistence succeeds', async () => {
const originalFailure = new Error('fixed-original-failure');
await assert.rejects(
persistXtreamIterationFailureEvidenceAndThrow(originalFailure, {
evidence: {},
persist: async () => undefined,
stage: 'capture-setup',
}),
(failure: unknown) => {
assert.strictEqual(failure, originalFailure);
return true;
}
);
});
it('preserves both the original and evidence persistence failures', async () => {
const originalFailure = new Error('fixed-original-failure');
const persistenceFailure = new Error('fixed-persistence-failure');
await assert.rejects(
persistXtreamIterationFailureEvidenceAndThrow(originalFailure, {
evidence: {},
persist: async (filename) => {
if (filename === 'failure.json') {
throw persistenceFailure;
}
},
stage: 'capture-setup',
}),
(failure: unknown) => {
assert.ok(failure instanceof AggregateError);
assert.deepEqual(failure.errors, [
originalFailure,
persistenceFailure,
]);
assert.strictEqual(failure.cause, originalFailure);
return true;
}
);
});
it('collects failure evidence before teardown and writes summary before its guard', () => {
const iteration = readFileSync(
resolve(performanceDirectory, 'xtream-benchmark-iteration.ts'),
'utf8'
);
const failureCatch = iteration.indexOf('} catch (failure) {');
const failurePersistence = iteration.indexOf(
'persistXtreamIterationFailureEvidenceAndThrow(',
failureCatch
);
const teardown = iteration.indexOf('} finally {', failureCatch);
assert.ok(failureCatch >= 0, 'iteration failure catch is missing');
assert.ok(
failurePersistence > failureCatch,
'failure evidence persistence is missing'
);
assert.ok(
teardown > failurePersistence,
'teardown occurs before failure evidence persistence'
);
assert.doesNotMatch(
iteration.slice(failureCatch, teardown),
/if \(captureInstalled\)/u,
'early capture-setup failure metadata is incorrectly gated'
);
assert.match(iteration, /createXtreamSingleAttemptCapture/);
const seededBranch = iteration.indexOf('if (seeded) {');
const seedStop = iteration.indexOf(
'stopMainCaptureOnce = createXtreamSingleAttemptCapture',
seededBranch
);
const seedRun = iteration.indexOf(
'await seedXtreamExistingPortal',
seededBranch
);
assert.ok(
seedStop > seededBranch && seedRun > seedStop,
'seed capture does not have failure finalization armed'
);
const orchestrator = readFileSync(
resolve(performanceDirectory, 'xtream-benchmark-orchestrator.ts'),
'utf8'
);
const summaryWrite = orchestrator.indexOf(
"join(configuration.outputDirectory, 'summary.json')"
);
const validityGuard = orchestrator.indexOf(
'summary.validForComparison !=='
);
assert.ok(summaryWrite >= 0, 'summary persistence is missing');
assert.ok(
validityGuard > summaryWrite,
'comparison-validity guard runs before summary persistence'
);
});
});
@@ -0,0 +1,93 @@
export type XtreamBenchmarkFailureStage =
| 'background-ui'
| 'capture-setup'
| 'capture-stop'
| 'evidence-validation'
| 'measured-capture-start'
| 'operation-trigger'
| 'renderer-capture-start'
| 'result-persistence'
| 'scenario-preparation'
| 'seed'
| 'terminal-settlement';
type FailureEvidenceName =
| 'control'
| 'mainCapture'
| 'mainStatus'
| 'rendererCapture'
| 'terminal'
| 'trigger';
type FailureEvidenceStatus = 'capture-failed' | 'captured' | 'not-available';
interface PersistXtreamIterationFailureEvidenceOptions {
readonly evidence: Partial<
Record<FailureEvidenceName, () => Promise<unknown>>
>;
readonly persist: (filename: string, value: unknown) => Promise<void>;
readonly stage: XtreamBenchmarkFailureStage;
}
const EVIDENCE_ARTIFACTS: readonly [FailureEvidenceName, string][] =
Object.freeze([
['mainStatus', 'failure-main-status.json'],
['mainCapture', 'failure-main-capture.json'],
['rendererCapture', 'failure-renderer-capture.json'],
['trigger', 'failure-trigger-evidence.json'],
['terminal', 'failure-terminal-evidence.json'],
['control', 'failure-control-state.json'],
]);
export function createXtreamSingleAttemptCapture<T>(
capture: () => Promise<T>
): () => Promise<T> {
let attempt: Promise<T> | null = null;
return () => {
attempt ??= Promise.resolve().then(capture);
return attempt;
};
}
export async function persistXtreamIterationFailureEvidence(
options: PersistXtreamIterationFailureEvidenceOptions
): Promise<void> {
const status = {} as Record<FailureEvidenceName, FailureEvidenceStatus>;
for (const [name, filename] of EVIDENCE_ARTIFACTS) {
const capture = options.evidence[name];
if (!capture) {
status[name] = 'not-available';
continue;
}
try {
const value = await capture();
await options.persist(filename, value);
status[name] = 'captured';
} catch {
status[name] = 'capture-failed';
}
}
await options.persist('failure.json', {
evidence: status,
reason: 'xtream-benchmark-iteration-failed',
stage: options.stage,
status: 'failed',
validForComparison: false,
});
}
export async function persistXtreamIterationFailureEvidenceAndThrow(
failure: unknown,
options: PersistXtreamIterationFailureEvidenceOptions
): Promise<never> {
try {
await persistXtreamIterationFailureEvidence(options);
} catch (persistenceFailure) {
throw new AggregateError(
[failure, persistenceFailure],
'Xtream benchmark iteration and failure evidence persistence failed',
{ cause: failure }
);
}
throw failure;
}
@@ -0,0 +1,186 @@
import type { XtreamBenchmarkManifest } from './xtream-benchmark-contract';
import { parseXtreamBenchmarkBuildIdentity } from './xtream-build-identity-schema';
import { assertXtreamArtifactRedacted } from './xtream-diagnostic-artifacts';
import { XTREAM_MEMORY_ACCOUNTING } from './xtream-summary-contract';
export const XTREAM_SHA256 = /^[a-f0-9]{64}$/u;
export const XTREAM_IDENTIFIER =
/^(?!(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$))[A-Za-z0-9](?:[A-Za-z0-9._-]{0,126}[A-Za-z0-9_-])?$/iu;
const ROOT_KEYS = [
'build',
'environment',
'fixture',
'memoryAccounting',
'mode',
'runtime',
'source',
'suite',
'variant',
] as const;
const ENVIRONMENT_KEYS = [
'cdpAddress',
'cdpPort',
'databaseWorkerBatchDelayMs',
'exposeGc',
'freshUserDataPerIteration',
'perfCapture',
'perfWorkerProfiling',
'traceRendererConsole',
] as const;
const FIXTURE_KEYS = [
'bytes',
'catalogSha256',
'categories',
'items',
'scenario',
'seed',
] as const;
const RUNTIME_KEYS = [
'arch',
'electronVersion',
'harnessNodeVersion',
'platform',
] as const;
const SOURCE_KEYS = ['gitCommit', 'gitDiffSha256', 'gitDirty'] as const;
const MEMORY_KEYS = Object.keys(XTREAM_MEMORY_ACCOUNTING);
export function parseXtreamBenchmarkManifest(
value: unknown
): XtreamBenchmarkManifest {
try {
const input = snapshotExactRecord(value, ROOT_KEYS);
const build = parseXtreamBenchmarkBuildIdentity(input['build']);
const environment = snapshotExactRecord(
input['environment'],
ENVIRONMENT_KEYS
);
const fixture = snapshotExactRecord(input['fixture'], FIXTURE_KEYS);
const memoryAccounting = snapshotExactRecord(
input['memoryAccounting'],
MEMORY_KEYS
);
const runtime = snapshotExactRecord(input['runtime'], RUNTIME_KEYS);
const source = snapshotExactRecord(input['source'], SOURCE_KEYS);
const snapshot = {
build,
environment: { ...environment },
fixture: { ...fixture },
memoryAccounting: { ...memoryAccounting },
mode: input['mode'],
runtime: { ...runtime },
source: { ...source },
suite: input['suite'],
variant: input['variant'],
};
assertXtreamArtifactRedacted(snapshot);
if (!isValidManifest(snapshot)) invalid();
return freezeDeep(snapshot) as unknown as XtreamBenchmarkManifest;
} catch {
throw new Error('invalid Xtream benchmark manifest');
}
}
export function assertXtreamBenchmarkManifest(
value: unknown
): asserts value is XtreamBenchmarkManifest {
parseXtreamBenchmarkManifest(value);
}
function isValidManifest(
manifest: Record<string, unknown> & {
environment: Record<string, unknown>;
fixture: Record<string, unknown>;
memoryAccounting: Record<string, unknown>;
runtime: Record<string, unknown>;
source: Record<string, unknown>;
}
): boolean {
const { environment, fixture, memoryAccounting, runtime, source } =
manifest;
return (
environment['cdpAddress'] === '127.0.0.1' &&
isValidXtreamCdpPort(manifest['mode'], environment['cdpPort']) &&
environment['databaseWorkerBatchDelayMs'] === 0 &&
environment['exposeGc'] === true &&
environment['freshUserDataPerIteration'] === true &&
environment['perfCapture'] === '1' &&
environment['perfWorkerProfiling'] === '1' &&
environment['traceRendererConsole'] === '0' &&
fixture['scenario'] === 'performance-100k' &&
fixture['seed'] === 91_001 &&
fixture['categories'] === 100 &&
fixture['items'] === 100_000 &&
isPositiveSafeInteger(fixture['bytes']) &&
typeof fixture['catalogSha256'] === 'string' &&
XTREAM_SHA256.test(fixture['catalogSha256']) &&
Object.values(runtime).every(
(entry) => typeof entry === 'string' && entry.length > 0
) &&
typeof source['gitCommit'] === 'string' &&
/^[a-f0-9]{40}$/u.test(source['gitCommit']) &&
typeof source['gitDiffSha256'] === 'string' &&
XTREAM_SHA256.test(source['gitDiffSha256']) &&
typeof source['gitDirty'] === 'boolean' &&
(manifest['mode'] !== 'formal' || !source['gitDirty']) &&
(manifest['mode'] === 'formal' || manifest['mode'] === 'smoke') &&
manifest['suite'] === 'xtream-performance-100k' &&
typeof manifest['variant'] === 'string' &&
XTREAM_IDENTIFIER.test(manifest['variant']) &&
MEMORY_KEYS.every(
(key) =>
memoryAccounting[key] ===
XTREAM_MEMORY_ACCOUNTING[
key as keyof typeof XTREAM_MEMORY_ACCOUNTING
]
)
);
}
function isValidXtreamCdpPort(mode: unknown, cdpPort: unknown): boolean {
return (
(mode === 'formal' || mode === 'smoke') &&
typeof cdpPort === 'number' &&
Number.isInteger(cdpPort) &&
cdpPort >= 1024 &&
cdpPort <= 65_535 &&
(mode === 'smoke' || cdpPort === 9222)
);
}
function snapshotExactRecord(
value: unknown,
expectedKeys: readonly string[]
): Record<string, unknown> {
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
invalid();
}
const keys = Reflect.ownKeys(value);
if (
keys.length !== expectedKeys.length ||
keys.some(
(key) => typeof key !== 'string' || !expectedKeys.includes(key)
)
) {
invalid();
}
return Object.fromEntries(
expectedKeys.map((key) => [key, Reflect.get(value, key)])
);
}
function freezeDeep<T>(value: T): T {
if (value && typeof value === 'object' && !Object.isFrozen(value)) {
Object.values(value).forEach(freezeDeep);
Object.freeze(value);
}
return value;
}
function isPositiveSafeInteger(value: unknown): boolean {
return Number.isSafeInteger(value) && Number(value) > 0;
}
function invalid(): never {
throw new Error('invalid manifest');
}
@@ -0,0 +1,119 @@
import { mkdir } from 'node:fs/promises';
import { join } from 'node:path';
import {
createXtreamIterationDefinitions,
listXtreamBenchmarkScenarios,
} from './xtream-benchmark-contract';
import {
assertXtreamBenchmarkBuildUnchanged,
createXtreamBenchmarkManifest,
resolveXtreamBenchmarkConfiguration,
} from './xtream-benchmark-configuration';
import {
createXtreamArtifactSafetyContext,
writeXtreamSafeJson,
} from './xtream-benchmark-artifacts';
import { runXtreamBenchmarkIteration } from './xtream-benchmark-iteration';
import { createXtreamBenchmarkSummary } from './xtream-benchmark-report';
import {
assertXtreamControlReadyAfterObservationReset,
createXtreamControlClient,
} from './xtream-control-client';
import type { XtreamDiagnosticArtifactEvidence } from './xtream-diagnostic-artifacts';
import type { XtreamValidatedIterationResult } from './xtream-summary-contract';
export async function runXtreamBenchmark(): Promise<void> {
const configuration = await resolveXtreamBenchmarkConfiguration();
const safety = createXtreamArtifactSafetyContext(
configuration.controlToken
);
const control = createXtreamControlClient({
origin: configuration.mockOrigin,
token: configuration.controlToken,
});
const iterations: XtreamValidatedIterationResult[] = [];
const diagnosticEvidence = new Map<
XtreamValidatedIterationResult,
XtreamDiagnosticArtifactEvidence
>();
const seenElectronPids = new Set<number>();
try {
await control.resetAll();
const expectedFixture = await control.prepare();
await control.resetObservations();
assertXtreamControlReadyAfterObservationReset(
await control.state(),
expectedFixture
);
const manifest = createXtreamBenchmarkManifest(
configuration,
expectedFixture
);
await writeXtreamSafeJson(
join(configuration.outputDirectory, 'manifest.json'),
manifest,
safety
);
const definitions = createXtreamIterationDefinitions(
configuration.smoke
);
for (const scenario of listXtreamBenchmarkScenarios()) {
const scenarioDirectory = join(
configuration.outputDirectory,
scenario.id
);
await mkdir(scenarioDirectory, {
mode: 0o700,
recursive: false,
});
for (const definition of definitions.filter(
({ scenarioId }) => scenarioId === scenario.id
)) {
console.log(
`[performance] ${configuration.variant}/${scenario.id}/${definition.runId} starting`
);
const persisted = await runXtreamBenchmarkIteration({
configuration,
control,
definition,
expectedFixture,
scenarioDirectory,
seenElectronPids,
});
iterations.push(persisted.iteration);
if (persisted.diagnosticEvidence) {
diagnosticEvidence.set(
persisted.iteration,
persisted.diagnosticEvidence
);
}
console.log(
`[performance] ${scenario.id}/${definition.runId} total=${persisted.iteration.phases.totalMs.toFixed(3)}ms`
);
}
}
await assertXtreamBenchmarkBuildUnchanged(configuration);
const summary = createXtreamBenchmarkSummary(
manifest,
iterations,
diagnosticEvidence
);
await writeXtreamSafeJson(
join(configuration.outputDirectory, 'summary.json'),
summary,
safety
);
if (summary.validForComparison !== (configuration.mode === 'formal')) {
throw new Error('xtream-benchmark-comparison-validity-invalid');
}
console.log(
`[performance] completed: ${join(
configuration.outputDirectory,
'summary.json'
)}`
);
} finally {
await control.resetAll().catch(() => undefined);
}
}
@@ -0,0 +1,180 @@
import type { MakeDirectoryOptions } from 'node:fs';
import { lstat, mkdir, rmdir } from 'node:fs/promises';
import {
basename,
dirname,
isAbsolute,
join,
relative,
resolve,
sep,
} from 'node:path';
import { assertXtreamSafePathIdentifier } from './xtream-exact-schema';
export const XTREAM_BENCHMARK_FORMAL_CDP_PORT = 9222;
const OUTPUT_TIMESTAMP =
/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z(?:-[a-z][a-z0-9-]{0,63})?$/u;
export interface XtreamBenchmarkOutputLayout {
readonly outputDirectory: string;
readonly outputRoot: string;
readonly performanceRoot: string;
}
export type XtreamMkdir = (
path: string,
options?: MakeDirectoryOptions
) => Promise<string | undefined | void>;
export function resolveXtreamBenchmarkOutputLayout(
repositoryRoot: string,
requestedRoot: string,
variant: string
): XtreamBenchmarkOutputLayout {
const root = resolve(repositoryRoot);
const performanceRoot = join(root, 'dist', 'performance');
const outputRoot = resolve(requestedRoot);
if (
!isAbsolute(repositoryRoot) ||
!isAbsolute(requestedRoot) ||
requestedRoot !== outputRoot ||
dirname(outputRoot) !== performanceRoot ||
!isValidTimestampDirectory(basename(outputRoot))
) {
throw new Error(
'Performance output must be an absolute fresh timestamp path below dist/performance'
);
}
try {
assertXtreamSafePathIdentifier(variant, 'variant');
} catch {
throw new Error('IPTVNATOR_PERF_VARIANT must be a safe Xtream variant');
}
const outputDirectory = join(outputRoot, variant);
if (!isStrictDescendant(outputRoot, outputDirectory)) {
throw new Error('IPTVNATOR_PERF_VARIANT must be a safe Xtream variant');
}
return Object.freeze({ outputDirectory, outputRoot, performanceRoot });
}
export function resolveXtreamBenchmarkCdpPort(
mode: 'formal' | 'smoke',
requestedPort: string | undefined
): number {
const port =
requestedPort === undefined
? XTREAM_BENCHMARK_FORMAL_CDP_PORT
: Number(requestedPort);
if (
(requestedPort !== undefined && !/^[1-9]\d*$/u.test(requestedPort)) ||
!Number.isSafeInteger(port) ||
port < 1024 ||
port > 65_535
) {
throw new Error('IPTVNATOR_PERF_CDP_PORT is invalid');
}
if (mode === 'formal' && port !== XTREAM_BENCHMARK_FORMAL_CDP_PORT) {
throw new Error(
`Formal Xtream performance runs require CDP port ${XTREAM_BENCHMARK_FORMAL_CDP_PORT}`
);
}
return port;
}
export async function assertXtreamBenchmarkOutputPathHasNoSymlinks(
repositoryRoot: string,
outputRoot: string
): Promise<void> {
const root = resolve(repositoryRoot);
const output = resolve(outputRoot);
if (!isStrictDescendant(root, output)) {
throw new Error('Xtream performance output escapes the repository');
}
const components = relative(root, output).split(sep);
let current = root;
for (const component of ['', ...components]) {
current = component ? join(current, component) : current;
try {
if ((await lstat(current)).isSymbolicLink()) {
throw new Error(
`Xtream performance output contains a symbolic link: ${current}`
);
}
} catch (error) {
if (isMissingPath(error)) return;
throw error;
}
}
}
export async function createExclusiveXtreamBenchmarkOutputLayout(
repositoryRoot: string,
layout: XtreamBenchmarkOutputLayout,
createDirectory: XtreamMkdir = mkdir
): Promise<void> {
await createDirectory(layout.performanceRoot, {
mode: 0o700,
recursive: true,
});
await assertXtreamBenchmarkOutputPathHasNoSymlinks(
repositoryRoot,
layout.outputRoot
);
await createDirectory(layout.outputRoot, {
mode: 0o700,
recursive: false,
});
try {
await createDirectory(layout.outputDirectory, {
mode: 0o700,
recursive: false,
});
} catch (error) {
await rmdir(layout.outputRoot).catch(() => undefined);
throw error;
}
await assertXtreamBenchmarkOutputPathHasNoSymlinks(
repositoryRoot,
layout.outputDirectory
);
}
function isValidTimestampDirectory(value: string): boolean {
const match = OUTPUT_TIMESTAMP.exec(value);
if (!match) return false;
const [, year, month, day, hour, minute, second] = match;
const timestamp = Date.UTC(
Number(year),
Number(month) - 1,
Number(day),
Number(hour),
Number(minute),
Number(second)
);
return (
Number.isFinite(timestamp) &&
new Date(timestamp).toISOString().replace(/[-:]/gu, '').slice(0, 15) ===
`${year}${month}${day}T${hour}${minute}${second}`
);
}
function isStrictDescendant(parent: string, candidate: string): boolean {
const pathFromParent = relative(resolve(parent), resolve(candidate));
return (
pathFromParent.length > 0 &&
pathFromParent !== '..' &&
!pathFromParent.startsWith(`..${sep}`) &&
!isAbsolute(pathFromParent)
);
}
function isMissingPath(error: unknown): boolean {
return (
typeof error === 'object' &&
error !== null &&
'code' in error &&
error.code === 'ENOENT'
);
}
@@ -0,0 +1,178 @@
import { mkdtemp, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import {
createXtreamIterationDefinitions,
XTREAM_ITERATION_KIND,
XTREAM_SCENARIO_ID,
type XtreamIterationDefinition,
} from './xtream-benchmark-contract';
import {
validateXtreamDiagnosticArtifacts,
type XtreamDiagnosticArtifactEvidence,
type XtreamDiagnosticCapture,
} from './xtream-diagnostic-artifacts';
import { CPU_PROFILE } from './initial-import-diagnostic-test-fixtures';
import {
iteration,
persist,
withWorkerRequestOverlap,
} from './xtream-benchmark-report.fixtures';
import type { XtreamValidatedIterationResult } from './xtream-summary-contract';
const HEAP_SNAPSHOT = {
edges: [0, 0, 0],
nodes: [0, 0, 1, 0, 1, 0],
snapshot: {
meta: {
edge_fields: ['type', 'name_or_index', 'to_node'],
edge_types: [['context'], 'string_or_number', 'node'],
node_fields: [
'type',
'name',
'id',
'self_size',
'edge_count',
'detachedness',
],
node_types: [
['hidden'],
'string',
'number',
'number',
'number',
'number',
],
},
},
strings: ['', 'root'],
};
const RENDERER_TRACE = {
traceEvents: [{ name: 'xtream-diagnostic', ph: 'X', ts: 1 }],
};
const directories: string[] = [];
export interface XtreamReportFixture {
readonly diagnosticEvidence: ReadonlyMap<
XtreamValidatedIterationResult,
XtreamDiagnosticArtifactEvidence
>;
readonly iterations: readonly XtreamValidatedIterationResult[];
}
export async function formalReportFixture(): Promise<XtreamReportFixture> {
return reportFixture(createXtreamIterationDefinitions(false), 10, true);
}
export async function smokeReportFixture(): Promise<XtreamReportFixture> {
return reportFixture(createXtreamIterationDefinitions(true), 100, false);
}
export async function clearXtreamProvenanceFixtureDirectories(): Promise<void> {
await Promise.all(
directories
.splice(0)
.map((directory) => rm(directory, { force: true, recursive: true }))
);
}
async function reportFixture(
definitions: readonly XtreamIterationDefinition[],
identityOffset: number,
mixedInitialOverlap: boolean
): Promise<XtreamReportFixture> {
const entries = await Promise.all(
definitions.map(async (definition, index) => {
const identity = index + 1;
let raw = iteration(definition, identity);
let evidence: XtreamDiagnosticArtifactEvidence | null = null;
if (definition.kind === XTREAM_ITERATION_KIND.DIAGNOSTIC) {
evidence = await diagnosticEvidence(identity + identityOffset);
raw = {
...raw,
processIdentity: {
...raw.processIdentity,
profileDirectorySha256: evidence.directorySha256,
},
};
}
if (
mixedInitialOverlap &&
definition.scenarioId ===
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE &&
['run-02', 'run-04'].includes(definition.runId)
) {
raw = withWorkerRequestOverlap(raw, 2);
}
return {
evidence,
iteration: await persist(raw, identity + identityOffset),
};
})
);
return {
diagnosticEvidence: new Map(
entries.flatMap(({ evidence, iteration: result }) =>
evidence ? [[result, evidence] as const] : []
)
),
iterations: entries.map(({ iteration: result }) => result),
};
}
async function diagnosticEvidence(
identity: number
): Promise<XtreamDiagnosticArtifactEvidence> {
const directory = await mkdtemp(
join(tmpdir(), `iptvnator-xtream-report-diagnostic-${identity}-`)
);
directories.push(directory);
await writeArtifacts(directory);
return validateXtreamDiagnosticArtifacts(capture(directory), directory);
}
function capture(directory: string): XtreamDiagnosticCapture {
return {
main: {
cpuProfilePath: join(directory, 'main.cpuprofile'),
heapSnapshotPath: join(directory, 'main.heapsnapshot'),
workers: [
{
kind: 'database.worker',
ordinal: 1,
profilePath: join(
directory,
'database.worker-1.cpuprofile'
),
snapshotPath: join(
directory,
'database.worker-1.heapsnapshot'
),
},
],
},
renderer: {
cpuProfilePath: join(directory, 'renderer.cpuprofile'),
heapSnapshotPath: join(directory, 'renderer.heapsnapshot'),
tracePath: join(directory, 'renderer.trace.json'),
},
};
}
async function writeArtifacts(directory: string): Promise<void> {
const artifacts = [
['main.cpuprofile', CPU_PROFILE],
['renderer.cpuprofile', CPU_PROFILE],
['database.worker-1.cpuprofile', CPU_PROFILE],
['main.heapsnapshot', HEAP_SNAPSHOT],
['renderer.heapsnapshot', HEAP_SNAPSHOT],
['database.worker-1.heapsnapshot', HEAP_SNAPSHOT],
['renderer.trace.json', RENDERER_TRACE],
] as const;
await Promise.all(
artifacts.map(([filename, value]) =>
writeFile(join(directory, filename), JSON.stringify(value))
)
);
}
@@ -0,0 +1,400 @@
import { createHash } from 'node:crypto';
import { mkdtemp, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import {
XTREAM_ITERATION_KIND,
XTREAM_SCENARIO_ID,
type XtreamIterationDefinition,
} from './xtream-benchmark-contract';
import {
computeXtreamBuildFilesAggregate,
type XtreamBenchmarkBuildIdentity,
type XtreamBuildFileIdentity,
} from './xtream-build-identity';
import { persistThenValidateXtreamIteration } from './xtream-benchmark-report';
import { bindFixtureCancellationEvidence } from './xtream-cancellation-evidence.fixture';
import { bindFixtureIpcWorkerIdentities } from './xtream-ipc-worker-identity.fixture';
import { scenarioCapture } from './xtream-phase-attribution.fixtures';
import { attributeXtreamPhases } from './xtream-phase-attribution';
import {
XTREAM_MEMORY_ACCOUNTING,
type XtreamArtifactSafetyContext,
type XtreamBenchmarkManifest,
type XtreamPersistenceReceipt,
type XtreamRawIterationResult,
type XtreamValidatedIterationResult,
} from './xtream-summary-contract';
import {
invalidateWorkerRequestMetrics,
workerRequestEvidence,
} from './xtream-worker-request-evidence.fixtures';
import { bindFixtureWorkerEvidence } from './xtream-worker-phase-evidence.fixture';
import type { WorkerRequestPerformanceMetrics } from './m3u-refresh-cancellation-contract';
export const TOKEN = 'random-control-token-that-must-never-persist';
const buildFile = (path: string, marker: string): XtreamBuildFileIdentity => ({
bytes: marker.length,
path,
sha256: sha256(marker),
});
const rendererFiles = [
buildFile('dist/apps/web/index.html', 'renderer-index'),
buildFile('dist/apps/web/main-FIXTURE.js', 'renderer-javascript'),
buildFile('dist/apps/web/main-FIXTURE.js.map', 'renderer-source-map'),
] as const;
export const BUILD_IDENTITY: XtreamBenchmarkBuildIdentity = {
electron: {
databaseWorker: {
javascript: buildFile(
'dist/apps/electron-backend/workers/database.worker.js',
'database-worker-javascript'
),
sourceMap: buildFile(
'dist/apps/electron-backend/workers/database.worker.js.map',
'database-worker-source-map'
),
},
main: {
javascript: buildFile(
'dist/apps/electron-backend/main.js',
'main-javascript'
),
sourceMap: buildFile(
'dist/apps/electron-backend/main.js.map',
'main-source-map'
),
},
playlistRefreshWorker: {
javascript: buildFile(
'dist/apps/electron-backend/workers/playlist-refresh.worker.js',
'playlist-worker-javascript'
),
sourceMap: buildFile(
'dist/apps/electron-backend/workers/playlist-refresh.worker.js.map',
'playlist-worker-source-map'
),
},
preload: {
javascript: buildFile(
'dist/apps/electron-backend/main.preload.js',
'preload-javascript'
),
sourceMap: buildFile(
'dist/apps/electron-backend/main.preload.js.map',
'preload-source-map'
),
},
},
renderer: {
aggregateSha256: computeXtreamBuildFilesAggregate(rendererFiles),
bytes: rendererFiles.reduce((total, file) => total + file.bytes, 0),
executableJavaScriptCount: 1,
files: rendererFiles,
sourceMapCount: 1,
},
};
const SAFETY: XtreamArtifactSafetyContext = {
controlToken: TOKEN,
syntheticCredentials: {
password: 'performance',
username: 'performance',
},
};
export const MANIFEST: XtreamBenchmarkManifest = {
build: BUILD_IDENTITY,
environment: {
cdpAddress: '127.0.0.1',
cdpPort: 9222,
databaseWorkerBatchDelayMs: 0,
exposeGc: true,
freshUserDataPerIteration: true,
perfCapture: '1',
perfWorkerProfiling: '1',
traceRendererConsole: '0',
},
fixture: {
bytes: 12_345,
catalogSha256: hash('1'),
categories: 100,
items: 100_000,
scenario: 'performance-100k',
seed: 91_001,
},
memoryAccounting: XTREAM_MEMORY_ACCOUNTING,
mode: 'formal',
runtime: {
arch: 'arm64',
electronVersion: '38.0.0',
harnessNodeVersion: '22.0.0',
platform: 'darwin',
},
source: {
gitCommit: '0123456789abcdef0123456789abcdef01234567',
gitDiffSha256: hash('2'),
gitDirty: false,
},
suite: 'xtream-performance-100k',
variant: 'baseline',
};
const directories: string[] = [];
export async function clearXtreamReportFixtureDirectories(): Promise<void> {
await Promise.all(
directories
.splice(0)
.map((directory) => rm(directory, { force: true, recursive: true }))
);
}
export async function persist(
raw: XtreamRawIterationResult,
id: number,
afterWrite?: () => void
): Promise<XtreamValidatedIterationResult> {
return persistWith(raw, async (serialized) => {
const directory = await mkdtemp(
join(tmpdir(), `iptvnator-xtream-raw-${id}-`)
);
directories.push(directory);
const absolutePath = join(directory, 'raw.json');
await writeFile(absolutePath, serialized, 'utf8');
afterWrite?.();
return {
absolutePath,
bytes: Buffer.byteLength(serialized),
sha256: sha256(serialized),
};
});
}
export function persistWith(
raw: XtreamRawIterationResult,
write: (serialized: string) => Promise<XtreamPersistenceReceipt>
): Promise<XtreamValidatedIterationResult> {
return persistThenValidateXtreamIteration(raw, SAFETY, write);
}
export function iteration(
definition: XtreamIterationDefinition,
identity: number
): XtreamRawIterationResult {
const diagnostic = definition.kind === XTREAM_ITERATION_KIND.DIAGNOSTIC;
const background =
definition.scenarioId === XTREAM_SCENARIO_ID.BACKGROUND_UI;
const workerBinding = bindFixtureWorkerEvidence(
scenarioCapture(definition.scenarioId),
workerRequestEvidence(definition.scenarioId)
);
const cancellationBinding = bindFixtureCancellationEvidence(
workerBinding.phaseCapture,
workerBinding.requests
);
const ipcWorkerBinding = bindFixtureIpcWorkerIdentities(
cancellationBinding.phaseCapture,
workerBinding.requests
);
const phaseCapture = ipcWorkerBinding.phaseCapture;
const phases = attributeXtreamPhases(phaseCapture);
const requestEvidence = ipcWorkerBinding.requests;
const capturedRequestEvidence = background
? invalidateWorkerRequestMetrics(requestEvidence, 3)
: requestEvidence;
const requestTotalCount = requestEvidence.length;
const profile = {
cpuProfileDurationMicros: diagnostic ? 2_000 : null,
cpuProfileUnavailableReason: diagnostic
? null
: 'not-captured-outside-diagnostic',
} as const;
return {
...definition,
processIdentity: {
captureGeneration: 1,
electronPid: 10_000 + identity,
freshProcess: true,
generationIdentitySha256: numberedHash(identity, 3),
launchId: `launch-${identity}`,
profileDirectorySha256: numberedHash(identity, 4),
},
phaseCapture,
phases,
renderer: {
...profile,
actionLatencyMs: background ? 7 : null,
consoleErrors: [],
dashboardPaintVisibility: background
? 'visible-without-overlay'
: null,
frameGapMaxMs: 45,
frameGapP95Ms: 20,
heartbeatMaxMs: 12,
heartbeatP95Ms: 5,
longTaskCount: 2,
longTaskMaxMs: 75,
navigationLatencyMs: background ? 8 : null,
peakHeapUsedBytes: 300,
peakRssBytes: 500,
postGcHeapUsedBytes: 200,
searchLatencyMs: background ? 9 : null,
storeToPaintMs: phases.angularRenderingMs,
targetId: `renderer-${identity}`,
},
main: {
...profile,
browserWindowId: 1,
cpuMetricScope: 'electron-main-thread',
cpuSystemMicros: 200,
cpuUserMicros: 1_000,
eventLoopDelayMaxMs: 8,
eventLoopDelayP95Ms: 2,
eventLoopDelayP99Ms: 4,
eventLoopUtilization: null,
eventLoopUtilizationUnavailableReason:
'electron-main-embedded-event-loop',
peakHeapUsedBytes: 400,
peakRssBytes: 1_000,
postGcHeapUsedBytes: 250,
responsiveEvents: 0,
unresponsiveEvents: 0,
webContentsId: 2,
},
databaseWorker: {
...profile,
cpuMetricScope: 'sum-valid-request-thread-cpu',
cpuSystemMicros:
capturedRequestEvidence.filter(
({ invalidReason }) => invalidReason === null
).length * 10,
cpuUserMicros:
capturedRequestEvidence.filter(
({ invalidReason }) => invalidReason === null
).length * 20,
currentForCapture: true,
eventLoopDelayMaxMs: 9,
eventLoopDelayMetricScope: 'valid-request-window-proxy',
eventLoopDelayP95Ms: 3,
eventLoopDelayP99Ms: 5,
eventLoopUtilization: 0.6,
kind: 'database.worker',
ordinal: 1,
peakExternalBytes: 40,
peakHeapUsedBytes: 250,
postGcHeapUsedBytes: 150,
requests: {
evidence: capturedRequestEvidence,
eventLoopDelayMaxMs: 9,
eventLoopDelayP95Ms: 3,
eventLoopDelayP99Ms: 5,
eventLoopUtilization: 0.5,
invalidReasons: background
? [
{
count: 3,
reason: 'overlapping-database-worker-requests',
},
]
: [],
invalidSampleCount: background ? 3 : 0,
metricScope: 'valid-request-window-proxy',
totalCount: requestTotalCount,
validSampleCount: requestTotalCount - (background ? 3 : 0),
},
rssBytes: null,
rssUnavailableReason: 'unavailable-per-worker-thread',
wholeWorkerMetricScope: 'whole-worker-operation-window',
},
playlistRefreshWorker: {
instantiated: false,
reason: 'not-instantiated-by-xtream-flow',
},
cancellation: cancellationBinding.cancellation,
cancellationEvidence: cancellationBinding.cancellationEvidence,
catalogVerification: {
databaseStateValid: true,
fixtureIdentityValid: true,
providerCategoryCount: 100,
providerItemCount: 100_000,
verifiedAfterCapture: true,
},
validity: {
actionContractValid: true,
catalogContractValid: true,
databaseWorkerCount: 1,
dbPhaseContractValid: true,
diagnosticArtifactsValid: diagnostic ? true : null,
lateDatabaseRequestCount: 0,
playlistWorkerCount: 0,
rendererTargetCount: 1,
},
};
}
export function withWorkerRequestOverlap(
raw: XtreamRawIterationResult,
invalidSampleCount: number
): XtreamRawIterationResult {
return {
...raw,
databaseWorker: {
...raw.databaseWorker,
requests: {
...raw.databaseWorker.requests,
evidence: invalidateWorkerRequestMetrics(
raw.databaseWorker.requests.evidence.map(
restoreValidRequestMetrics
),
invalidSampleCount
),
invalidReasons:
invalidSampleCount === 0
? []
: [
{
count: invalidSampleCount,
reason: 'overlapping-database-worker-requests',
},
],
invalidSampleCount,
validSampleCount:
raw.databaseWorker.requests.totalCount - invalidSampleCount,
},
},
};
}
function restoreValidRequestMetrics(
request: WorkerRequestPerformanceMetrics
): WorkerRequestPerformanceMetrics {
if (
request.workEndedEpochMs === null ||
request.responsePostedEpochMs === null
) {
throw new Error('invalid Xtream request fixture');
}
return {
...request,
eventLoopDelay: { maxMs: 9, p95Ms: 3, p99Ms: 5 },
eventLoopDelayUnavailableReason: null,
eventLoopUtilization: 0.5,
eventLoopUtilizationUnavailableReason: null,
histogramFlushedEpochMs:
(request.workEndedEpochMs + request.responsePostedEpochMs) / 2,
invalidReason: null,
threadCpuSystemMicros: 10,
threadCpuUnavailableReason: null,
threadCpuUserMicros: 20,
};
}
export function sha256(value: string): string {
return createHash('sha256').update(value).digest('hex');
}
function hash(character: string): string {
return character.repeat(64);
}
function numberedHash(value: number, salt: number): string {
return sha256(`${salt}:${value}`);
}
@@ -0,0 +1,351 @@
import assert from 'node:assert/strict';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, describe, it } from 'node:test';
import {
createXtreamIterationDefinitions,
type XtreamBenchmarkManifest,
} from './xtream-benchmark-contract';
import { createXtreamBenchmarkSummary } from './xtream-benchmark-report';
import {
MANIFEST,
TOKEN,
clearXtreamReportFixtureDirectories,
iteration,
persist,
persistWith,
sha256,
} from './xtream-benchmark-report.fixtures';
import {
clearXtreamProvenanceFixtureDirectories,
formalReportFixture,
smokeReportFixture,
} from './xtream-benchmark-report-provenance.fixtures';
afterEach(async () => {
await Promise.all([
clearXtreamReportFixtureDirectories(),
clearXtreamProvenanceFixtureDirectories(),
]);
});
describe('Xtream benchmark report contract', () => {
it('writes exact raw bytes before semantic validation and verifies a real receipt', async () => {
const raw = iteration(
itemAt(createXtreamIterationDefinitions(false), 1),
1
);
const invalid = {
...raw,
main: { ...raw.main, peakRssBytes: -1 },
};
const order: string[] = [];
await assert.rejects(
() =>
persist(invalid, 1, () => {
order.push('raw-written');
}),
/invalid Xtream iteration/
);
order.push('validation-rejected');
assert.deepEqual(order, ['raw-written', 'validation-rejected']);
await assert.rejects(
() =>
persistWith(raw, async (serialized) => ({
absolutePath: join(tmpdir(), 'does-not-exist.json'),
bytes: Buffer.byteLength(serialized),
sha256: sha256(serialized),
})),
/persistence receipt/
);
});
it('brands the exact persisted bytes when the caller mutates during write', async () => {
const raw = iteration(
itemAt(createXtreamIterationDefinitions(false), 1),
1
);
const persistedPeakRss = raw.main.peakRssBytes;
const validated = await persist(raw, 2, () => {
Object.assign(raw.main, { peakRssBytes: persistedPeakRss + 1 });
});
assert.equal(validated.main.peakRssBytes, persistedPeakRss);
assert.notEqual(validated.main.peakRssBytes, raw.main.peakRssBytes);
assert.throws(
() => Object.assign(validated.main, { peakRssBytes: 1 }),
TypeError
);
});
it('blocks exact token and credential-shaped bytes before write but permits suite labels', async () => {
const raw = iteration(
itemAt(createXtreamIterationDefinitions(false), 1),
1
);
let writes = 0;
for (const leaked of [
TOKEN,
'performance:performance',
'http://performance:performance@127.0.0.1:43123',
'?username=performance&password=performance',
]) {
await assert.rejects(
() =>
persistWith(
{
...raw,
renderer: {
...raw.renderer,
consoleErrors: [leaked],
},
},
async () => {
writes += 1;
throw new Error('must not write');
}
),
/credential-safe/
);
}
assert.equal(writes, 0);
await assert.doesNotReject(() => persist(raw, 2));
});
it('requires exact clean formal source, runtime, CDP, and environment evidence', async () => {
const { diagnosticEvidence, iterations } = await formalReportFixture();
assert.doesNotThrow(() =>
createXtreamBenchmarkSummary(
MANIFEST,
iterations,
diagnosticEvidence
)
);
for (const invalid of [
{ ...MANIFEST, source: { ...MANIFEST.source, gitDirty: true } },
{
...MANIFEST,
environment: { ...MANIFEST.environment, cdpPort: 9223 },
},
{
...MANIFEST,
environment: {
...MANIFEST.environment,
perfWorkerProfiling: '0',
},
},
{
...MANIFEST,
runtime: { ...MANIFEST.runtime, electronVersion: '' },
},
{ ...MANIFEST, variant: { length: 1 } },
]) {
assert.throws(
() =>
createXtreamBenchmarkSummary(
invalid as unknown as XtreamBenchmarkManifest,
iterations,
diagnosticEvidence
),
/invalid Xtream benchmark manifest/
);
}
});
it('requires ordered definitions and unique process/profile/generation identity', async () => {
const { diagnosticEvidence, iterations } = await formalReportFixture();
const shuffled = [...iterations];
[shuffled[0], shuffled[1]] = [itemAt(shuffled, 1), itemAt(shuffled, 0)];
assert.throws(
() =>
createXtreamBenchmarkSummary(
MANIFEST,
shuffled,
diagnosticEvidence
),
/ordered Xtream benchmark schedule/
);
const reused = [...iterations];
const first = itemAt(reused, 0);
const second = itemAt(reused, 1);
reused[1] = {
...second,
processIdentity: first.processIdentity,
};
assert.throws(
() =>
createXtreamBenchmarkSummary(
MANIFEST,
reused,
diagnosticEvidence
),
/fresh process identity/
);
});
it('rejects forged validated objects and excludes diagnostic CPU profiles from headline metrics', async () => {
const { diagnosticEvidence, iterations } = await formalReportFixture();
const forged = [...iterations];
forged[0] = { ...itemAt(forged, 0) };
assert.throws(
() =>
createXtreamBenchmarkSummary(
MANIFEST,
forged,
diagnosticEvidence
),
/validated persistence evidence/
);
const summary = createXtreamBenchmarkSummary(
MANIFEST,
iterations,
diagnosticEvidence
);
const background = summary.scenarios.find(
({ scenarioId }) => scenarioId === 'xtream-background-ui'
);
const initial = summary.scenarios.find(
({ scenarioId }) => scenarioId === 'xtream-initial-import-large'
);
assert.ok(background);
assert.ok(initial);
assert.deepEqual(background.databaseWorkerRequestInvalidReasons, [
'overlapping-database-worker-requests',
]);
assert.equal(
background.metrics.databaseWorkerRequestInvalidSampleCount.min,
3
);
assert.equal(
background.metrics.databaseWorkerRequestInvalidSampleCount.max,
3
);
assert.deepEqual(initial.databaseWorkerRequestInvalidReasons, [
'overlapping-database-worker-requests',
]);
assert.equal(
initial.metrics.databaseWorkerRequestInvalidSampleCount.min,
0
);
assert.equal(
initial.metrics.databaseWorkerRequestInvalidSampleCount.max,
2
);
assert.ok(
summary.scenarios.every(
({
databaseWorkerEventLoopDelayMetricScope,
databaseWorkerRequestMetricScope,
databaseWorkerWholeWorkerMetricScope,
metrics,
}) =>
databaseWorkerEventLoopDelayMetricScope ===
'valid-request-window-proxy' &&
databaseWorkerRequestMetricScope ===
'valid-request-window-proxy' &&
databaseWorkerWholeWorkerMetricScope ===
'whole-worker-operation-window' &&
metrics.databaseWorkerRequestEventLoopDelayP95Ms.count === 5
)
);
assert.equal(summary.validForComparison, true);
assert.ok(Object.isFrozen(summary));
assert.ok(Object.isFrozen(summary.manifest));
assert.ok(Object.isFrozen(summary.iterations));
assert.ok(
Object.isFrozen(
itemAt(summary.iterations, 0).databaseWorker.requests.evidence
)
);
assert.notEqual(summary.manifest, MANIFEST);
assert.notEqual(summary.iterations, iterations);
assert.ok(
summary.scenarios.every(
({
diagnosticProfiles,
mainEventLoopUtilization,
measuredRuns,
metrics,
phases,
}) =>
measuredRuns === 5 &&
metrics.totalMs.count === 5 &&
diagnosticProfiles.mainDurationMicros !== null &&
diagnosticProfiles.artifactProvenance.artifacts.length ===
7 &&
Object.isFrozen(
diagnosticProfiles.artifactProvenance.artifacts
) &&
mainEventLoopUtilization.reason ===
'electron-main-embedded-event-loop' &&
mainEventLoopUtilization.value === null &&
phases.indexes.reason ===
'schema-indexes-pre-exist; operation-creates-none' &&
phases.restoreUserData.value === null &&
phases.structuredCloneAttribution ===
'selected-ipc-proxy-includes-queueing-and-scheduling' &&
!Object.prototype.hasOwnProperty.call(
metrics,
'mainCpuProfileDurationMicros'
)
)
);
assert.equal(
initial.phases.restoreUserData.reason,
'not-invoked-by-scenario'
);
assert.equal(background.phases.restoreUserData.reason, 'no-user-data');
});
it('requires branded one-to-one diagnostic evidence bound to each iteration directory', async () => {
const { diagnosticEvidence, iterations } = await formalReportFixture();
const entries = [...diagnosticEvidence.entries()];
const first = itemAt(entries, 0);
const second = itemAt(entries, 1);
const missing = new Map(entries.slice(1));
const swapped = new Map(entries);
swapped.set(first[0], second[1]);
swapped.set(second[0], first[1]);
const extra = new Map(entries);
extra.set(itemAt(iterations, 0), first[1]);
const forged = new Map(entries);
forged.set(first[0], structuredClone(first[1]));
const malformed = new Map(entries);
malformed.set(first[0], null as unknown as (typeof entries)[number][1]);
for (const evidence of [missing, swapped, extra, forged, malformed]) {
assert.throws(
() =>
createXtreamBenchmarkSummary(
MANIFEST,
iterations,
evidence
),
/diagnostic artifact evidence/
);
}
});
it('keeps one-run smoke output ineligible after all clean gates pass', async () => {
const { diagnosticEvidence, iterations } = await smokeReportFixture();
const summary = createXtreamBenchmarkSummary(
{ ...MANIFEST, mode: 'smoke' },
iterations,
diagnosticEvidence
);
assert.equal(summary.validForComparison, false);
});
});
function itemAt<T>(items: readonly T[], index: number): T {
const item = items[index];
assert.ok(item);
return item;
}
@@ -0,0 +1,387 @@
import {
createXtreamIterationDefinitions,
listXtreamBenchmarkScenarios,
summarizeXtreamNumbers,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import {
serializeXtreamArtifactForPersistence,
type XtreamDiagnosticArtifactEvidence,
} from './xtream-diagnostic-artifacts';
import {
bindXtreamDiagnosticEvidence,
cloneXtreamSummaryValue,
copyXtreamDiagnosticProvenance,
} from './xtream-benchmark-summary-evidence';
import {
assertFreshXtreamProcessIdentities,
assertOrderedXtreamSchedule,
freezeDeep,
isFiniteNonNegative,
parseXtreamBenchmarkManifest,
snapshotXtreamIterations,
toXtreamRawIteration,
} from './xtream-exact-schema';
import { assertXtreamIterationResult } from './xtream-iteration-validity';
import { assertUniqueXtreamPersistencePaths } from './xtream-persistence-schedule';
import { verifyXtreamPersistenceReceipt } from './xtream-raw-persistence-receipt';
import {
XTREAM_NOT_APPLICABLE,
XTREAM_RENDERER_VISIBILITY,
XTREAM_STRUCTURED_CLONE_ATTRIBUTION,
XTREAM_WORKER_REQUEST_METRIC_SCOPE,
XTREAM_WORKER_WHOLE_METRIC_SCOPE,
type NumericDistribution,
type XtreamArtifactSafetyContext,
type XtreamBenchmarkManifest,
type XtreamBenchmarkSummary,
type XtreamPersistedRawEvidence,
type XtreamPersistenceReceipt,
type XtreamRawIterationResult,
type XtreamScenarioMetrics,
type XtreamScenarioSummary,
type XtreamValidatedIterationResult,
} from './xtream-summary-contract';
const VALIDATED = new WeakSet<object>();
export async function persistThenValidateXtreamIteration(
raw: XtreamRawIterationResult,
safety: XtreamArtifactSafetyContext,
persistRaw: (serialized: string) => Promise<XtreamPersistenceReceipt>
): Promise<XtreamValidatedIterationResult> {
const serialized = serializeXtreamArtifactForPersistence(raw, safety);
const receipt = await persistRaw(serialized);
const evidence = await verifyXtreamPersistenceReceipt(serialized, receipt);
const persisted: unknown = JSON.parse(serialized);
assertXtreamIterationResult(persisted);
return brandValidatedIteration(persisted, evidence);
}
export function createXtreamBenchmarkSummary(
manifest: XtreamBenchmarkManifest,
iterations: readonly XtreamValidatedIterationResult[],
diagnosticEvidence: ReadonlyMap<
XtreamValidatedIterationResult,
XtreamDiagnosticArtifactEvidence
>
): XtreamBenchmarkSummary {
const canonicalManifest = parseXtreamBenchmarkManifest(manifest);
const expected = createXtreamIterationDefinitions(
canonicalManifest.mode === 'smoke'
);
const canonicalIterations = snapshotXtreamIterations(iterations);
assertOrderedXtreamSchedule(
canonicalIterations,
expected,
canonicalManifest.mode
);
assertFreshXtreamProcessIdentities(canonicalIterations);
for (const iteration of canonicalIterations) {
assertValidatedIteration(iteration);
if (iteration.validationStatus !== 'valid') invalidIteration();
assertXtreamIterationResult(toXtreamRawIteration(iteration));
}
assertUniqueXtreamPersistencePaths(canonicalIterations);
const boundDiagnosticEvidence = bindXtreamDiagnosticEvidence(
canonicalIterations,
diagnosticEvidence
);
const measuredRunCount = canonicalManifest.mode === 'formal' ? 5 : 1;
const comparable =
canonicalManifest.mode === 'formal' &&
canonicalIterations
.filter(({ kind }) => kind === 'measured')
.every(({ eligibleForComparison }) => eligibleForComparison);
return freezeDeep({
iterations: cloneXtreamSummaryValue(canonicalIterations),
manifest: cloneXtreamSummaryValue(canonicalManifest),
scenarios: listXtreamBenchmarkScenarios().map(({ id }) =>
summarizeScenario(
canonicalIterations,
id,
measuredRunCount,
boundDiagnosticEvidence
)
),
validForComparison: comparable,
});
}
function summarizeScenario(
iterations: readonly XtreamValidatedIterationResult[],
scenarioId: XtreamScenarioId,
measuredRunCount: number,
diagnosticEvidence: ReadonlyMap<
XtreamValidatedIterationResult,
XtreamDiagnosticArtifactEvidence
>
): XtreamScenarioSummary {
const measured = iterations.filter(
(iteration) =>
iteration.scenarioId === scenarioId && iteration.kind === 'measured'
);
const diagnostic = iterations.find(
(iteration) =>
iteration.scenarioId === scenarioId &&
iteration.kind === 'diagnostic'
);
if (measured.length !== measuredRunCount || !diagnostic) {
scheduleError(measuredRunCount === 5 ? 'formal' : 'smoke');
}
const provenance = diagnosticEvidence.get(diagnostic);
if (!provenance) invalidIteration();
const restores =
scenarioId === 'xtream-refresh-large' ||
scenarioId === 'xtream-background-ui';
return {
scenarioId,
measuredRuns: measuredRunCount,
databaseWorkerEventLoopDelayMetricScope:
XTREAM_WORKER_REQUEST_METRIC_SCOPE.VALID_REQUEST_WINDOW_PROXY,
databaseWorkerRequestInvalidReasons: [
...new Set(
measured.flatMap((run) =>
run.databaseWorker.requests.invalidReasons.map(
({ reason }) => reason
)
)
),
],
databaseWorkerRequestMetricScope:
XTREAM_WORKER_REQUEST_METRIC_SCOPE.VALID_REQUEST_WINDOW_PROXY,
databaseWorkerWholeWorkerMetricScope:
XTREAM_WORKER_WHOLE_METRIC_SCOPE.OPERATION_WINDOW,
dashboardPaintVisibility:
scenarioId === 'xtream-background-ui'
? XTREAM_RENDERER_VISIBILITY.VISIBLE_WITHOUT_OVERLAY
: null,
diagnosticProfiles: {
artifactProvenance: copyXtreamDiagnosticProvenance(provenance),
databaseWorkerDurationMicros:
provenance.profiles.databaseWorker.durationMicros,
mainDurationMicros: provenance.profiles.main.durationMicros,
rendererDurationMicros: provenance.profiles.renderer.durationMicros,
},
metrics: summarizeMetrics(measured, scenarioId, measuredRunCount),
memory: {
databaseWorkerRss: notApplicable(
XTREAM_NOT_APPLICABLE.DATABASE_WORKER_RSS
),
nativeAndSqlite: notApplicable(
XTREAM_NOT_APPLICABLE.NATIVE_SQLITE_MEMORY
),
playlistRefreshWorker: notApplicable(
XTREAM_NOT_APPLICABLE.PLAYLIST_REFRESH_WORKER
),
},
mainEventLoopUtilization: notApplicable(
XTREAM_NOT_APPLICABLE.MAIN_EVENT_LOOP_UTILIZATION
),
phases: {
debugCopy: notApplicable(XTREAM_NOT_APPLICABLE.DEBUG_COPY),
indexes: notApplicable(XTREAM_NOT_APPLICABLE.INDEXES_PRE_EXIST),
transactionCommit: notApplicable(
XTREAM_NOT_APPLICABLE.COMMIT_INCLUDED_IN_SQLITE_WRITE
),
restoreUserData: notApplicable(
restores
? XTREAM_NOT_APPLICABLE.RESTORE_NO_USER_DATA
: XTREAM_NOT_APPLICABLE.RESTORE_NOT_INVOKED
),
backgroundSearchMarker:
scenarioId === 'xtream-background-ui'
? notApplicable(XTREAM_NOT_APPLICABLE.SOURCES_SEARCH_MARKER)
: null,
structuredCloneAttribution:
XTREAM_STRUCTURED_CLONE_ATTRIBUTION.SELECTED_IPC_PROXY,
},
rendererLongTaskCountTotal: sumValues(
measured,
(run) => run.renderer.longTaskCount
),
responsiveEventsTotal: sumValues(
measured,
(run) => run.main.responsiveEvents
),
unresponsiveEventsTotal: sumValues(
measured,
(run) => run.main.unresponsiveEvents
),
};
}
function summarizeMetrics(
runs: readonly XtreamValidatedIterationResult[],
scenarioId: XtreamScenarioId,
count: number
): XtreamScenarioMetrics {
const metric = (
select: (run: XtreamValidatedIterationResult) => number
): NumericDistribution => distribution(runs, select, count);
const optional = (
select: (run: XtreamValidatedIterationResult) => number | null
): NumericDistribution =>
distribution(runs, (run) => requireNumber(select(run)), count);
return {
totalMs: metric((run) => run.phases.totalMs),
dataAcquisitionMs: metric((run) => run.phases.dataAcquisitionMs),
jsonParsingMs: metric((run) => run.phases.jsonParsingMs),
normalizationMs: metric((run) => run.phases.normalizationMs),
serializationMs: metric((run) => run.phases.serializationMs),
deserializationMs: metric((run) => run.phases.deserializationMs),
structuredCloneProxyMs: metric(
(run) => run.phases.structuredCloneProxyMs
),
sqliteReadMs: metric((run) => run.phases.sqliteReadMs),
sqliteWriteMs: metric((run) => run.phases.sqliteWriteMs),
storeUpdateMs: metric((run) => run.phases.storeUpdateMs),
angularRenderingMs: metric((run) => run.phases.angularRenderingMs),
rendererPeakRssBytes: metric((run) => run.renderer.peakRssBytes),
rendererPeakHeapBytes: metric((run) => run.renderer.peakHeapUsedBytes),
rendererPostGcHeapBytes: metric(
(run) => run.renderer.postGcHeapUsedBytes
),
rendererLongTaskCount: metric((run) => run.renderer.longTaskCount),
rendererLongTaskMaxMs: metric((run) => run.renderer.longTaskMaxMs),
rendererFrameGapP95Ms: metric((run) => run.renderer.frameGapP95Ms),
rendererFrameGapMaxMs: metric((run) => run.renderer.frameGapMaxMs),
rendererHeartbeatP95Ms: metric((run) => run.renderer.heartbeatP95Ms),
rendererHeartbeatMaxMs: metric((run) => run.renderer.heartbeatMaxMs),
rendererNavigationLatencyMs:
scenarioId === 'xtream-background-ui'
? optional((run) => run.renderer.navigationLatencyMs)
: null,
rendererSearchLatencyMs:
scenarioId === 'xtream-background-ui'
? optional((run) => run.renderer.searchLatencyMs)
: null,
rendererActionLatencyMs:
scenarioId === 'xtream-background-ui'
? optional((run) => run.renderer.actionLatencyMs)
: null,
mainCpuUserMicros: metric((run) => run.main.cpuUserMicros),
mainCpuSystemMicros: metric((run) => run.main.cpuSystemMicros),
mainPeakRssBytes: metric((run) => run.main.peakRssBytes),
mainPeakHeapBytes: metric((run) => run.main.peakHeapUsedBytes),
mainPostGcHeapBytes: metric((run) => run.main.postGcHeapUsedBytes),
mainEventLoopDelayP95Ms: metric((run) => run.main.eventLoopDelayP95Ms),
mainEventLoopDelayP99Ms: metric((run) => run.main.eventLoopDelayP99Ms),
mainEventLoopDelayMaxMs: metric((run) => run.main.eventLoopDelayMaxMs),
databaseWorkerCpuUserMicros: metric(
(run) => run.databaseWorker.cpuUserMicros
),
databaseWorkerCpuSystemMicros: metric(
(run) => run.databaseWorker.cpuSystemMicros
),
databaseWorkerPeakHeapBytes: metric(
(run) => run.databaseWorker.peakHeapUsedBytes
),
databaseWorkerPostGcHeapBytes: metric(
(run) => run.databaseWorker.postGcHeapUsedBytes
),
databaseWorkerRequestTotalCount: metric(
(run) => run.databaseWorker.requests.totalCount
),
databaseWorkerRequestValidSampleCount: metric(
(run) => run.databaseWorker.requests.validSampleCount
),
databaseWorkerRequestInvalidSampleCount: metric(
(run) => run.databaseWorker.requests.invalidSampleCount
),
databaseWorkerRequestEventLoopDelayP95Ms: metric(
(run) => run.databaseWorker.requests.eventLoopDelayP95Ms
),
databaseWorkerRequestEventLoopDelayP99Ms: metric(
(run) => run.databaseWorker.requests.eventLoopDelayP99Ms
),
databaseWorkerRequestEventLoopDelayMaxMs: metric(
(run) => run.databaseWorker.requests.eventLoopDelayMaxMs
),
databaseWorkerRequestEventLoopUtilization: metric(
(run) => run.databaseWorker.requests.eventLoopUtilization
),
databaseWorkerPeakExternalBytes: metric(
(run) => run.databaseWorker.peakExternalBytes
),
databaseWorkerEventLoopDelayP95Ms: metric(
(run) => run.databaseWorker.eventLoopDelayP95Ms
),
databaseWorkerEventLoopDelayP99Ms: metric(
(run) => run.databaseWorker.eventLoopDelayP99Ms
),
databaseWorkerEventLoopDelayMaxMs: metric(
(run) => run.databaseWorker.eventLoopDelayMaxMs
),
databaseWorkerEventLoopUtilization: metric(
(run) => run.databaseWorker.eventLoopUtilization
),
cancelAcknowledgementLatencyMs:
scenarioId === 'xtream-cancel-import'
? optional((run) => run.cancellation.acknowledgementLatencyMs)
: null,
};
}
function distribution(
runs: readonly XtreamValidatedIterationResult[],
select: (run: XtreamValidatedIterationResult) => number,
expectedCount: number
): NumericDistribution {
const values = runs.map(select);
if (
values.length !== expectedCount ||
values.some((value) => !isFiniteNonNegative(value))
) {
throw new Error(
'Xtream metric requires complete finite measured values'
);
}
return summarizeXtreamNumbers(values);
}
function sumValues(
runs: readonly XtreamValidatedIterationResult[],
select: (run: XtreamValidatedIterationResult) => number
): number {
return runs.reduce((total, run) => total + select(run), 0);
}
function requireNumber(value: number | null): number {
if (!isFiniteNonNegative(value)) invalidIteration();
return value;
}
function notApplicable(reason: string): { reason: string; value: null } {
return { reason, value: null };
}
function brandValidatedIteration(
raw: XtreamRawIterationResult,
persistence: XtreamPersistedRawEvidence
): XtreamValidatedIterationResult {
const result = freezeDeep({
...raw,
persistence,
validationStatus: 'valid' as const,
});
VALIDATED.add(result);
return result;
}
function assertValidatedIteration(value: XtreamValidatedIterationResult): void {
if (!VALIDATED.has(value)) {
throw new Error('Xtream validated persistence evidence is missing');
}
}
function scheduleError(mode: 'formal' | 'smoke'): never {
throw new Error(
`Xtream benchmark requires exactly ${mode === 'formal' ? 'five' : 'one'} measured runs per scenario`
);
}
function invalidIteration(): never {
throw new Error('invalid Xtream iteration');
}
@@ -0,0 +1,52 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_SCENARIO_ID,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import {
deriveXtreamMeasuredPlaylistId,
xtreamScenarioRequiresSeed,
} from './xtream-benchmark-runtime';
describe('Xtream benchmark runtime evidence', () => {
it('seeds only scenarios that measure an operation on an existing portal', () => {
const expected: Record<XtreamScenarioId, boolean> = {
[XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE]: false,
[XTREAM_SCENARIO_ID.REFRESH_LARGE]: true,
[XTREAM_SCENARIO_ID.DELETE_LARGE]: true,
[XTREAM_SCENARIO_ID.CANCEL_IMPORT]: false,
[XTREAM_SCENARIO_ID.BACKGROUND_UI]: true,
};
for (const scenarioId of Object.values(XTREAM_SCENARIO_ID)) {
assert.equal(
xtreamScenarioRequiresSeed(scenarioId),
expected[scenarioId]
);
}
});
it('derives exactly one non-null measured playlist identity', () => {
assert.equal(
deriveXtreamMeasuredPlaylistId([
{ playlistId: null },
{ playlistId: 'playlist-1' },
{ playlistId: 'playlist-1' },
]),
'playlist-1'
);
for (const requests of [
[{ playlistId: null }],
[{ playlistId: 'playlist-1' }, { playlistId: 'playlist-2' }],
[{ playlistId: '' }],
]) {
assert.throws(
() => deriveXtreamMeasuredPlaylistId(requests),
/xtream-measured-playlist-identity-invalid/
);
}
});
});
@@ -0,0 +1,52 @@
import type { Page } from '@playwright/test';
import {
XTREAM_SCENARIO_ID,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
export function xtreamScenarioRequiresSeed(
scenarioId: XtreamScenarioId
): boolean {
return (
scenarioId === XTREAM_SCENARIO_ID.REFRESH_LARGE ||
scenarioId === XTREAM_SCENARIO_ID.DELETE_LARGE ||
scenarioId === XTREAM_SCENARIO_ID.BACKGROUND_UI
);
}
export function deriveXtreamMeasuredPlaylistId(
requests: readonly { readonly playlistId: string | null }[]
): string {
const identities = new Set(
requests
.map(({ playlistId }) => playlistId)
.filter(
(playlistId): playlistId is string =>
typeof playlistId === 'string' && playlistId.length > 0
)
);
const playlistId = identities.values().next().value as string | undefined;
if (identities.size !== 1 || !playlistId) {
throw new Error('xtream-measured-playlist-identity-invalid');
}
return playlistId;
}
export async function disableGenericElectronFixtureProbes(
page: Page
): Promise<void> {
await page.evaluate(() => {
window.__portalDebugUnsubscribe?.();
window.__portalDebugUnsubscribe = undefined;
window.__portalDebugEvents = [];
window.__dbOperationUnsubscribe?.();
window.__dbOperationUnsubscribe = undefined;
window.__dbOperationEvents = [];
if (window.__rendererFrameRequestId) {
window.cancelAnimationFrame(window.__rendererFrameRequestId);
}
window.__rendererFrameRequestId = undefined;
window.__rendererFrameCount = 0;
});
}
@@ -0,0 +1,112 @@
import {
assertXtreamDiagnosticArtifactEvidence,
type XtreamDiagnosticArtifactEvidence,
} from './xtream-diagnostic-artifacts';
import type {
XtreamDiagnosticArtifactProvenance,
XtreamValidatedIterationResult,
} from './xtream-summary-contract';
export function bindXtreamDiagnosticEvidence(
iterations: readonly XtreamValidatedIterationResult[],
evidenceByIteration: ReadonlyMap<
XtreamValidatedIterationResult,
XtreamDiagnosticArtifactEvidence
>
): ReadonlyMap<
XtreamValidatedIterationResult,
XtreamDiagnosticArtifactEvidence
> {
const diagnostic = iterations.filter(({ kind }) => kind === 'diagnostic');
const evidenceEntries = snapshotEvidenceEntries(evidenceByIteration);
if (evidenceEntries.length !== diagnostic.length) {
invalidEvidence();
}
const diagnosticSet = new Set(diagnostic);
const boundEvidence = new Map<
XtreamValidatedIterationResult,
XtreamDiagnosticArtifactEvidence
>();
for (const [iteration, evidence] of evidenceEntries) {
if (!diagnosticSet.has(iteration)) {
invalidEvidence();
}
try {
assertXtreamDiagnosticArtifactEvidence(evidence);
} catch {
invalidEvidence();
}
if (
iteration.processIdentity.profileDirectorySha256 !==
evidence.directorySha256 ||
iteration.renderer.cpuProfileDurationMicros !==
evidence.profiles.renderer.durationMicros ||
iteration.main.cpuProfileDurationMicros !==
evidence.profiles.main.durationMicros ||
iteration.databaseWorker.cpuProfileDurationMicros !==
evidence.profiles.databaseWorker.durationMicros ||
iteration.databaseWorker.ordinal !==
evidence.profiles.databaseWorker.ordinal
) {
invalidEvidence();
}
Map.prototype.set.call(boundEvidence, iteration, evidence);
}
if (
diagnostic.some(
(iteration) => !Map.prototype.has.call(boundEvidence, iteration)
)
) {
invalidEvidence();
}
return boundEvidence;
}
export function copyXtreamDiagnosticProvenance(
evidence: XtreamDiagnosticArtifactEvidence
): XtreamDiagnosticArtifactProvenance {
assertXtreamDiagnosticArtifactEvidence(evidence);
return {
artifacts: evidence.artifacts.map((artifact) => ({ ...artifact })),
directorySha256: evidence.directorySha256,
};
}
export function cloneXtreamSummaryValue<T>(value: T): T {
return structuredClone(value);
}
function snapshotEvidenceEntries(
value: ReadonlyMap<
XtreamValidatedIterationResult,
XtreamDiagnosticArtifactEvidence
>
): readonly (readonly [
XtreamValidatedIterationResult,
XtreamDiagnosticArtifactEvidence,
])[] {
try {
if (!(value instanceof Map)) invalidEvidence();
const sizeGetter = Object.getOwnPropertyDescriptor(
Map.prototype,
'size'
)?.get;
if (!sizeGetter) invalidEvidence();
const size = Reflect.apply(sizeGetter, value, []) as unknown;
const entries: [
XtreamValidatedIterationResult,
XtreamDiagnosticArtifactEvidence,
][] = [];
Map.prototype.forEach.call(value, (evidence, iteration) => {
entries.push([iteration, evidence]);
});
if (size !== entries.length) invalidEvidence();
return entries;
} catch {
invalidEvidence();
}
}
function invalidEvidence(): never {
throw new Error('invalid Xtream diagnostic artifact evidence binding');
}
@@ -0,0 +1,214 @@
import {
computeXtreamBuildFilesAggregate,
type XtreamBenchmarkBuildIdentity,
type XtreamBuildFileIdentity,
type XtreamBuildPairIdentity,
} from './xtream-build-identity';
const SHA256 = /^[a-f0-9]{64}$/u;
const RENDERER_FILE =
/^dist\/apps\/web\/[A-Za-z0-9][A-Za-z0-9._-]{0,254}\.js(?:\.map)?$/u;
const BUILD_KEYS = ['electron', 'renderer'] as const;
const ELECTRON_KEYS = [
'databaseWorker',
'main',
'playlistRefreshWorker',
'preload',
] as const;
const PAIR_KEYS = ['javascript', 'sourceMap'] as const;
const FILE_KEYS = ['bytes', 'path', 'sha256'] as const;
const RENDERER_KEYS = [
'aggregateSha256',
'bytes',
'executableJavaScriptCount',
'files',
'sourceMapCount',
] as const;
const ELECTRON_PATHS = {
databaseWorker: 'dist/apps/electron-backend/workers/database.worker.js',
main: 'dist/apps/electron-backend/main.js',
playlistRefreshWorker:
'dist/apps/electron-backend/workers/playlist-refresh.worker.js',
preload: 'dist/apps/electron-backend/main.preload.js',
} as const;
export function parseXtreamBenchmarkBuildIdentity(
value: unknown
): XtreamBenchmarkBuildIdentity {
try {
const input = exactRecord(value, BUILD_KEYS);
const electronInput = exactRecord(input['electron'], ELECTRON_KEYS);
const rendererInput = exactRecord(input['renderer'], RENDERER_KEYS);
const electron = Object.freeze({
databaseWorker: pair(
electronInput['databaseWorker'],
ELECTRON_PATHS.databaseWorker
),
main: pair(electronInput['main'], ELECTRON_PATHS.main),
playlistRefreshWorker: pair(
electronInput['playlistRefreshWorker'],
ELECTRON_PATHS.playlistRefreshWorker
),
preload: pair(electronInput['preload'], ELECTRON_PATHS.preload),
});
const renderer = rendererIdentity(rendererInput);
return Object.freeze({ electron, renderer });
} catch {
throw new Error('invalid Xtream benchmark build identity');
}
}
function pair(value: unknown, javascriptPath: string): XtreamBuildPairIdentity {
const input = exactRecord(value, PAIR_KEYS);
return Object.freeze({
javascript: fileIdentity(input['javascript'], javascriptPath),
sourceMap: fileIdentity(input['sourceMap'], `${javascriptPath}.map`),
});
}
function rendererIdentity(
input: Record<string, unknown>
): XtreamBenchmarkBuildIdentity['renderer'] {
const files = exactArray(input['files']).map((value) =>
fileIdentity(value)
);
if (
files.length < 3 ||
files.length > 10_000 ||
!isStrictlySorted(files.map((file) => file.path))
) {
invalid();
}
const indexFiles = files.filter(
(file) => file.path === 'dist/apps/web/index.html'
);
const javascript = files.filter((file) => file.path.endsWith('.js'));
const sourceMaps = files.filter((file) => file.path.endsWith('.js.map'));
if (
indexFiles.length !== 1 ||
javascript.length === 0 ||
files.length !== 1 + javascript.length + sourceMaps.length ||
javascript.length !== sourceMaps.length ||
javascript.some(
(file) =>
!sourceMaps.some(
(sourceMap) => sourceMap.path === `${file.path}.map`
)
) ||
sourceMaps.some(
(sourceMap) =>
!javascript.some(
(file) => file.path === sourceMap.path.slice(0, -4)
)
)
) {
invalid();
}
const bytes = files.reduce((total, file) => total + file.bytes, 0);
if (
!isPositiveSafeInteger(input['bytes']) ||
input['bytes'] !== bytes ||
input['executableJavaScriptCount'] !== javascript.length ||
input['sourceMapCount'] !== sourceMaps.length ||
typeof input['aggregateSha256'] !== 'string' ||
!SHA256.test(input['aggregateSha256']) ||
input['aggregateSha256'] !== computeXtreamBuildFilesAggregate(files)
) {
invalid();
}
return Object.freeze({
aggregateSha256: input['aggregateSha256'],
bytes,
executableJavaScriptCount: javascript.length,
files: Object.freeze(files),
sourceMapCount: sourceMaps.length,
}) as XtreamBenchmarkBuildIdentity['renderer'];
}
function fileIdentity(
value: unknown,
expectedPath?: string
): XtreamBuildFileIdentity {
const input = exactRecord(value, FILE_KEYS);
const path = input['path'];
const validRendererPath =
path === 'dist/apps/web/index.html' ||
(typeof path === 'string' && RENDERER_FILE.test(path));
if (
!isPositiveSafeInteger(input['bytes']) ||
typeof path !== 'string' ||
(expectedPath === undefined
? !validRendererPath
: path !== expectedPath) ||
typeof input['sha256'] !== 'string' ||
!SHA256.test(input['sha256'])
) {
invalid();
}
return Object.freeze({
bytes: input['bytes'],
path,
sha256: input['sha256'],
}) as XtreamBuildFileIdentity;
}
function exactArray(value: unknown): unknown[] {
if (!Array.isArray(value)) invalid();
const length = Reflect.get(value, 'length') as unknown;
if (
!Number.isSafeInteger(length) ||
Number(length) < 0 ||
Number(length) > 10_000
) {
invalid();
}
const expectedKeys = new Set([
'length',
...Array.from({ length: Number(length) }, (_, index) => String(index)),
]);
const keys = Reflect.ownKeys(value);
if (
keys.length !== expectedKeys.size ||
keys.some((key) => typeof key !== 'string' || !expectedKeys.has(key))
) {
invalid();
}
return Array.from({ length: Number(length) }, (_, index) =>
Reflect.get(value, String(index))
);
}
function exactRecord(
value: unknown,
expectedKeys: readonly string[]
): Record<string, unknown> {
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
invalid();
}
const keys = Reflect.ownKeys(value);
if (
keys.length !== expectedKeys.length ||
keys.some(
(key) => typeof key !== 'string' || !expectedKeys.includes(key)
)
) {
invalid();
}
return Object.fromEntries(
expectedKeys.map((key) => [key, Reflect.get(value, key)])
);
}
function isStrictlySorted(values: readonly string[]): boolean {
return values.every(
(value, index) => index === 0 || (values[index - 1] ?? '') < value
);
}
function isPositiveSafeInteger(value: unknown): value is number {
return Number.isSafeInteger(value) && Number(value) > 0;
}
function invalid(): never {
throw new Error('invalid');
}
@@ -0,0 +1,246 @@
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import {
link,
mkdir,
mkdtemp,
rm,
symlink,
unlink,
writeFile,
} from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, describe, it } from 'node:test';
import {
captureXtreamBuildIdentity,
computeXtreamBuildFilesAggregate,
} from './xtream-build-identity';
import { assertXtreamBenchmarkManifest } from './xtream-exact-schema';
import { BUILD_IDENTITY, MANIFEST } from './xtream-benchmark-report.fixtures';
const directories: string[] = [];
afterEach(async () => {
await Promise.all(
directories
.splice(0)
.map((directory) => rm(directory, { force: true, recursive: true }))
);
});
describe('Xtream benchmark build identity', () => {
it('hashes exact Electron pairs and sorted top-level renderer code', async () => {
const root = await buildFixture();
const identity = await captureXtreamBuildIdentity(root);
assert.deepEqual(identity.electron.main.javascript, {
bytes: 4,
path: 'dist/apps/electron-backend/main.js',
sha256: sha256('main'),
});
assert.deepEqual(identity.electron.preload.sourceMap, {
bytes: 11,
path: 'dist/apps/electron-backend/main.preload.js.map',
sha256: sha256('preload-map'),
});
assert.deepEqual(
identity.renderer.files.map((file) => file.path),
[
'dist/apps/web/chunk-A.js',
'dist/apps/web/chunk-A.js.map',
'dist/apps/web/index.html',
'dist/apps/web/main-A.js',
'dist/apps/web/main-A.js.map',
]
);
assert.equal(identity.renderer.executableJavaScriptCount, 2);
assert.equal(identity.renderer.sourceMapCount, 2);
assert.equal(
identity.renderer.bytes,
identity.renderer.files.reduce(
(total, file) => total + file.bytes,
0
)
);
assert.equal(
identity.renderer.aggregateSha256,
computeXtreamBuildFilesAggregate(identity.renderer.files)
);
assert.equal(
identity.renderer.files.some((file) =>
file.path.includes('app-config.js')
),
false
);
});
it('fails closed when an executable or its source map is missing', async () => {
const missingElectron = await buildFixture();
await unlink(
join(
missingElectron,
'dist/apps/electron-backend/workers/database.worker.js.map'
)
);
await assert.rejects(
captureXtreamBuildIdentity(missingElectron),
/invalid Xtream performance build/
);
const missingRendererMap = await buildFixture();
await unlink(join(missingRendererMap, 'dist/apps/web/chunk-A.js.map'));
await assert.rejects(
captureXtreamBuildIdentity(missingRendererMap),
/invalid Xtream performance build/
);
const orphanRendererMap = await buildFixture();
await writeFile(
join(orphanRendererMap, 'dist/apps/web/orphan.js.map'),
'orphan'
);
await assert.rejects(
captureXtreamBuildIdentity(orphanRendererMap),
/invalid Xtream performance build/
);
});
it('rejects symlinked and hard-linked build evidence', async () => {
const symlinkRoot = await buildFixture();
const mainPath = join(
symlinkRoot,
'dist/apps/electron-backend/main.js'
);
const external = join(symlinkRoot, 'external-main.js');
await writeFile(external, 'main');
await unlink(mainPath);
await symlink(external, mainPath);
await assert.rejects(
captureXtreamBuildIdentity(symlinkRoot),
/invalid Xtream performance build/
);
const hardLinkRoot = await buildFixture();
await link(
join(hardLinkRoot, 'dist/apps/web/main-A.js'),
join(hardLinkRoot, 'main-alias.js')
);
await assert.rejects(
captureXtreamBuildIdentity(hardLinkRoot),
/invalid Xtream performance build/
);
});
it('produces a different aggregate for path, byte, or hash drift', () => {
const files = [
{ bytes: 1, path: 'a.js', sha256: 'a'.repeat(64) },
{ bytes: 2, path: 'a.js.map', sha256: 'b'.repeat(64) },
];
const baseline = computeXtreamBuildFilesAggregate(files);
for (const changed of [
[{ ...files[0], path: 'b.js' }, files[1]],
[{ ...files[0], bytes: 2 }, files[1]],
[{ ...files[0], sha256: 'c'.repeat(64) }, files[1]],
]) {
assert.notEqual(
computeXtreamBuildFilesAggregate(changed),
baseline
);
}
});
it('binds exact build descriptors into the persisted benchmark manifest', () => {
assert.doesNotThrow(() => assertXtreamBenchmarkManifest(MANIFEST));
const files = BUILD_IDENTITY.renderer.files;
const invalidBuilds = [
{
...BUILD_IDENTITY,
renderer: {
...BUILD_IDENTITY.renderer,
aggregateSha256: 'f'.repeat(64),
},
},
{
...BUILD_IDENTITY,
renderer: {
...BUILD_IDENTITY.renderer,
bytes: BUILD_IDENTITY.renderer.bytes + 1,
},
},
{
...BUILD_IDENTITY,
renderer: {
...BUILD_IDENTITY.renderer,
files: [...files].reverse(),
},
},
{
...BUILD_IDENTITY,
renderer: {
...BUILD_IDENTITY.renderer,
files: files.slice(0, -1),
},
},
{
...BUILD_IDENTITY,
electron: {
...BUILD_IDENTITY.electron,
main: {
...BUILD_IDENTITY.electron.main,
javascript: {
...BUILD_IDENTITY.electron.main.javascript,
path: 'dist/apps/electron-backend/other.js',
},
},
},
},
];
for (const build of invalidBuilds) {
assert.throws(
() => assertXtreamBenchmarkManifest({ ...MANIFEST, build }),
/invalid Xtream benchmark manifest/
);
}
});
});
async function buildFixture(): Promise<string> {
const root = await mkdtemp(join(tmpdir(), 'iptvnator-xtream-build-'));
directories.push(root);
const backend = join(root, 'dist/apps/electron-backend');
const workers = join(backend, 'workers');
const renderer = join(root, 'dist/apps/web');
await Promise.all([
mkdir(workers, { recursive: true }),
mkdir(join(renderer, 'assets'), { recursive: true }),
]);
await Promise.all([
writeFile(join(backend, 'main.js'), 'main'),
writeFile(join(backend, 'main.js.map'), 'main-map'),
writeFile(join(backend, 'main.preload.js'), 'preload'),
writeFile(join(backend, 'main.preload.js.map'), 'preload-map'),
writeFile(join(workers, 'database.worker.js'), 'database'),
writeFile(join(workers, 'database.worker.js.map'), 'database-map'),
writeFile(join(workers, 'playlist-refresh.worker.js'), 'refresh'),
writeFile(
join(workers, 'playlist-refresh.worker.js.map'),
'refresh-map'
),
writeFile(join(renderer, 'index.html'), '<app-root/>'),
writeFile(join(renderer, 'main-A.js'), 'renderer-main'),
writeFile(join(renderer, 'main-A.js.map'), 'renderer-main-map'),
writeFile(join(renderer, 'chunk-A.js'), 'renderer-chunk'),
writeFile(join(renderer, 'chunk-A.js.map'), 'renderer-chunk-map'),
writeFile(join(renderer, 'styles.css'), 'ignored'),
writeFile(join(renderer, 'assets/app-config.js'), 'ignored'),
]);
return root;
}
function sha256(value: string): string {
return createHash('sha256').update(value).digest('hex');
}
@@ -0,0 +1,202 @@
import { createHash } from 'node:crypto';
import { readdir } from 'node:fs/promises';
import { isAbsolute, join } from 'node:path';
import { readXtreamSafeRegularFile } from './xtream-safe-file-read';
export interface XtreamBuildFileIdentity {
readonly bytes: number;
readonly path: string;
readonly sha256: string;
}
export interface XtreamBuildPairIdentity {
readonly javascript: XtreamBuildFileIdentity;
readonly sourceMap: XtreamBuildFileIdentity;
}
export interface XtreamBenchmarkBuildIdentity {
readonly electron: {
readonly databaseWorker: XtreamBuildPairIdentity;
readonly main: XtreamBuildPairIdentity;
readonly playlistRefreshWorker: XtreamBuildPairIdentity;
readonly preload: XtreamBuildPairIdentity;
};
readonly renderer: {
readonly aggregateSha256: string;
readonly bytes: number;
readonly executableJavaScriptCount: number;
readonly files: readonly XtreamBuildFileIdentity[];
readonly sourceMapCount: number;
};
}
const BACKEND_ROOT = 'dist/apps/electron-backend';
const RENDERER_ROOT = 'dist/apps/web';
const ELECTRON_PATHS = {
databaseWorker: `${BACKEND_ROOT}/workers/database.worker.js`,
main: `${BACKEND_ROOT}/main.js`,
playlistRefreshWorker: `${BACKEND_ROOT}/workers/playlist-refresh.worker.js`,
preload: `${BACKEND_ROOT}/main.preload.js`,
} as const;
export async function captureXtreamBuildIdentity(
workspaceRoot: string
): Promise<XtreamBenchmarkBuildIdentity> {
try {
if (!isAbsolute(workspaceRoot)) invalid();
const [databaseWorker, main, playlistRefreshWorker, preload, renderer] =
await Promise.all([
readPair(workspaceRoot, ELECTRON_PATHS.databaseWorker),
readPair(workspaceRoot, ELECTRON_PATHS.main),
readPair(workspaceRoot, ELECTRON_PATHS.playlistRefreshWorker),
readPair(workspaceRoot, ELECTRON_PATHS.preload),
readRenderer(workspaceRoot),
]);
return Object.freeze({
electron: Object.freeze({
databaseWorker,
main,
playlistRefreshWorker,
preload,
}),
renderer,
});
} catch {
throw new Error('invalid Xtream performance build');
}
}
export function computeXtreamBuildFilesAggregate(
files: readonly XtreamBuildFileIdentity[]
): string {
try {
const length = Reflect.get(files, 'length') as unknown;
if (
!Number.isSafeInteger(length) ||
Number(length) <= 0 ||
Number(length) > 10_000
) {
invalid();
}
const snapshot = Array.from({ length: Number(length) }, (_, index) => {
const value = Reflect.get(files, String(index)) as
XtreamBuildFileIdentity | undefined;
if (
!value ||
!Number.isSafeInteger(value.bytes) ||
value.bytes < 0 ||
typeof value.path !== 'string' ||
value.path.length === 0 ||
typeof value.sha256 !== 'string' ||
!/^[a-f0-9]{64}$/u.test(value.sha256)
) {
invalid();
}
return [value.path, value.bytes, value.sha256] as const;
});
return sha256(Buffer.from(JSON.stringify(snapshot), 'utf8'));
} catch {
throw new Error('invalid Xtream build file identity');
}
}
async function readPair(
workspaceRoot: string,
javascriptPath: string
): Promise<XtreamBuildPairIdentity> {
const [javascript, sourceMap] = await Promise.all([
readIdentity(workspaceRoot, javascriptPath),
readIdentity(workspaceRoot, `${javascriptPath}.map`),
]);
return Object.freeze({ javascript, sourceMap });
}
async function readRenderer(
workspaceRoot: string
): Promise<XtreamBenchmarkBuildIdentity['renderer']> {
const rendererDirectory = join(workspaceRoot, RENDERER_ROOT);
const namesBefore = await readRendererNames(rendererDirectory);
assertRendererPairing(namesBefore);
const relativePaths = namesBefore.map((name) => `${RENDERER_ROOT}/${name}`);
const files = await Promise.all(
relativePaths.map((path) => readIdentity(workspaceRoot, path))
);
const namesAfter = await readRendererNames(rendererDirectory);
if (
namesAfter.length !== namesBefore.length ||
namesAfter.some((name, index) => name !== namesBefore[index])
) {
invalid();
}
const executableJavaScriptCount = namesBefore.filter((name) =>
name.endsWith('.js')
).length;
const sourceMapCount = namesBefore.filter((name) =>
name.endsWith('.js.map')
).length;
const bytes = files.reduce((total, file) => total + file.bytes, 0);
if (!Number.isSafeInteger(bytes) || bytes <= 0) invalid();
const frozenFiles = Object.freeze(files);
return Object.freeze({
aggregateSha256: computeXtreamBuildFilesAggregate(frozenFiles),
bytes,
executableJavaScriptCount,
files: frozenFiles,
sourceMapCount,
});
}
async function readRendererNames(directory: string): Promise<string[]> {
const entries = await readdir(directory, { withFileTypes: true });
const relevant = entries.filter(
(entry) =>
entry.name === 'index.html' ||
entry.name.endsWith('.js') ||
entry.name.endsWith('.js.map')
);
if (
relevant.some((entry) => !entry.isFile()) ||
relevant.filter((entry) => entry.name === 'index.html').length !== 1
) {
invalid();
}
return relevant.map((entry) => entry.name).sort();
}
function assertRendererPairing(names: readonly string[]): void {
const javascript = names.filter((name) => name.endsWith('.js'));
const sourceMaps = names.filter((name) => name.endsWith('.js.map'));
const javascriptSet = new Set(javascript);
const sourceMapSet = new Set(sourceMaps);
if (
javascript.length === 0 ||
javascript.length !== sourceMaps.length ||
javascript.some((name) => !sourceMapSet.has(`${name}.map`)) ||
sourceMaps.some((name) => !javascriptSet.has(name.slice(0, -4)))
) {
invalid();
}
}
async function readIdentity(
workspaceRoot: string,
relativePath: string
): Promise<XtreamBuildFileIdentity> {
const { content } = await readXtreamSafeRegularFile(
join(workspaceRoot, relativePath)
);
return Object.freeze({
bytes: content.byteLength,
path: relativePath,
sha256: sha256(content),
});
}
function sha256(value: Uint8Array): string {
return createHash('sha256').update(value).digest('hex');
}
function invalid(): never {
throw new Error('invalid');
}
@@ -0,0 +1,258 @@
import type { DatabaseWorkerCancelTimelineRecord } from './database-worker-cancel-capture';
import { snapshotXtreamCancellationEvidence } from './xtream-cancellation-evidence-snapshot';
import {
isFiniteNonNegative,
isPositiveSafeInteger,
} from './xtream-exact-schema';
import type {
XtreamAttributionPhaseEvent,
XtreamIpcAttributionSpan,
} from './xtream-phase-attribution';
import {
hasDistinctMonotonicXtreamIpcProducerIdentities,
XTREAM_IPC_PRODUCER_NAMESPACE,
xtreamIpcProducerNamespaceForWorkerOperation,
type XtreamIpcProducerIdentity,
} from './xtream-ipc-producer-identity';
import { XTREAM_ATTRIBUTION_PHASE as PHASE } from './xtream-phase-inventory';
import type {
XtreamCancellationMetrics,
XtreamRawIterationResult,
} from './xtream-summary-contract';
type WorkerRequest =
XtreamRawIterationResult['databaseWorker']['requests']['evidence'][number];
const RECORD_TYPES = [
'db-cancel-dispatched',
'db-cancel-received',
'db-cancel-terminal-received',
] as const;
export function assertXtreamCancellationEvidenceBinding(
raw: XtreamRawIterationResult,
events: readonly XtreamAttributionPhaseEvent[],
ipcSpans: readonly XtreamIpcAttributionSpan[],
requests: readonly WorkerRequest[]
): void {
const failed = requests.filter(
({ operation, success }) => operation === 'DB_SAVE_CONTENT' && !success
);
if (raw.scenarioId !== 'xtream-cancel-import') {
if (failed.length !== 0 || raw.cancellationEvidence !== null) invalid();
return;
}
const request = failed[0];
if (
failed.length !== 1 ||
!request ||
typeof request.requestId !== 'string' ||
typeof request.operationId !== 'string' ||
raw.cancellation.failedDatabaseRequestId !== request.requestId ||
raw.cancellation.failedOperationId !== request.operationId
) {
invalid();
}
const timeline = cancellationTimeline(raw, request);
const databasePreload = ipcPair(ipcSpans, 'dbCancelOperation');
assertCancellationProducerIdentity(timeline, databasePreload[0], requests);
assertCancellationTimeline(
raw.cancellation,
request,
timeline,
phaseSpan(
events,
PHASE.SQLITE_CONTENT_WRITE_TRANSACTIONS,
request.requestId
),
phaseSpan(events, PHASE.CANCEL_SESSION),
phaseSpan(events, PHASE.STORE_IMPORT_TERMINAL),
ipcPair(ipcSpans, 'xtreamCancelSession'),
databasePreload,
raw.phaseCapture.uiPaintEpochMs
);
}
interface Span {
readonly endEpochMs: number;
readonly startEpochMs: number;
}
function assertCancellationTimeline(
value: XtreamCancellationMetrics,
request: WorkerRequest,
timeline: readonly DatabaseWorkerCancelTimelineRecord[],
write: Span,
networkCancel: Span,
terminal: Span,
networkPreload: readonly [
XtreamIpcAttributionSpan,
XtreamIpcAttributionSpan,
],
databasePreload: readonly [
XtreamIpcAttributionSpan,
XtreamIpcAttributionSpan,
],
uiPaintEpochMs: number
): void {
const [dispatchRecord, receiptRecord, workerTerminalRecord] = timeline;
if (!dispatchRecord || !receiptRecord || !workerTerminalRecord) invalid();
const click = epoch(value.clickEpochMs);
const preloadStart = epoch(value.preloadStartEpochMs);
const preloadReturn = epoch(value.preloadReturnEpochMs);
const dispatch = epoch(value.databaseDispatchEpochMs);
const receipt = epoch(value.workerReceiptEpochMs);
const authoritative = epoch(value.authoritativeTerminalEpochMs);
const painted = epoch(value.paintedEpochMs);
if (
request.requestReceivedEpochMs === null ||
request.workEndedEpochMs === null ||
click < write.startEpochMs ||
click < request.requestReceivedEpochMs ||
click > write.endEpochMs ||
networkPreload[0].startEpochMs < click ||
networkPreload[0].endEpochMs > networkCancel.startEpochMs ||
networkCancel.endEpochMs > networkPreload[1].startEpochMs ||
networkPreload[1].startEpochMs > databasePreload[0].startEpochMs ||
preloadStart !== databasePreload[0].startEpochMs ||
dispatchRecord.ipcCallId !== databasePreload[0].ipcCallId ||
dispatchRecord.sourceEpochMs !== databasePreload[0].sourceEpochMs ||
databasePreload[0].endEpochMs > dispatch ||
dispatch !== dispatchRecord.epochMs ||
dispatch < request.requestReceivedEpochMs ||
dispatch > write.endEpochMs ||
databasePreload[1].startEpochMs < dispatch ||
preloadReturn !== databasePreload[1].endEpochMs ||
preloadReturn < dispatch ||
receipt !== receiptRecord.epochMs ||
receipt < dispatch ||
receipt > request.workEndedEpochMs ||
receipt > authoritative ||
workerTerminalRecord.epochMs < receipt ||
workerTerminalRecord.epochMs > authoritative ||
authoritative !== request.responseEpochMs ||
terminal.startEpochMs < authoritative ||
terminal.endEpochMs > painted ||
painted !== uiPaintEpochMs
) {
invalid();
}
}
function cancellationTimeline(
raw: XtreamRawIterationResult,
request: WorkerRequest
): readonly DatabaseWorkerCancelTimelineRecord[] {
const evidence = snapshotXtreamCancellationEvidence(
raw.cancellationEvidence
);
if (evidence === null) invalid();
const timeline = evidence.timeline;
if (timeline.length !== RECORD_TYPES.length) invalid();
const first = timeline[0];
if (!first) invalid();
for (let index = 0; index < timeline.length; index += 1) {
const record = timeline[index];
if (
!record ||
record.type !== RECORD_TYPES[index] ||
!isFiniteNonNegative(record.epochMs) ||
!isFiniteNonNegative(record.sourceEpochMs) ||
!isPositiveSafeInteger(record.ipcCallId) ||
typeof record.operationId !== 'string' ||
record.operationId.length === 0 ||
typeof record.requestId !== 'string' ||
record.requestId.length === 0 ||
record.ipcCallId !== first.ipcCallId ||
record.operationId !== first.operationId ||
record.requestId !== first.requestId ||
record.sourceEpochMs !== first.sourceEpochMs
) {
invalid();
}
}
if (
first.requestId !== request.requestId ||
first.operationId !== request.operationId
) {
invalid();
}
return timeline;
}
function assertCancellationProducerIdentity(
timeline: readonly DatabaseWorkerCancelTimelineRecord[],
databasePreload: XtreamIpcAttributionSpan,
requests: readonly WorkerRequest[]
): void {
const dispatch = timeline[0];
if (
!dispatch ||
dispatch.ipcCallId !== databasePreload.ipcCallId ||
dispatch.sourceEpochMs !== databasePreload.sourceEpochMs
) {
invalid();
}
const identities: XtreamIpcProducerIdentity[] = [];
for (const { ipcCallId, operation, sourceEpochMs } of requests) {
if (ipcCallId === null && sourceEpochMs === null) continue;
const namespace = xtreamIpcProducerNamespaceForWorkerOperation(
typeof operation === 'string' ? operation : ''
);
if (
namespace === null ||
!isPositiveSafeInteger(ipcCallId) ||
!isFiniteNonNegative(sourceEpochMs)
) {
invalid();
}
if (namespace === XTREAM_IPC_PRODUCER_NAMESPACE.XTREAM_PRELOAD) {
identities.push({ ipcCallId, namespace, sourceEpochMs });
}
}
identities.push({
ipcCallId: databasePreload.ipcCallId,
namespace: XTREAM_IPC_PRODUCER_NAMESPACE.XTREAM_PRELOAD,
sourceEpochMs: databasePreload.sourceEpochMs,
});
if (!hasDistinctMonotonicXtreamIpcProducerIdentities(identities)) {
invalid();
}
}
function phaseSpan(
events: readonly XtreamAttributionPhaseEvent[],
phase: string,
correlationId?: string
): Span {
const selected = events.filter(
(event) =>
event.phase === phase &&
(correlationId === undefined ||
event.correlationId === correlationId)
);
const start = selected.find(({ boundary }) => boundary === 'start');
const end = selected.find(({ boundary }) => boundary === 'end');
if (selected.length !== 2 || !start || !end) invalid();
return { endEpochMs: end.epochMs, startEpochMs: start.epochMs };
}
function ipcPair(
spans: readonly XtreamIpcAttributionSpan[],
method: string
): readonly [XtreamIpcAttributionSpan, XtreamIpcAttributionSpan] {
const selected = spans.filter((span) => span.method === method);
const request = selected.find(({ boundary }) => boundary === 'request');
const response = selected.find(({ boundary }) => boundary === 'response');
if (selected.length !== 2 || !request || !response) invalid();
return [request, response];
}
function epoch(value: number | null): number {
if (!isFiniteNonNegative(value)) invalid();
return value;
}
function invalid(): never {
throw new Error('invalid Xtream persisted cancellation evidence');
}
@@ -0,0 +1,115 @@
import type { DatabaseWorkerCancelTimelineRecord } from './database-worker-cancel-capture';
import type { XtreamCancellationEvidence } from './xtream-summary-contract';
const EVIDENCE_KEYS = ['timeline'] as const;
const RECORD_KEYS = [
'epochMs',
'ipcCallId',
'operationId',
'requestId',
'sourceEpochMs',
'type',
] as const;
const MAX_TIMELINE_LENGTH = 16;
export function snapshotXtreamCancellationEvidence(
value: unknown
): XtreamCancellationEvidence | null {
try {
const evidence = snapshotExactRecord(value, EVIDENCE_KEYS);
const timeline = snapshotExactArray(
evidence['timeline'],
snapshotTimelineRecord
);
return Object.freeze({ timeline });
} catch {
return null;
}
}
function snapshotTimelineRecord(
value: unknown
): DatabaseWorkerCancelTimelineRecord {
return snapshotExactRecord(
value,
RECORD_KEYS
) as unknown as DatabaseWorkerCancelTimelineRecord;
}
function snapshotExactArray<T>(
value: unknown,
snapshotEntry: (entry: unknown) => T
): readonly T[] {
if (!Array.isArray(value)) invalid();
const length = dataDescriptorValue(
Reflect.getOwnPropertyDescriptor(value, 'length')
);
if (
!Number.isSafeInteger(length) ||
Number(length) < 0 ||
Number(length) > MAX_TIMELINE_LENGTH
) {
invalid();
}
const expectedKeys = new Set<PropertyKey>(['length']);
const snapshot: T[] = [];
for (let index = 0; index < Number(length); index += 1) {
const key = String(index);
expectedKeys.add(key);
snapshot[index] = snapshotEntry(
dataDescriptorValue(Reflect.getOwnPropertyDescriptor(value, key))
);
}
const ownKeys = Reflect.ownKeys(value);
if (
ownKeys.length !== expectedKeys.size ||
ownKeys.some((key) => !expectedKeys.has(key))
) {
invalid();
}
return Object.freeze(snapshot);
}
function snapshotExactRecord(
value: unknown,
keys: readonly string[]
): Readonly<Record<string, unknown>> {
if (
typeof value !== 'object' ||
value === null ||
Array.isArray(value) ||
![Object.prototype, null].includes(Reflect.getPrototypeOf(value))
) {
invalid();
}
const ownKeys = Reflect.ownKeys(value);
if (
ownKeys.length !== keys.length ||
ownKeys.some((key) => typeof key !== 'string' || !keys.includes(key))
) {
invalid();
}
const snapshot: Record<string, unknown> = {};
for (const key of keys) {
snapshot[key] = dataDescriptorValue(
Reflect.getOwnPropertyDescriptor(value, key)
);
}
return Object.freeze(snapshot);
}
function dataDescriptorValue(
descriptor: PropertyDescriptor | undefined
): unknown {
if (
!descriptor ||
!Object.prototype.hasOwnProperty.call(descriptor, 'value')
) {
invalid();
}
return descriptor.value;
}
function invalid(): never {
throw new Error('invalid Xtream cancellation evidence snapshot');
}
@@ -0,0 +1,283 @@
import type { WorkerRequestPerformanceMetrics } from './m3u-refresh-cancellation-contract';
import type { DatabaseWorkerCancelTimelineRecord } from './database-worker-cancel-capture';
import type {
XtreamAttributionPhaseEvent,
XtreamIpcAttributionSpan,
XtreamPhaseAttributionInput,
} from './xtream-phase-attribution';
import {
XTREAM_IPC_PRODUCER_NAMESPACE,
xtreamIpcProducerNamespaceForMethod,
} from './xtream-ipc-producer-identity';
import { XTREAM_ATTRIBUTION_PHASE as PHASE } from './xtream-phase-inventory';
import type { XtreamCancellationMetrics } from './xtream-summary-contract';
import type { XtreamCancellationEvidence } from './xtream-summary-contract';
export function bindFixtureCancellationEvidence(
input: XtreamPhaseAttributionInput,
requests: readonly WorkerRequestPerformanceMetrics[]
): {
readonly cancellation: XtreamCancellationMetrics;
readonly cancellationEvidence: XtreamCancellationEvidence | null;
readonly phaseCapture: XtreamPhaseAttributionInput;
} {
if (input.scenarioId !== 'xtream-cancel-import') {
return {
cancellation: emptyCancellation(),
cancellationEvidence: null,
phaseCapture: input,
};
}
const failed = requests.filter(
({ operation, success }) => operation === 'DB_SAVE_CONTENT' && !success
);
const request = failed[0];
if (
failed.length !== 1 ||
!request ||
typeof request.requestId !== 'string' ||
typeof request.operationId !== 'string' ||
request.workEndedEpochMs === null
) {
fixtureError();
}
const write = phaseSpan(
input.events,
PHASE.SQLITE_CONTENT_WRITE_TRANSACTIONS,
request.requestId
);
const cancel = phaseSpan(input.events, PHASE.CANCEL_SESSION);
const clickEpochMs = write.startEpochMs + 0.25;
const networkPreloadStartEpochMs = clickEpochMs + 0.25;
const networkPreloadReturnEpochMs = cancel.endEpochMs + 0.25;
const preloadStartEpochMs = networkPreloadReturnEpochMs + 0.25;
const databaseDispatchEpochMs = preloadStartEpochMs + 0.5;
const preloadReturnEpochMs = databaseDispatchEpochMs + 0.5;
const workerReceiptEpochMs = preloadReturnEpochMs + 0.25;
const workerTerminalEpochMs = workerReceiptEpochMs + 0.25;
if (
databaseDispatchEpochMs > write.endEpochMs ||
workerTerminalEpochMs > request.workEndedEpochMs ||
workerTerminalEpochMs > request.responseEpochMs
) {
fixtureError();
}
const authoritativeTerminalEpochMs = request.responseEpochMs;
const paintedEpochMs = input.uiPaintEpochMs;
const ipcSpans = resequenceFixtureIpcSpans(
input.ipcSpans.map((span) => {
if (span.method === 'xtreamCancelSession') {
return retime(
span,
networkPreloadStartEpochMs,
cancel.startEpochMs,
cancel.endEpochMs,
networkPreloadReturnEpochMs
);
}
if (span.method === 'dbCancelOperation') {
return retime(
span,
preloadStartEpochMs,
databaseDispatchEpochMs - 0.25,
databaseDispatchEpochMs + 0.25,
preloadReturnEpochMs
);
}
return span;
})
);
const databasePreload = ipcSpans.find(
({ boundary, method }) =>
boundary === 'request' && method === 'dbCancelOperation'
);
if (!databasePreload) fixtureError();
const cancelTimeline = cancellationTimeline(
request,
databasePreload,
databaseDispatchEpochMs,
workerReceiptEpochMs,
workerTerminalEpochMs
);
return {
cancellation: {
acknowledgementLatencyMs:
authoritativeTerminalEpochMs - clickEpochMs,
authoritativeDatabaseAcknowledgementObserved: true,
authoritativeTerminalEpochMs,
clickEpochMs,
clickToDatabaseDispatchMs: databaseDispatchEpochMs - clickEpochMs,
clickToPaintMs: paintedEpochMs - clickEpochMs,
clickToPreloadReturnMs: preloadReturnEpochMs - clickEpochMs,
databaseDispatchEpochMs,
failedDatabaseRequestId: request.requestId,
failedOperationId: request.operationId,
mainNetworkAbortObserved: false,
mainNetworkAbortReason: 'cancel-triggered-after-network-complete',
paintedEpochMs,
preloadReturnEpochMs,
preloadStartEpochMs,
workerReceiptEpochMs,
workerReceiptIsAuthoritative: false,
workerReceiptLatencyMs: workerReceiptEpochMs - clickEpochMs,
},
cancellationEvidence: { timeline: cancelTimeline },
phaseCapture: { ...input, ipcSpans },
};
}
function cancellationTimeline(
request: WorkerRequestPerformanceMetrics,
databasePreload: XtreamIpcAttributionSpan,
dispatchEpochMs: number,
receiptEpochMs: number,
terminalEpochMs: number
): readonly DatabaseWorkerCancelTimelineRecord[] {
if (
typeof request.requestId !== 'string' ||
typeof request.operationId !== 'string'
) {
fixtureError();
}
const identity = {
ipcCallId: databasePreload.ipcCallId,
operationId: request.operationId,
requestId: request.requestId,
sourceEpochMs: databasePreload.sourceEpochMs,
};
return [
{
...identity,
epochMs: dispatchEpochMs,
type: 'db-cancel-dispatched',
},
{
...identity,
epochMs: receiptEpochMs,
type: 'db-cancel-received',
},
{
...identity,
epochMs: terminalEpochMs,
type: 'db-cancel-terminal-received',
},
];
}
function emptyCancellation(): XtreamCancellationMetrics {
return {
acknowledgementLatencyMs: null,
authoritativeDatabaseAcknowledgementObserved: false,
authoritativeTerminalEpochMs: null,
clickEpochMs: null,
clickToDatabaseDispatchMs: null,
clickToPaintMs: null,
clickToPreloadReturnMs: null,
databaseDispatchEpochMs: null,
failedDatabaseRequestId: null,
failedOperationId: null,
mainNetworkAbortObserved: false,
mainNetworkAbortReason: null,
paintedEpochMs: null,
preloadReturnEpochMs: null,
preloadStartEpochMs: null,
workerReceiptEpochMs: null,
workerReceiptIsAuthoritative: false,
workerReceiptLatencyMs: null,
};
}
function retime(
span: XtreamIpcAttributionSpan,
requestStartEpochMs: number,
requestEndEpochMs: number,
responseStartEpochMs: number,
responseEndEpochMs: number
): XtreamIpcAttributionSpan {
return {
...span,
endEpochMs:
span.boundary === 'request'
? requestEndEpochMs
: responseEndEpochMs,
startEpochMs:
span.boundary === 'request'
? requestStartEpochMs
: responseStartEpochMs,
sourceEpochMs: requestStartEpochMs,
};
}
function resequenceFixtureIpcSpans(
spans: readonly XtreamIpcAttributionSpan[]
): readonly XtreamIpcAttributionSpan[] {
const groups = new Map<string, XtreamIpcAttributionSpan[]>();
for (const span of spans) {
groups.set(span.correlationId, [
...(groups.get(span.correlationId) ?? []),
span,
]);
}
const calls = [...groups.entries()].map(([correlationId, call]) => {
const span = call[0];
if (
call.length !== 2 ||
!span ||
call.some(
(candidate) =>
candidate.ipcCallId !== span.ipcCallId ||
candidate.sourceEpochMs !== span.sourceEpochMs
)
) {
fixtureError();
}
const namespace = xtreamIpcProducerNamespaceForMethod(span.method);
if (namespace === null) fixtureError();
return { correlationId, namespace, span };
});
const reassigned = new Map<string, number>();
for (const namespace of Object.values(XTREAM_IPC_PRODUCER_NAMESPACE)) {
const selected = calls
.filter((call) => call.namespace === namespace)
.sort(
(left, right) =>
left.span.sourceEpochMs - right.span.sourceEpochMs ||
left.span.ipcCallId - right.span.ipcCallId
);
const ids = selected
.map(({ span }) => span.ipcCallId)
.sort((left, right) => left - right);
if (new Set(ids).size !== ids.length) fixtureError();
selected.forEach(({ correlationId }, index) => {
const ipcCallId = ids[index];
if (!ipcCallId) fixtureError();
reassigned.set(correlationId, ipcCallId);
});
}
return spans.map((span) => {
const ipcCallId = reassigned.get(span.correlationId);
if (!ipcCallId) fixtureError();
return { ...span, ipcCallId };
});
}
function phaseSpan(
events: readonly XtreamAttributionPhaseEvent[],
phase: string,
correlationId?: string
): { readonly endEpochMs: number; readonly startEpochMs: number } {
const selected = events.filter(
(event) =>
event.phase === phase &&
(correlationId === undefined ||
event.correlationId === correlationId)
);
const start = selected.find(({ boundary }) => boundary === 'start');
const end = selected.find(({ boundary }) => boundary === 'end');
if (selected.length !== 2 || !start || !end) fixtureError();
return { endEpochMs: end.epochMs, startEpochMs: start.epochMs };
}
function fixtureError(): never {
throw new Error('invalid Xtream cancellation fixture evidence');
}
@@ -0,0 +1,180 @@
export interface XtreamCatalogDatabaseQuery {
readonly parameters: readonly (number | string)[];
readonly sql: string;
}
const CATEGORY_PARTITIONS = [
{
categoryType: 'live',
expectedName: 'Performance Live %02d',
idBase: 91_100,
},
{
categoryType: 'movies',
expectedName: 'Performance VOD %02d',
idBase: 92_100,
},
{
categoryType: 'series',
expectedName: 'Performance Series %02d',
idBase: 93_100,
},
] as const;
const CONTENT_PARTITIONS = [
{
categoryType: 'live',
contentType: 'live',
expectedTitle: 'Performance Live %06d',
idBase: 999_999,
},
{
categoryType: 'movies',
contentType: 'movie',
expectedTitle: 'Performance Movie %06d',
idBase: 1_999_999,
},
{
categoryType: 'series',
contentType: 'series',
expectedTitle: 'Performance Series %06d',
idBase: 2_999_999,
},
] as const;
const PLAYLIST_QUERY = `
SELECT
COUNT(*) AS playlistCount,
COALESCE(SUM(CASE WHEN id = ? THEN 1 ELSE 0 END), 0)
AS matchingPlaylistCount,
MAX(CASE WHEN id = ? THEN type ELSE NULL END)
AS matchingPlaylistType
FROM playlists
`;
const CATEGORY_COUNT_QUERY = `
SELECT COUNT(*) AS categoryCount
FROM categories
WHERE playlist_id = ?
`;
const CONTENT_COUNT_QUERY = `
SELECT COUNT(*) AS contentCount
FROM content AS item
INNER JOIN categories AS category ON category.id = item.category_id
WHERE category.playlist_id = ?
`;
const CATEGORY_PARTITION_QUERY = `
SELECT
COUNT(*) AS count,
COUNT(DISTINCT xtream_id) AS distinctXtreamIdCount,
COALESCE(
SUM(CASE
WHEN name <> printf(?, xtream_id - ?) THEN 1
ELSE 0
END),
0
) AS invalidNameCount,
MAX(xtream_id) AS maxXtreamId,
MIN(xtream_id) AS minXtreamId
FROM categories
WHERE playlist_id = ? AND type = ?
`;
const CONTENT_PARTITION_QUERY = `
SELECT
COUNT(*) AS count,
COUNT(DISTINCT item.xtream_id) AS distinctXtreamIdCount,
(
SELECT COUNT(*)
FROM (
SELECT expected_category.id
FROM categories AS expected_category
LEFT JOIN content AS expected_item
ON expected_item.category_id = expected_category.id
AND expected_item.type = ?
WHERE expected_category.playlist_id = ?
AND expected_category.type = ?
GROUP BY expected_category.id
HAVING COUNT(expected_item.id) <> 1000
)
) AS invalidCategoryCardinalityCount,
COALESCE(
SUM(CASE
WHEN item.title <> printf(?, item.xtream_id - ?) THEN 1
ELSE 0
END),
0
) AS invalidTitleCount,
MAX(item.xtream_id) AS maxXtreamId,
MIN(item.xtream_id) AS minXtreamId
FROM content AS item
INNER JOIN categories AS category ON category.id = item.category_id
WHERE category.playlist_id = ?
AND category.type = ?
AND item.type = ?
`;
const IMPORT_STATUS_QUERY = `
SELECT
(SELECT value FROM app_state WHERE key = ?) AS live,
(SELECT value FROM app_state WHERE key = ?) AS movie,
(SELECT value FROM app_state WHERE key = ?) AS series
`;
export function buildXtreamCatalogDatabaseQueries(
playlistId: string
): readonly XtreamCatalogDatabaseQuery[] {
const queries: XtreamCatalogDatabaseQuery[] = [
descriptor(PLAYLIST_QUERY, [playlistId, playlistId]),
descriptor(CATEGORY_COUNT_QUERY, [playlistId]),
descriptor(CONTENT_COUNT_QUERY, [playlistId]),
];
for (const partition of CATEGORY_PARTITIONS) {
queries.push(
descriptor(CATEGORY_PARTITION_QUERY, [
partition.expectedName,
partition.idBase,
playlistId,
partition.categoryType,
])
);
}
for (const partition of CONTENT_PARTITIONS) {
queries.push(
descriptor(CONTENT_PARTITION_QUERY, [
partition.contentType,
playlistId,
partition.categoryType,
partition.expectedTitle,
partition.idBase,
playlistId,
partition.categoryType,
partition.contentType,
])
);
}
queries.push(
descriptor(IMPORT_STATUS_QUERY, [
importStatusKey(playlistId, 'live'),
importStatusKey(playlistId, 'movie'),
importStatusKey(playlistId, 'series'),
])
);
return Object.freeze(queries);
}
function descriptor(
sql: string,
parameters: readonly (number | string)[]
): XtreamCatalogDatabaseQuery {
return Object.freeze({
parameters: Object.freeze([...parameters]),
sql,
});
}
function importStatusKey(playlistId: string, type: string): string {
return `xtream-import-status:${playlistId}:${type}`;
}
@@ -0,0 +1,365 @@
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import { describe, it } from 'node:test';
import {
readXtreamCatalogDatabaseSnapshot,
type XtreamCatalogDatabaseEvaluator,
} from './xtream-catalog-database-reader';
interface TestStatement {
get(...parameters: readonly (number | string)[]): unknown;
run(...parameters: readonly (number | string)[]): unknown;
}
interface TestDatabase {
close(): void;
exec(source: string): void;
prepare(source: string): TestStatement;
}
interface TestDatabaseConstructor {
new (path: string): TestDatabase;
}
interface RuntimeProcess {
getBuiltinModule(id: string): unknown;
}
const { DatabaseSync } = (
process as unknown as RuntimeProcess
).getBuiltinModule('node:sqlite') as {
readonly DatabaseSync: TestDatabaseConstructor;
};
describe('Xtream catalog database reader', () => {
it('reads the scoped catalog and import state after capture stops', async () => {
const database = createDatabase();
seedPlaylist(database, 'playlist-1');
seedPartition(database, {
categoryId: 91_101,
categoryName: 'Performance Live 01',
categoryType: 'live',
contentBase: 1_000_000,
contentType: 'live',
playlistId: 'playlist-1',
titleLabel: 'Live',
});
seedPartition(database, {
categoryId: 92_101,
categoryName: 'Performance VOD 01',
categoryType: 'movies',
contentBase: 2_000_000,
contentType: 'movie',
playlistId: 'playlist-1',
titleLabel: 'Movie',
});
seedPartition(database, {
categoryId: 93_101,
categoryName: 'Performance Series 01',
categoryType: 'series',
contentBase: 3_000_000,
contentType: 'series',
playlistId: 'playlist-1',
titleLabel: 'Series',
});
seedStatuses(database, 'playlist-1', 'completed');
const evaluator = evaluatorFor(database, 2_001);
const snapshot = await readXtreamCatalogDatabaseSnapshot(evaluator, {
captureStoppedEpochMs: 2_000,
dataDirectory: '/tmp/iptvnator-performance-fixture',
playlistId: 'playlist-1',
requireFromPath: '/workspace/dist/apps/electron-backend/main.js',
});
assert.deepEqual(snapshot, {
captureStoppedEpochMs: 2_000,
categories: {
live: categoryPartition(1, 91_101),
movies: categoryPartition(1, 92_101),
series: categoryPartition(1, 93_101),
},
categoryCount: 3,
content: {
live: contentPartition(1_000, 1_000_000),
movie: contentPartition(1_000, 2_000_000),
series: contentPartition(1_000, 3_000_000),
},
contentCount: 3_000,
databaseReadStartedEpochMs: 2_001,
importStatuses: {
live: 'completed',
movie: 'completed',
series: 'completed',
},
matchingPlaylistCount: 1,
matchingPlaylistType: 'xtream',
playlistCount: 1,
});
database.close();
});
it('reports malformed fixture rows and incomplete category cardinality', async () => {
const database = createDatabase();
seedPlaylist(database, 'playlist-1');
database.exec(`
INSERT INTO categories (playlist_id, name, type, xtream_id)
VALUES ('playlist-1', 'wrong category', 'live', 91101);
INSERT INTO content (category_id, title, xtream_id, type)
VALUES (last_insert_rowid(), 'wrong title', 1000000, 'live');
`);
seedStatuses(database, 'playlist-1', 'cancelled');
const snapshot = await readXtreamCatalogDatabaseSnapshot(
evaluatorFor(database, 3_001),
{
captureStoppedEpochMs: 3_000,
dataDirectory: '/tmp/iptvnator-performance-fixture',
playlistId: 'playlist-1',
requireFromPath:
'/workspace/dist/apps/electron-backend/main.js',
}
);
assert.equal(snapshot.categories.live.invalidNameCount, 1);
assert.equal(snapshot.content.live.invalidTitleCount, 1);
assert.equal(snapshot.content.live.invalidCategoryCardinalityCount, 1);
assert.deepEqual(snapshot.importStatuses, {
live: 'cancelled',
movie: 'cancelled',
series: 'cancelled',
});
database.close();
});
it('returns an empty deleted state without inventing a playlist type', async () => {
const database = createDatabase();
seedStatuses(database, 'playlist-1', 'completed');
const snapshot = await readXtreamCatalogDatabaseSnapshot(
evaluatorFor(database, 4_001),
{
captureStoppedEpochMs: 4_000,
dataDirectory: '/tmp/iptvnator-performance-fixture',
playlistId: 'playlist-1',
requireFromPath:
'/workspace/dist/apps/electron-backend/main.js',
}
);
assert.equal(snapshot.categoryCount, 0);
assert.equal(snapshot.contentCount, 0);
assert.equal(snapshot.matchingPlaylistCount, 0);
assert.equal(snapshot.matchingPlaylistType, null);
assert.equal(snapshot.playlistCount, 0);
database.close();
});
it('fails closed for pre-capture reads and malformed main-process results', async () => {
const database = createDatabase();
const base = {
captureStoppedEpochMs: 5_000,
dataDirectory: '/tmp/iptvnator-performance-fixture',
playlistId: 'playlist-1',
requireFromPath: '/workspace/dist/apps/electron-backend/main.js',
};
await assert.rejects(
readXtreamCatalogDatabaseSnapshot(
evaluatorFor(database, 4_999),
base
),
/invalid Xtream catalog database read/
);
await assert.rejects(
readXtreamCatalogDatabaseSnapshot(
{
evaluate: async () => ({
databaseReadStartedEpochMs: 5_001,
rows: [],
}),
},
base
),
/invalid Xtream catalog database read/
);
await assert.rejects(
readXtreamCatalogDatabaseSnapshot(evaluatorFor(database, 5_001), {
...base,
dataDirectory: 'relative',
}),
/invalid Xtream catalog database read/
);
database.close();
});
it('accepts high-resolution fractional capture and database epochs', async () => {
const database = createDatabase();
const snapshot = await readXtreamCatalogDatabaseSnapshot(
evaluatorFor(database, 6_000.75),
{
captureStoppedEpochMs: 6_000.5,
dataDirectory: '/tmp/iptvnator-performance-fixture',
playlistId: 'playlist-1',
requireFromPath:
'/workspace/dist/apps/electron-backend/main.js',
}
);
assert.equal(snapshot.captureStoppedEpochMs, 6_000.5);
assert.equal(snapshot.databaseReadStartedEpochMs, 6_000.75);
database.close();
});
it('uses the high-resolution epoch clock inside the main-process read boundary', () => {
const source = readFileSync(
resolve(
process.cwd(),
'src/performance/xtream-catalog-database-reader.ts'
),
'utf8'
);
assert.match(source, /getBuiltinModule\(\s*'node:perf_hooks'\s*\)/u);
assert.match(
source,
/perfHooks\.performance\.timeOrigin\s*\+\s*perfHooks\.performance\.now\(\)/u
);
assert.doesNotMatch(source, /Date\.now\(\)/u);
});
});
interface QueryDescriptor {
readonly parameters: readonly (number | string)[];
readonly sql: string;
}
interface EvaluationInput {
readonly queries: readonly QueryDescriptor[];
}
function evaluatorFor(
database: TestDatabase,
databaseReadStartedEpochMs: number
): XtreamCatalogDatabaseEvaluator {
return {
evaluate: async (_pageFunction: unknown, value: unknown) => {
const input = value as unknown as EvaluationInput;
return {
databaseReadStartedEpochMs,
rows: input.queries.map((query) =>
database.prepare(query.sql).get(...query.parameters)
),
};
},
} as unknown as XtreamCatalogDatabaseEvaluator;
}
function createDatabase(): TestDatabase {
const database = new DatabaseSync(':memory:');
database.exec(`
CREATE TABLE playlists (id TEXT PRIMARY KEY, type TEXT NOT NULL);
CREATE TABLE app_state (key TEXT PRIMARY KEY, value TEXT NOT NULL);
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
playlist_id TEXT NOT NULL,
name TEXT NOT NULL,
type TEXT NOT NULL,
xtream_id INTEGER NOT NULL
);
CREATE TABLE content (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category_id INTEGER NOT NULL,
title TEXT NOT NULL,
xtream_id INTEGER NOT NULL,
type TEXT NOT NULL
);
`);
return database;
}
function seedPlaylist(database: TestDatabase, playlistId: string): void {
database
.prepare('INSERT INTO playlists (id, type) VALUES (?, ?)')
.run(playlistId, 'xtream');
}
function seedStatuses(
database: TestDatabase,
playlistId: string,
status: string
): void {
const insert = database.prepare(
'INSERT INTO app_state (key, value) VALUES (?, ?)'
);
for (const type of ['live', 'movie', 'series']) {
insert.run(`xtream-import-status:${playlistId}:${type}`, status);
}
}
function seedPartition(
database: TestDatabase,
options: {
readonly categoryId: number;
readonly categoryName: string;
readonly categoryType: string;
readonly contentBase: number;
readonly contentType: string;
readonly playlistId: string;
readonly titleLabel: string;
}
): void {
database
.prepare(
`INSERT INTO categories (playlist_id, name, type, xtream_id)
VALUES (?, ?, ?, ?)`
)
.run(
options.playlistId,
options.categoryName,
options.categoryType,
options.categoryId
);
const categoryRow = database
.prepare('SELECT id FROM categories WHERE playlist_id = ? AND type = ?')
.get(options.playlistId, options.categoryType) as { id: number };
const insert = database.prepare(
`INSERT INTO content (category_id, title, xtream_id, type)
VALUES (?, ?, ?, ?)`
);
for (let index = 0; index < 1_000; index += 1) {
insert.run(
categoryRow.id,
`Performance ${options.titleLabel} ${String(index + 1).padStart(
6,
'0'
)}`,
options.contentBase + index,
options.contentType
);
}
}
function categoryPartition(count: number, id: number) {
return {
count,
distinctXtreamIdCount: count,
invalidNameCount: 0,
maxXtreamId: id,
minXtreamId: id,
};
}
function contentPartition(count: number, id: number) {
return {
count,
distinctXtreamIdCount: count,
invalidCategoryCardinalityCount: 0,
invalidTitleCount: 0,
maxXtreamId: id + count - 1,
minXtreamId: id,
};
}
@@ -0,0 +1,302 @@
import type { ElectronApplication } from '@playwright/test';
import { isAbsolute, join } from 'node:path';
import type { XtreamCatalogDatabaseSnapshot } from './xtream-catalog-database-verification';
import {
buildXtreamCatalogDatabaseQueries,
type XtreamCatalogDatabaseQuery,
} from './xtream-catalog-database-queries';
export type XtreamCatalogDatabaseEvaluator = Pick<
ElectronApplication,
'evaluate'
>;
export interface XtreamCatalogDatabaseReadOptions {
readonly captureStoppedEpochMs: number;
readonly dataDirectory: string;
readonly playlistId: string;
readonly requireFromPath: string;
}
interface DatabaseReadInput {
readonly databasePath: string;
readonly queries: readonly XtreamCatalogDatabaseQuery[];
readonly requireFromPath: string;
}
interface DatabaseReadTransport {
readonly databaseReadStartedEpochMs: number;
readonly rows: readonly unknown[];
}
export async function readXtreamCatalogDatabaseSnapshot(
evaluator: XtreamCatalogDatabaseEvaluator,
options: XtreamCatalogDatabaseReadOptions
): Promise<XtreamCatalogDatabaseSnapshot> {
try {
assertOptions(options);
const queries = buildXtreamCatalogDatabaseQueries(options.playlistId);
const transport = (await evaluator.evaluate(
async (_electron, input: DatabaseReadInput) => {
interface SqliteStatement {
get(...parameters: readonly (number | string)[]): unknown;
}
interface SqliteDatabase {
close(): void;
pragma(source: string): unknown;
prepare(source: string): SqliteStatement;
}
interface SqliteConstructor {
new (
path: string,
options: {
readonly: true;
fileMustExist: true;
}
): SqliteDatabase;
}
interface NodeModuleBuiltin {
createRequire(path: string): (id: string) => unknown;
}
interface NodePerfHooksBuiltin {
readonly performance: {
now(): number;
readonly timeOrigin: number;
};
}
const perfHooks = process.getBuiltinModule(
'node:perf_hooks'
) as NodePerfHooksBuiltin;
const databaseReadStartedEpochMs =
perfHooks.performance.timeOrigin +
perfHooks.performance.now();
const nodeModule = process.getBuiltinModule(
'node:module'
) as NodeModuleBuiltin;
const requireFromBuild = nodeModule.createRequire(
input.requireFromPath
);
const Sqlite = requireFromBuild(
'better-sqlite3'
) as SqliteConstructor;
const database = new Sqlite(input.databasePath, {
readonly: true,
fileMustExist: true,
});
try {
database.pragma('query_only = ON');
return {
databaseReadStartedEpochMs,
rows: input.queries.map((query) =>
database.prepare(query.sql).get(...query.parameters)
),
};
} finally {
database.close();
}
},
{
databasePath: join(
options.dataDirectory,
'databases',
'iptvnator.db'
),
queries,
requireFromPath: options.requireFromPath,
}
)) as DatabaseReadTransport;
return snapshotTransport(
transport,
options.captureStoppedEpochMs,
queries.length
);
} catch {
throw new Error('invalid Xtream catalog database read');
}
}
function snapshotTransport(
value: unknown,
captureStoppedEpochMs: number,
expectedRowCount: number
): XtreamCatalogDatabaseSnapshot {
const transport = exactRecord(value, [
'databaseReadStartedEpochMs',
'rows',
]);
const databaseReadStartedEpochMs = transport[
'databaseReadStartedEpochMs'
] as unknown;
const rows = transport['rows'];
if (
!isPositiveFinite(databaseReadStartedEpochMs) ||
databaseReadStartedEpochMs < captureStoppedEpochMs ||
!Array.isArray(rows) ||
rows.length !== expectedRowCount
) {
invalid();
}
const playlist = numericRecord(rows[0], [
'playlistCount',
'matchingPlaylistCount',
'matchingPlaylistType',
]);
const categoryCount = singleCount(rows[1], 'categoryCount');
const contentCount = singleCount(rows[2], 'contentCount');
const categories = [rows[3], rows[4], rows[5]].map(categoryPartition);
const content = [rows[6], rows[7], rows[8]].map(contentPartition);
const importStatuses = statusRecord(rows[9]);
const matchingPlaylistType = playlist['matchingPlaylistType'];
if (
matchingPlaylistType !== null &&
typeof matchingPlaylistType !== 'string'
) {
invalid();
}
return Object.freeze({
captureStoppedEpochMs,
categories: Object.freeze({
live: categories[0],
movies: categories[1],
series: categories[2],
}),
categoryCount,
content: Object.freeze({
live: content[0],
movie: content[1],
series: content[2],
}),
contentCount,
databaseReadStartedEpochMs,
importStatuses,
matchingPlaylistCount: nonNegativeInteger(
playlist['matchingPlaylistCount']
),
matchingPlaylistType,
playlistCount: nonNegativeInteger(playlist['playlistCount']),
});
}
function categoryPartition(value: unknown) {
const row = numericRecord(value, [
'count',
'distinctXtreamIdCount',
'invalidNameCount',
'maxXtreamId',
'minXtreamId',
]);
return Object.freeze({
count: nonNegativeInteger(row['count']),
distinctXtreamIdCount: nonNegativeInteger(row['distinctXtreamIdCount']),
invalidNameCount: nonNegativeInteger(row['invalidNameCount']),
maxXtreamId: nullableInteger(row['maxXtreamId']),
minXtreamId: nullableInteger(row['minXtreamId']),
});
}
function contentPartition(value: unknown) {
const row = numericRecord(value, [
'count',
'distinctXtreamIdCount',
'invalidCategoryCardinalityCount',
'invalidTitleCount',
'maxXtreamId',
'minXtreamId',
]);
return Object.freeze({
count: nonNegativeInteger(row['count']),
distinctXtreamIdCount: nonNegativeInteger(row['distinctXtreamIdCount']),
invalidCategoryCardinalityCount: nonNegativeInteger(
row['invalidCategoryCardinalityCount']
),
invalidTitleCount: nonNegativeInteger(row['invalidTitleCount']),
maxXtreamId: nullableInteger(row['maxXtreamId']),
minXtreamId: nullableInteger(row['minXtreamId']),
});
}
function singleCount(value: unknown, key: string): number {
return nonNegativeInteger(numericRecord(value, [key])[key]);
}
function statusRecord(value: unknown) {
const row = exactRecord(value, ['live', 'movie', 'series']);
for (const key of ['live', 'movie', 'series']) {
if (row[key] !== null && typeof row[key] !== 'string') {
invalid();
}
}
return Object.freeze({
live: row['live'] as string | null,
movie: row['movie'] as string | null,
series: row['series'] as string | null,
});
}
function numericRecord(
value: unknown,
keys: readonly string[]
): Record<string, unknown> {
return exactRecord(value, keys);
}
function exactRecord(
value: unknown,
expectedKeys: readonly string[]
): Record<string, unknown> {
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
invalid();
}
const keys = Reflect.ownKeys(value);
if (
keys.length !== expectedKeys.length ||
keys.some(
(key) => typeof key !== 'string' || !expectedKeys.includes(key)
)
) {
invalid();
}
return Object.fromEntries(
expectedKeys.map((key) => [key, Reflect.get(value, key)])
);
}
function nonNegativeInteger(value: unknown): number {
if (
typeof value !== 'number' ||
!Number.isSafeInteger(value) ||
value < 0
) {
invalid();
}
return value;
}
function nullableInteger(value: unknown): number | null {
if (value === null) return null;
return nonNegativeInteger(value);
}
function assertOptions(options: XtreamCatalogDatabaseReadOptions): void {
if (
!isPositiveFinite(options.captureStoppedEpochMs) ||
!isAbsolute(options.dataDirectory) ||
!isAbsolute(options.requireFromPath) ||
options.playlistId.length === 0 ||
options.playlistId.length > 256
) {
invalid();
}
}
function isPositiveFinite(value: unknown): value is number {
return typeof value === 'number' && Number.isFinite(value) && value > 0;
}
function invalid(): never {
throw new Error('invalid');
}
@@ -0,0 +1,361 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_SCENARIO_ID,
type XtreamPerformanceManifest,
} from './xtream-benchmark-contract';
import {
assertXtreamCatalogDatabaseSnapshot,
createXtreamCatalogVerification,
type XtreamCatalogDatabaseSnapshot,
} from './xtream-catalog-database-verification';
describe('Xtream catalog database verification', () => {
it('accepts the exact synthetic catalog after import and refresh scenarios', () => {
for (const scenarioId of [
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
XTREAM_SCENARIO_ID.REFRESH_LARGE,
XTREAM_SCENARIO_ID.BACKGROUND_UI,
] as const) {
const snapshot = importedSnapshot();
assert.doesNotThrow(() =>
assertXtreamCatalogDatabaseSnapshot(
snapshot,
manifest(),
scenarioId
)
);
assert.deepEqual(
createXtreamCatalogVerification(
snapshot,
manifest(),
scenarioId
),
{
databaseStateValid: true,
fixtureIdentityValid: true,
providerCategoryCount: 100,
providerItemCount: 100_000,
verifiedAfterCapture: true,
}
);
}
});
it('pins the current cancellation cleanup state and complete source deletion', () => {
assert.doesNotThrow(() =>
assertXtreamCatalogDatabaseSnapshot(
emptySnapshot({
matchingPlaylistCount: 1,
matchingPlaylistType: 'xtream',
playlistCount: 1,
statuses: {
live: 'failed',
movie: 'failed',
series: 'failed',
},
}),
manifest(),
XTREAM_SCENARIO_ID.CANCEL_IMPORT
)
);
assert.throws(
() =>
assertXtreamCatalogDatabaseSnapshot(
emptySnapshot({
matchingPlaylistCount: 1,
matchingPlaylistType: 'xtream',
playlistCount: 1,
statuses: {
live: 'cancelled',
movie: 'cancelled',
series: 'cancelled',
},
}),
manifest(),
XTREAM_SCENARIO_ID.CANCEL_IMPORT
),
/invalid Xtream database catalog state/
);
assert.doesNotThrow(() =>
assertXtreamCatalogDatabaseSnapshot(
emptySnapshot(),
manifest(),
XTREAM_SCENARIO_ID.DELETE_LARGE
)
);
});
it('rejects partial, foreign, mis-associated, and non-terminal database state', () => {
const baseline = importedSnapshot();
const invalid: XtreamCatalogDatabaseSnapshot[] = [
{ ...baseline, playlistCount: 2 },
{
...baseline,
categories: {
...baseline.categories,
live: {
...baseline.categories.live,
distinctXtreamIdCount: 59,
},
},
},
{
...baseline,
content: {
...baseline.content,
movie: {
...baseline.content.movie,
maxXtreamId: 2_019_998,
},
},
},
{
...baseline,
content: {
...baseline.content,
series: {
...baseline.content.series,
invalidCategoryCardinalityCount: 1,
},
},
},
{
...baseline,
content: {
...baseline.content,
live: {
...baseline.content.live,
invalidTitleCount: 1,
},
},
},
{
...baseline,
importStatuses: {
...baseline.importStatuses,
movie: 'importing',
},
},
{
...baseline,
databaseReadStartedEpochMs: baseline.captureStoppedEpochMs - 1,
},
];
for (const snapshot of invalid) {
assert.throws(
() =>
assertXtreamCatalogDatabaseSnapshot(
snapshot,
manifest(),
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE
),
/^Error: invalid Xtream database catalog state$/u
);
}
});
it('rejects cancellation residue and a delete that left the source row behind', () => {
const cancelled = emptySnapshot({
matchingPlaylistCount: 1,
matchingPlaylistType: 'xtream',
playlistCount: 1,
statuses: {
live: 'failed',
movie: 'failed',
series: 'failed',
},
});
const cancelWithResidue: XtreamCatalogDatabaseSnapshot = {
...cancelled,
content: {
...cancelled.content,
live: {
...cancelled.content.live,
count: 1,
distinctXtreamIdCount: 1,
maxXtreamId: 1_000_000,
minXtreamId: 1_000_000,
},
},
contentCount: 1,
};
assert.throws(
() =>
assertXtreamCatalogDatabaseSnapshot(
cancelWithResidue,
manifest(),
XTREAM_SCENARIO_ID.CANCEL_IMPORT
),
/invalid Xtream database catalog state/
);
assert.throws(
() =>
assertXtreamCatalogDatabaseSnapshot(
emptySnapshot({
matchingPlaylistCount: 1,
matchingPlaylistType: 'xtream',
playlistCount: 1,
}),
manifest(),
XTREAM_SCENARIO_ID.DELETE_LARGE
),
/invalid Xtream database catalog state/
);
});
it('uses one canonical fixture manifest snapshot', () => {
const expectedManifest = manifest();
const reducedCounts = {
categories: { live: 1, series: 1, total: 3, vod: 1 },
items: { live: 1, series: 1, total: 3, vod: 1 },
};
let countReads = 0;
const changingManifest = {
...expectedManifest,
get counts() {
countReads += 1;
return countReads === 1
? expectedManifest.counts
: reducedCounts;
},
};
const reducedSnapshot: XtreamCatalogDatabaseSnapshot = {
...importedSnapshot(),
categories: {
live: partition(1, 91_101),
movies: partition(1, 92_101),
series: partition(1, 93_101),
},
categoryCount: 3,
content: {
live: contentPartition(1, 1_000_000),
movie: contentPartition(1, 2_000_000),
series: contentPartition(1, 3_000_000),
},
contentCount: 3,
};
assert.throws(
() =>
createXtreamCatalogVerification(
reducedSnapshot,
changingManifest,
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE
),
/invalid Xtream database catalog state/
);
assert.equal(countReads, 1);
});
});
function manifest(): XtreamPerformanceManifest {
return {
bytes: 12_345_678,
catalogSha256: 'a'.repeat(64),
counts: {
categories: { live: 60, series: 20, total: 100, vod: 20 },
items: {
live: 60_000,
series: 20_000,
total: 100_000,
vod: 20_000,
},
},
epoch: 1,
scenario: 'performance-100k',
seed: 91_001,
};
}
function importedSnapshot(): XtreamCatalogDatabaseSnapshot {
return {
captureStoppedEpochMs: 1_000,
categories: {
live: partition(60, 91_101),
movies: partition(20, 92_101),
series: partition(20, 93_101),
},
categoryCount: 100,
content: {
live: contentPartition(60_000, 1_000_000),
movie: contentPartition(20_000, 2_000_000),
series: contentPartition(20_000, 3_000_000),
},
contentCount: 100_000,
databaseReadStartedEpochMs: 1_001,
importStatuses: {
live: 'completed',
movie: 'completed',
series: 'completed',
},
matchingPlaylistCount: 1,
matchingPlaylistType: 'xtream',
playlistCount: 1,
};
}
function emptySnapshot(
options: {
matchingPlaylistCount?: number;
matchingPlaylistType?: string | null;
playlistCount?: number;
statuses?: XtreamCatalogDatabaseSnapshot['importStatuses'];
} = {}
): XtreamCatalogDatabaseSnapshot {
return {
captureStoppedEpochMs: 1_000,
categories: {
live: partition(0, null),
movies: partition(0, null),
series: partition(0, null),
},
categoryCount: 0,
content: {
live: contentPartition(0, null),
movie: contentPartition(0, null),
series: contentPartition(0, null),
},
contentCount: 0,
databaseReadStartedEpochMs: 1_001,
importStatuses: options.statuses ?? {
live: 'completed',
movie: 'completed',
series: 'completed',
},
matchingPlaylistCount: options.matchingPlaylistCount ?? 0,
matchingPlaylistType: options.matchingPlaylistType ?? null,
playlistCount: options.playlistCount ?? 0,
};
}
function partition(
count: number,
minXtreamId: number | null
): XtreamCatalogDatabaseSnapshot['categories']['live'] {
return {
count,
distinctXtreamIdCount: count,
invalidNameCount: 0,
maxXtreamId: minXtreamId === null ? null : minXtreamId + count - 1,
minXtreamId,
};
}
function contentPartition(
count: number,
minXtreamId: number | null
): XtreamCatalogDatabaseSnapshot['content']['live'] {
return {
count,
distinctXtreamIdCount: count,
invalidCategoryCardinalityCount: 0,
invalidTitleCount: 0,
maxXtreamId: minXtreamId === null ? null : minXtreamId + count - 1,
minXtreamId,
};
}
@@ -0,0 +1,237 @@
import { isDeepStrictEqual } from 'node:util';
import {
XTREAM_SCENARIO_ID,
type XtreamPerformanceManifest,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import { parseXtreamManifest } from './xtream-control-state-schema';
interface XtreamCatalogPartition {
readonly count: number;
readonly distinctXtreamIdCount: number;
readonly invalidNameCount: number;
readonly maxXtreamId: number | null;
readonly minXtreamId: number | null;
}
interface XtreamContentPartition {
readonly count: number;
readonly distinctXtreamIdCount: number;
readonly invalidCategoryCardinalityCount: number;
readonly invalidTitleCount: number;
readonly maxXtreamId: number | null;
readonly minXtreamId: number | null;
}
export interface XtreamCatalogDatabaseSnapshot {
readonly captureStoppedEpochMs: number;
readonly categories: {
readonly live: XtreamCatalogPartition;
readonly movies: XtreamCatalogPartition;
readonly series: XtreamCatalogPartition;
};
readonly categoryCount: number;
readonly content: {
readonly live: XtreamContentPartition;
readonly movie: XtreamContentPartition;
readonly series: XtreamContentPartition;
};
readonly contentCount: number;
readonly databaseReadStartedEpochMs: number;
readonly importStatuses: {
readonly live: string | null;
readonly movie: string | null;
readonly series: string | null;
};
readonly matchingPlaylistCount: number;
readonly matchingPlaylistType: string | null;
readonly playlistCount: number;
}
export interface XtreamCatalogVerification {
readonly databaseStateValid: true;
readonly fixtureIdentityValid: true;
readonly providerCategoryCount: number;
readonly providerItemCount: number;
readonly verifiedAfterCapture: true;
}
export function assertXtreamCatalogDatabaseSnapshot(
snapshot: unknown,
manifest: XtreamPerformanceManifest,
scenarioId: XtreamScenarioId
): asserts snapshot is XtreamCatalogDatabaseSnapshot {
try {
const canonicalManifest = parseXtreamManifest(manifest);
assertCatalogSnapshot(snapshot, canonicalManifest, scenarioId);
} catch {
throw new Error('invalid Xtream database catalog state');
}
}
export function createXtreamCatalogVerification(
snapshot: unknown,
manifest: XtreamPerformanceManifest,
scenarioId: XtreamScenarioId
): XtreamCatalogVerification {
try {
const canonicalManifest = parseXtreamManifest(manifest);
assertCatalogSnapshot(snapshot, canonicalManifest, scenarioId);
return Object.freeze({
databaseStateValid: true,
fixtureIdentityValid: true,
providerCategoryCount: canonicalManifest.counts.categories.total,
providerItemCount: canonicalManifest.counts.items.total,
verifiedAfterCapture: true,
});
} catch {
throw new Error('invalid Xtream database catalog state');
}
}
function assertCatalogSnapshot(
snapshot: unknown,
manifest: XtreamPerformanceManifest,
scenarioId: XtreamScenarioId
): void {
const expected = expectedSnapshot(manifest, scenarioId);
const candidate = snapshotTopLevel(snapshot);
if (
!isSnapshotTimingValid(candidate) ||
!isDeepStrictEqual(withoutSnapshotTiming(candidate), expected)
) {
invalid();
}
}
function expectedSnapshot(
manifest: XtreamPerformanceManifest,
scenarioId: XtreamScenarioId
): XtreamCatalogDatabaseSnapshot {
if (!Object.values(XTREAM_SCENARIO_ID).includes(scenarioId)) {
invalid();
}
const empty = isEmptyScenario(scenarioId);
const deleted = scenarioId === XTREAM_SCENARIO_ID.DELETE_LARGE;
const cancelled = scenarioId === XTREAM_SCENARIO_ID.CANCEL_IMPORT;
const expected = {
captureStoppedEpochMs: 1,
categories: {
live: categoryPartition(
empty ? 0 : manifest.counts.categories.live,
91_101
),
movies: categoryPartition(
empty ? 0 : manifest.counts.categories.vod,
92_101
),
series: categoryPartition(
empty ? 0 : manifest.counts.categories.series,
93_101
),
},
categoryCount: empty ? 0 : manifest.counts.categories.total,
content: {
live: contentPartition(
empty ? 0 : manifest.counts.items.live,
1_000_000
),
movie: contentPartition(
empty ? 0 : manifest.counts.items.vod,
2_000_000
),
series: contentPartition(
empty ? 0 : manifest.counts.items.series,
3_000_000
),
},
contentCount: empty ? 0 : manifest.counts.items.total,
databaseReadStartedEpochMs: 1,
importStatuses: {
live: cancelled ? 'failed' : 'completed',
movie: cancelled ? 'failed' : 'completed',
series: cancelled ? 'failed' : 'completed',
},
matchingPlaylistCount: deleted ? 0 : 1,
matchingPlaylistType: deleted ? null : 'xtream',
playlistCount: deleted ? 0 : 1,
} satisfies XtreamCatalogDatabaseSnapshot;
return {
...expected,
captureStoppedEpochMs: Number.NaN,
databaseReadStartedEpochMs: Number.NaN,
};
}
function snapshotTopLevel(value: unknown): XtreamCatalogDatabaseSnapshot {
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
invalid();
}
return { ...value } as XtreamCatalogDatabaseSnapshot;
}
function isSnapshotTimingValid(
snapshot: XtreamCatalogDatabaseSnapshot
): boolean {
if (
!isPositiveFinite(snapshot.captureStoppedEpochMs) ||
!isPositiveFinite(snapshot.databaseReadStartedEpochMs) ||
snapshot.databaseReadStartedEpochMs < snapshot.captureStoppedEpochMs
) {
return false;
}
return true;
}
function withoutSnapshotTiming(
snapshot: XtreamCatalogDatabaseSnapshot
): XtreamCatalogDatabaseSnapshot {
return {
...snapshot,
captureStoppedEpochMs: Number.NaN,
databaseReadStartedEpochMs: Number.NaN,
};
}
function isEmptyScenario(scenarioId: XtreamScenarioId): boolean {
return (
scenarioId === XTREAM_SCENARIO_ID.CANCEL_IMPORT ||
scenarioId === XTREAM_SCENARIO_ID.DELETE_LARGE
);
}
function categoryPartition(
count: number,
firstXtreamId: number
): XtreamCatalogPartition {
return {
count,
distinctXtreamIdCount: count,
invalidNameCount: 0,
maxXtreamId: count === 0 ? null : firstXtreamId + count - 1,
minXtreamId: count === 0 ? null : firstXtreamId,
};
}
function contentPartition(
count: number,
firstXtreamId: number
): XtreamContentPartition {
return {
count,
distinctXtreamIdCount: count,
invalidCategoryCardinalityCount: 0,
invalidTitleCount: 0,
maxXtreamId: count === 0 ? null : firstXtreamId + count - 1,
minXtreamId: count === 0 ? null : firstXtreamId,
};
}
function isPositiveFinite(value: unknown): value is number {
return typeof value === 'number' && Number.isFinite(value) && value > 0;
}
function invalid(): never {
throw new Error('invalid');
}
@@ -0,0 +1,377 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import type {
XtreamControlState,
XtreamPerformanceManifest,
} from './xtream-benchmark-contract';
import { createXtreamControlClient } from './xtream-control-client';
const TOKEN = 'never-persist-this-control-token';
const MANIFEST: XtreamPerformanceManifest = {
epoch: 1,
scenario: 'performance-100k',
seed: 91_001,
counts: {
categories: { live: 60, vod: 20, series: 20, total: 100 },
items: {
live: 60_000,
vod: 20_000,
series: 20_000,
total: 100_000,
},
},
bytes: 100,
catalogSha256:
'abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789',
};
const STATE: XtreamControlState = {
epoch: 1,
prepared: MANIFEST,
rules: [],
heldIds: [],
heldCount: 0,
occurrences: [],
ledger: [],
};
describe('Xtream performance control client', () => {
it('exposes only fixed prepare, reset, and state operations', async () => {
const calls: RecordedCall[] = [];
const client = createXtreamControlClient({
origin: 'http://127.0.0.1:43123',
token: TOKEN,
fetchImpl: fakeFetch(calls),
});
assert.deepEqual(Object.keys(client).sort(), [
'prepare',
'resetAll',
'resetObservations',
'state',
]);
assert.deepEqual(await client.prepare(), MANIFEST);
await client.resetObservations();
await client.resetAll();
assert.deepEqual(await client.state(), STATE);
assert.deepEqual(
calls.map(({ body, method, path }) => ({ body, method, path })),
[
{
body: { scenario: 'performance-100k' },
method: 'POST',
path: '/__control/prepare',
},
{
body: { mode: 'observations' },
method: 'POST',
path: '/__control/reset',
},
{
body: { mode: 'all' },
method: 'POST',
path: '/__control/reset',
},
{
body: null,
method: 'GET',
path: '/__control/state',
},
]
);
assert.ok(
calls.every(
({ headers, redirect }) =>
redirect === 'error' &&
headers.get('x-iptvnator-performance-token') === TOKEN
)
);
assert.equal(
calls.at(-1)?.headers.get('content-type'),
null,
'GET must not carry a synthetic JSON body'
);
});
it('keeps the token closure-only and redacts transport failures', async () => {
const client = createXtreamControlClient({
origin: 'http://127.0.0.1:43123',
token: TOKEN,
fetchImpl: async () =>
new Response(
JSON.stringify({
error: TOKEN,
password: 'performance',
}),
{ status: 500 }
),
});
assert.doesNotMatch(JSON.stringify(client), new RegExp(TOKEN));
await assert.rejects(
() => client.prepare(),
(error: unknown) =>
error instanceof Error &&
/prepare failed with HTTP 500/.test(error.message) &&
!error.message.includes(TOKEN) &&
!error.message.includes('performance')
);
});
it('rejects redirects and a response finalized at any second origin', async () => {
let forwardedToken = false;
const client = createXtreamControlClient({
origin: 'http://127.0.0.1:43123',
token: TOKEN,
fetchImpl: async (_input, init) => {
if (init?.redirect !== 'error') {
forwardedToken = new Headers(init?.headers).has(
'x-iptvnator-performance-token'
);
}
return responseAt(
MANIFEST,
200,
'http://127.0.0.1:43124/__control/prepare'
);
},
});
await assert.rejects(
() => client.prepare(),
/redirect|origin|transport failed/
);
assert.equal(forwardedToken, false);
});
it('validates control responses without echoing their unsafe payloads', async () => {
const client = createXtreamControlClient({
origin: 'http://127.0.0.1:43123',
token: TOKEN,
fetchImpl: async () =>
responseAt(
{
username: 'performance',
secret: TOKEN,
},
200,
'http://127.0.0.1:43123/__control/state'
),
});
await assert.rejects(
() => client.state(),
(error: unknown) =>
error instanceof Error &&
/invalid control response/.test(error.message) &&
!error.message.includes(TOKEN) &&
!error.message.includes('performance')
);
});
it('sanitizes adversarial response metadata accessors', async () => {
for (const property of ['ok', 'status', 'redirected', 'url'] as const) {
const client = createXtreamControlClient({
origin: 'http://127.0.0.1:43123',
token: TOKEN,
fetchImpl: async (input) => {
const response = {
json: async () => MANIFEST,
ok: property === 'status' ? false : true,
redirected: false,
status: 200,
url: String(input),
};
Object.defineProperty(response, property, {
get() {
throw new Error(TOKEN);
},
});
return response as Response;
},
});
await assert.rejects(
() => client.prepare(),
(error: unknown) =>
error instanceof Error &&
/invalid response metadata/.test(error.message) &&
!error.message.includes(TOKEN)
);
}
});
it('sanitizes reset response Proxy failures', async () => {
const resetBody = new Proxy(
{},
{
ownKeys() {
throw new Error(TOKEN);
},
}
);
const client = createXtreamControlClient({
origin: 'http://127.0.0.1:43123',
token: TOKEN,
fetchImpl: async (input) =>
({
json: async () => resetBody,
ok: true,
redirected: false,
status: 200,
url: String(input),
}) as Response,
});
await assert.rejects(
() => client.resetAll(),
(error: unknown) =>
error instanceof Error &&
error.message === 'Xtream all reset invalid control response' &&
!error.message.includes(TOKEN)
);
});
it('rejects non-loopback origins and empty tokens before issuing I/O', () => {
let calls = 0;
const fetchImpl: typeof fetch = async () => {
calls += 1;
return new Response();
};
assert.throws(
() =>
createXtreamControlClient({
origin: 'https://provider.example',
token: TOKEN,
fetchImpl,
}),
/exact Xtream HTTP loopback origin/
);
assert.throws(
() =>
createXtreamControlClient({
origin: 'http://127.0.0.1:43123',
token: '',
fetchImpl,
}),
/non-empty control token/
);
assert.equal(calls, 0);
});
it('snapshots the validated origin and token before mutable getters can change them', async () => {
const calls: RecordedCall[] = [];
let currentOrigin = 'http://127.0.0.1:43123';
let currentToken = TOKEN;
let originReads = 0;
let tokenReads = 0;
const client = createXtreamControlClient({
fetchImpl: fakeFetch(calls),
get origin() {
originReads += 1;
return currentOrigin;
},
get token() {
tokenReads += 1;
return currentToken;
},
});
currentOrigin = 'https://provider.example';
currentToken = 'attacker-controlled-token';
await client.prepare();
assert.equal(originReads, 1);
assert.equal(tokenReads, 1);
assert.equal(calls[0]?.path, '/__control/prepare');
assert.equal(
calls[0]?.headers.get('x-iptvnator-performance-token'),
TOKEN
);
});
it('rejects invalid runtime token values before issuing I/O', () => {
let calls = 0;
const fetchImpl: typeof fetch = async () => {
calls += 1;
return new Response();
};
for (const token of [
null,
undefined,
42,
{},
' ',
'line\r\nbreak',
'x'.repeat(257),
]) {
assert.throws(
() =>
createXtreamControlClient({
origin: 'http://127.0.0.1:43123',
token,
fetchImpl,
} as unknown as Parameters<
typeof createXtreamControlClient
>[0]),
/non-empty control token/
);
}
assert.equal(calls, 0);
});
});
interface RecordedCall {
readonly body: Record<string, unknown> | null;
readonly headers: Headers;
readonly method: string;
readonly path: string;
readonly redirect: RequestRedirect | undefined;
}
function fakeFetch(calls: RecordedCall[]): typeof fetch {
return async (input, init) => {
const url = new URL(
typeof input === 'string'
? input
: input instanceof URL
? input.href
: input.url
);
const method = init?.method ?? 'GET';
const body =
typeof init?.body === 'string'
? (JSON.parse(init.body) as Record<string, unknown>)
: null;
calls.push({
body,
headers: new Headers(init?.headers),
method,
path: url.pathname,
redirect: init?.redirect,
});
if (url.pathname.endsWith('/prepare')) {
return responseAt(MANIFEST, 200, url.href);
}
if (url.pathname.endsWith('/reset')) {
return responseAt(
{
epoch: MANIFEST.epoch,
mode: body?.['mode'],
},
200,
url.href
);
}
return responseAt(STATE, 200, url.href);
};
}
function responseAt(value: unknown, status: number, url: string): Response {
const response = Response.json(value, { status });
Object.defineProperty(response, 'url', { value: url });
return response;
}
@@ -0,0 +1,273 @@
import type {
XtreamControlState,
XtreamPerformanceManifest,
XtreamScenarioId,
} from './xtream-benchmark-contract';
import {
assertXtreamArtifactRedacted,
assertXtreamManifest,
assertXtreamManifestIdentity,
} from './xtream-diagnostic-artifacts';
import {
parseXtreamControlState,
parseXtreamManifest,
} from './xtream-control-state-schema';
import { assertXtreamScenarioObservations } from './xtream-control-observation-contract';
export {
assertXtreamArtifactRedacted,
assertXtreamManifest,
assertXtreamManifestIdentity,
parseXtreamControlState,
parseXtreamManifest,
};
export interface XtreamControlClientOptions {
readonly fetchImpl?: typeof fetch;
readonly origin: string;
readonly token: string;
}
export interface XtreamControlClient {
prepare(): Promise<XtreamPerformanceManifest>;
resetAll(): Promise<void>;
resetObservations(): Promise<void>;
state(): Promise<XtreamControlState>;
}
export function createXtreamControlClient(
options: XtreamControlClientOptions
): XtreamControlClient {
let origin: string;
let token: string;
let configuredFetch: typeof fetch | undefined;
try {
origin = options.origin;
token = options.token;
configuredFetch = options.fetchImpl;
} catch {
throw new Error('Xtream benchmark control options are invalid');
}
assertXtreamMockOrigin(origin);
if (!isValidControlToken(token)) {
throw new Error('Xtream benchmark requires a non-empty control token');
}
const fetchImpl = configuredFetch ?? globalThis.fetch;
const request = async (
path: '/__control/prepare' | '/__control/reset' | '/__control/state',
label: string,
body?: Readonly<Record<string, string>>
): Promise<unknown> => {
let response: Response;
const requestUrl = `${origin}${path}`;
try {
response = await fetchImpl(requestUrl, {
method: body ? 'POST' : 'GET',
redirect: 'error',
headers: {
'x-iptvnator-performance-token': token,
...(body ? { 'content-type': 'application/json' } : {}),
},
...(body ? { body: JSON.stringify(body) } : {}),
});
} catch {
throw new Error(`Xtream control ${label} transport failed`);
}
const metadata = snapshotControlResponse(response, label);
if (!metadata.ok) {
throw new Error(
`Xtream control ${label} failed with HTTP ${metadata.status}`
);
}
if (metadata.redirected || metadata.url !== requestUrl) {
throw new Error(
`Xtream control ${label} redirect or origin rejected`
);
}
try {
return (await Reflect.apply(
metadata.json,
response,
[]
)) as unknown;
} catch {
throw new Error(`Xtream ${label} invalid control response`);
}
};
const reset = async (mode: 'all' | 'observations'): Promise<void> => {
const value = await request('/__control/reset', `${mode} reset`, {
mode,
});
try {
if (!isRecordWithKeys(value, ['epoch', 'mode'])) {
throw new Error('invalid reset response');
}
const epoch = Reflect.get(value, 'epoch');
const responseMode = Reflect.get(value, 'mode');
if (!isPositiveSafeInteger(epoch) || responseMode !== mode) {
throw new Error('invalid reset response');
}
} catch {
throw new Error(`Xtream ${mode} reset invalid control response`);
}
};
return Object.freeze({
async prepare() {
const value = await request('/__control/prepare', 'prepare', {
scenario: 'performance-100k',
});
try {
return parseXtreamManifest(value);
} catch {
throw new Error('Xtream prepare invalid control response');
}
},
resetAll: () => reset('all'),
resetObservations: () => reset('observations'),
async state() {
const value = await request('/__control/state', 'state');
try {
return parseXtreamControlState(value);
} catch {
throw new Error('Xtream state invalid control response');
}
},
});
}
export function assertXtreamMockOrigin(value: unknown): void {
if (typeof value !== 'string') throw invalidOrigin();
let url: URL;
try {
url = new URL(value);
} catch {
throw invalidOrigin();
}
if (
url.protocol !== 'http:' ||
url.hostname !== '127.0.0.1' ||
url.port.length === 0 ||
url.username.length > 0 ||
url.password.length > 0 ||
url.pathname !== '/' ||
url.search.length > 0 ||
url.hash.length > 0 ||
value !== url.origin
) {
throw invalidOrigin();
}
}
function snapshotControlResponse(
response: Response,
label: string
): {
readonly json: () => Promise<unknown>;
readonly ok: boolean;
readonly redirected: boolean;
readonly status: number;
readonly url: string;
} {
try {
const json = Reflect.get(response, 'json') as unknown;
const ok = Reflect.get(response, 'ok') as unknown;
const redirected = Reflect.get(response, 'redirected') as unknown;
const status = Reflect.get(response, 'status') as unknown;
const url = Reflect.get(response, 'url') as unknown;
if (
typeof json !== 'function' ||
typeof ok !== 'boolean' ||
typeof redirected !== 'boolean' ||
!Number.isSafeInteger(status) ||
Number(status) < 100 ||
Number(status) > 599 ||
typeof url !== 'string'
) {
throw new Error('invalid response metadata');
}
return {
json: json as () => Promise<unknown>,
ok,
redirected,
status: Number(status),
url,
};
} catch {
throw new Error(`Xtream control ${label} invalid response metadata`);
}
}
export function assertXtreamControlReadyAfterObservationReset(
input: unknown,
expectedManifest: XtreamPerformanceManifest
): asserts input is XtreamControlState {
try {
const state = parseXtreamControlState(input);
assertPreparedState(state, expectedManifest);
if (state.occurrences.length !== 0 || state.ledger.length !== 0) {
throw new Error('observations remain');
}
} catch {
throw new Error(
'invalid Xtream mock readiness after observation reset'
);
}
}
export function assertXtreamControlStateForScenario(
scenarioId: XtreamScenarioId,
input: unknown,
expectedManifest: XtreamPerformanceManifest
): asserts input is XtreamControlState {
try {
const state = parseXtreamControlState(input);
assertPreparedState(state, expectedManifest);
assertXtreamScenarioObservations(scenarioId, state);
} catch {
throw new Error('invalid Xtream mock observations');
}
}
function assertPreparedState(
state: XtreamControlState,
manifest: XtreamPerformanceManifest
): void {
if (
state.prepared === null ||
state.epoch !== manifest.epoch ||
state.prepared.epoch !== manifest.epoch ||
state.rules.length !== 0 ||
state.heldCount !== 0 ||
state.heldIds.length !== 0
) {
throw new Error('state residue');
}
assertXtreamManifestIdentity(manifest, state.prepared);
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
function isRecordWithKeys(
value: unknown,
keys: readonly string[]
): value is Record<string, unknown> {
return (
isRecord(value) &&
Object.keys(value).length === keys.length &&
keys.every((key) => Object.prototype.hasOwnProperty.call(value, key))
);
}
function isPositiveSafeInteger(value: unknown): value is number {
return Number.isSafeInteger(value) && Number(value) > 0;
}
function isValidControlToken(value: unknown): value is string {
return typeof value === 'string' && /^[\x21-\x7e]{1,256}$/u.test(value);
}
function invalidOrigin(): Error {
return new Error('mock must use the exact Xtream HTTP loopback origin');
}
@@ -0,0 +1,223 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_SCENARIO_ID,
type XtreamControlState,
type XtreamPerformanceManifest,
} from './xtream-benchmark-contract';
import { assertXtreamControlStateForScenario } from './xtream-control-client';
const MANIFEST: XtreamPerformanceManifest = {
epoch: 1,
scenario: 'performance-100k',
seed: 91_001,
counts: {
categories: { live: 60, vod: 20, series: 20, total: 100 },
items: {
live: 60_000,
vod: 20_000,
series: 20_000,
total: 100_000,
},
},
bytes: 12_345_678,
catalogSha256:
'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
};
const FULL_ACTIONS = [
'get_account_info',
'get_live_categories',
'get_vod_categories',
'get_series_categories',
'get_live_streams',
'get_vod_streams',
'get_series',
] as const;
describe('Xtream mock observation contract', () => {
it('models exact account-info multiplicity for every measured window', () => {
assert.doesNotThrow(() =>
validate(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
controlState(FULL_ACTIONS, 2)
)
);
assert.doesNotThrow(() =>
validate(
XTREAM_SCENARIO_ID.CANCEL_IMPORT,
controlState(FULL_ACTIONS.slice(0, 5), 2)
)
);
for (const scenarioId of [
XTREAM_SCENARIO_ID.REFRESH_LARGE,
XTREAM_SCENARIO_ID.BACKGROUND_UI,
] as const) {
assert.doesNotThrow(() =>
validate(scenarioId, controlState(FULL_ACTIONS, 2, true))
);
}
assert.doesNotThrow(() =>
validate(XTREAM_SCENARIO_ID.DELETE_LARGE, controlState([], 0))
);
});
it('rejects account-info multiplicity from a different scenario window', () => {
for (const [scenarioId, state] of [
[
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
controlState(FULL_ACTIONS, 1),
],
[
XTREAM_SCENARIO_ID.CANCEL_IMPORT,
controlState(FULL_ACTIONS.slice(0, 5), 1),
],
[XTREAM_SCENARIO_ID.REFRESH_LARGE, controlState(FULL_ACTIONS, 1)],
[XTREAM_SCENARIO_ID.BACKGROUND_UI, controlState(FULL_ACTIONS, 1)],
] as const) {
assert.throws(
() => validate(scenarioId, state),
/invalid Xtream mock observations/
);
}
for (const scenarioId of [
XTREAM_SCENARIO_ID.REFRESH_LARGE,
XTREAM_SCENARIO_ID.BACKGROUND_UI,
] as const) {
assert.throws(
() => validate(scenarioId, controlState(FULL_ACTIONS, 2)),
/invalid Xtream mock observations/
);
}
});
it('allows account overlap but requires complete route-account causality', () => {
const exact = controlState(FULL_ACTIONS, 2);
const duplicateArrival = {
...exact,
ledger: exact.ledger.map((entry) =>
entry.action === 'get_account_info' &&
entry.occurrence === 2 &&
entry.status === 'responded'
? { ...entry, status: 'arrived' }
: entry
),
};
const overlappingAccounts = {
...exact,
ledger: exact.ledger.map((entry) =>
entry.action === 'get_account_info' &&
entry.occurrence === 1 &&
entry.status === 'responded'
? { ...entry, atMs: 25 }
: entry
),
};
const routeAccountAfterCategories = {
...exact,
ledger: exact.ledger.map((entry) =>
entry.action === 'get_account_info' &&
entry.occurrence === 2 &&
entry.status === 'responded'
? { ...entry, atMs: 35 }
: entry
),
};
const reversedAccountStarts = {
...exact,
ledger: exact.ledger.map((entry) =>
entry.action === 'get_account_info' &&
entry.occurrence === 2 &&
entry.status === 'arrived'
? { ...entry, atMs: 9 }
: entry
),
};
assert.doesNotThrow(() =>
validate(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
overlappingAccounts
)
);
for (const invalid of [
duplicateArrival,
reversedAccountStarts,
routeAccountAfterCategories,
]) {
assert.throws(
() =>
validate(XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE, invalid),
/invalid Xtream mock observations/
);
}
});
});
function validate(
scenarioId: Parameters<typeof assertXtreamControlStateForScenario>[0],
state: XtreamControlState
): void {
assertXtreamControlStateForScenario(scenarioId, state, MANIFEST);
}
function controlState(
actions: readonly string[],
accountCount: number,
routeAccountAfterContent = false
): XtreamControlState {
const counts = new Map(
actions.map((action) => [
action,
action === 'get_account_info' ? accountCount : 1,
])
);
let order = 1;
return {
epoch: MANIFEST.epoch,
prepared: MANIFEST,
rules: [],
heldIds: [],
heldCount: 0,
occurrences: [...counts].map(([action, count]) => ({
scenario: 'performance-100k',
transport: 'direct',
action,
categoryId: 'all',
count,
})),
ledger: [...counts].flatMap(([action, count]) =>
Array.from({ length: count }, (_, index) => {
const routeAccount =
routeAccountAfterContent &&
action === 'get_account_info' &&
index === 1;
const arrived = routeAccount ? 1_000 : order++ * 10;
return [
{
scenario: 'performance-100k',
transport: 'direct',
action,
categoryId: 'all',
epoch: MANIFEST.epoch,
occurrence: index + 1,
status: 'arrived',
atMs: arrived,
},
{
scenario: 'performance-100k',
transport: 'direct',
action,
categoryId: 'all',
epoch: MANIFEST.epoch,
occurrence: index + 1,
status: 'responded',
atMs: arrived + 1,
},
];
}).flat()
),
};
}
@@ -0,0 +1,204 @@
import {
XTREAM_SCENARIO_ID,
type XtreamControlState,
type XtreamLedgerEntry,
type XtreamOccurrence,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
const FULL_ACTIONS = [
'get_account_info',
'get_live_categories',
'get_vod_categories',
'get_series_categories',
'get_live_streams',
'get_vod_streams',
'get_series',
] as const;
const CATEGORY_ACTIONS = FULL_ACTIONS.slice(1, 4);
interface ExpectedAction {
readonly action: string;
readonly count: number;
}
interface RequestLifecycle {
readonly arrived: number;
readonly responded: number;
}
export function assertXtreamScenarioObservations(
scenarioId: XtreamScenarioId,
state: XtreamControlState
): void {
const expected = expectedActions(scenarioId);
if (
state.occurrences.length !== expected.length ||
state.ledger.length !==
expected.reduce((total, entry) => total + entry.count * 2, 0)
) {
throw new Error('action cardinality');
}
const lifecycle = new Map<string, readonly RequestLifecycle[]>();
for (const expectedAction of expected) {
const occurrences = state.occurrences.filter(
(entry) => entry.action === expectedAction.action
);
const entries = state.ledger.filter(
(entry) => entry.action === expectedAction.action
);
if (
occurrences.length !== 1 ||
!isExpectedOccurrence(occurrences[0], expectedAction.count) ||
entries.length !== expectedAction.count * 2
) {
throw new Error('action occurrence');
}
const requests = Array.from(
{ length: expectedAction.count },
(_, index) => requestLifecycle(entries, state.epoch, index + 1)
);
assertOccurrenceStartOrder(requests);
lifecycle.set(expectedAction.action, requests);
}
if (
state.occurrences.some(
(entry) => !expected.some(({ action }) => action === entry.action)
) ||
state.ledger.some(
(entry) => !expected.some(({ action }) => action === entry.action)
)
) {
throw new Error('unexpected action');
}
assertActionOrder(scenarioId, expected, lifecycle);
}
function expectedActions(
scenarioId: XtreamScenarioId
): readonly ExpectedAction[] {
if (scenarioId === XTREAM_SCENARIO_ID.DELETE_LARGE) return [];
const actions =
scenarioId === XTREAM_SCENARIO_ID.CANCEL_IMPORT
? FULL_ACTIONS.slice(0, 5)
: FULL_ACTIONS;
return actions.map((action) => ({
action,
count: action === 'get_account_info' ? 2 : 1,
}));
}
function requestLifecycle(
entries: readonly XtreamLedgerEntry[],
epoch: number,
occurrence: number
): RequestLifecycle {
const requestEntries = entries.filter(
(entry) => entry.occurrence === occurrence
);
const arrived = requestEntries.find((entry) => entry.status === 'arrived');
const responded = requestEntries.find(
(entry) => entry.status === 'responded'
);
if (
requestEntries.length !== 2 ||
!isExpectedLedger(arrived, epoch, occurrence) ||
!isExpectedLedger(responded, epoch, occurrence) ||
arrived.status !== 'arrived' ||
responded.status !== 'responded' ||
arrived.atMs > responded.atMs
) {
throw new Error('action lifecycle');
}
return { arrived: arrived.atMs, responded: responded.atMs };
}
function assertOccurrenceStartOrder(
requests: readonly RequestLifecycle[]
): void {
for (let index = 1; index < requests.length; index += 1) {
if (
(requests[index - 1]?.arrived ?? Number.POSITIVE_INFINITY) >
(requests[index]?.arrived ?? Number.NEGATIVE_INFINITY)
) {
throw new Error('occurrence start order');
}
}
}
function assertActionOrder(
scenarioId: XtreamScenarioId,
expected: readonly ExpectedAction[],
lifecycle: ReadonlyMap<string, readonly RequestLifecycle[]>
): void {
if (expected.length === 0) return;
const accounts = lifecycle.get('get_account_info');
const routeHydratesAfterImport =
scenarioId === XTREAM_SCENARIO_ID.REFRESH_LARGE ||
scenarioId === XTREAM_SCENARIO_ID.BACKGROUND_UI;
const account = routeHydratesAfterImport ? accounts?.[0] : accounts?.at(-1);
const liveCategory = lifecycle.get(CATEGORY_ACTIONS[0])?.[0];
const vodCategory = lifecycle.get(CATEGORY_ACTIONS[1])?.[0];
const seriesCategory = lifecycle.get(CATEGORY_ACTIONS[2])?.[0];
const live = lifecycle.get('get_live_streams')?.[0];
if (
!account ||
!liveCategory ||
!vodCategory ||
!seriesCategory ||
account.responded >
Math.min(
liveCategory.arrived,
vodCategory.arrived,
seriesCategory.arrived
) ||
!live ||
Math.max(
liveCategory.responded,
vodCategory.responded,
seriesCategory.responded
) > live.arrived
) {
throw new Error('action order');
}
const vod = lifecycle.get('get_vod_streams')?.[0];
const series = lifecycle.get('get_series')?.[0];
if (
(vod && live.responded > vod.arrived) ||
(series && (!vod || vod.responded > series.arrived)) ||
(routeHydratesAfterImport &&
(!series ||
!accounts?.[1] ||
series.responded > accounts[1].arrived))
) {
throw new Error('content order');
}
}
function isExpectedOccurrence(
value: XtreamOccurrence | undefined,
count: number
): boolean {
return (
value?.scenario === 'performance-100k' &&
value.transport === 'direct' &&
value.categoryId === 'all' &&
value.count === count
);
}
function isExpectedLedger(
value: XtreamLedgerEntry | undefined,
epoch: number,
occurrence: number
): value is XtreamLedgerEntry {
return (
value?.scenario === 'performance-100k' &&
value.transport === 'direct' &&
value.categoryId === 'all' &&
value.epoch === epoch &&
value.occurrence === occurrence
);
}
@@ -0,0 +1,167 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import type {
XtreamControlState,
XtreamPerformanceManifest,
} from './xtream-benchmark-contract';
import { parseXtreamControlState } from './xtream-control-state-schema';
const MANIFEST: XtreamPerformanceManifest = {
epoch: 1,
scenario: 'performance-100k',
seed: 91_001,
counts: {
categories: { live: 60, vod: 20, series: 20, total: 100 },
items: {
live: 60_000,
vod: 20_000,
series: 20_000,
total: 100_000,
},
},
bytes: 100,
catalogSha256:
'abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789',
};
const OCCURRENCE = {
scenario: 'performance-100k',
transport: 'direct',
action: 'get_account_info',
categoryId: 'all',
count: 1,
};
const LEDGER = {
scenario: 'performance-100k',
transport: 'direct',
action: 'get_account_info',
categoryId: 'all',
epoch: 1,
occurrence: 1,
status: 'arrived',
atMs: 1,
};
describe('Xtream control-state exact schema', () => {
it('requires exact occurrence and ledger records with known lifecycle states', () => {
const populated = state();
assert.doesNotThrow(() => parseXtreamControlState(populated));
for (const invalid of [
{
...populated,
occurrences: [{ ...OCCURRENCE, injected: true }],
},
{
...populated,
ledger: [{ ...LEDGER, injected: true }],
},
{
...populated,
ledger: [{ ...LEDGER, status: 'completed' }],
},
]) {
assert.throws(
() => parseXtreamControlState(invalid),
/^Error: invalid control response$/
);
}
});
it('returns a stable deep-frozen snapshot of nested accessor values', () => {
let epoch = 1;
let manifestBytes = MANIFEST.bytes;
let occurrenceAction = OCCURRENCE.action;
let ledgerStatus = LEDGER.status;
const input = withAccessor(
{
...state(),
prepared: withAccessor(
{ ...MANIFEST },
'bytes',
() => manifestBytes
),
occurrences: [
withAccessor(
{ ...OCCURRENCE },
'action',
() => occurrenceAction
),
],
ledger: [
withAccessor({ ...LEDGER }, 'status', () => ledgerStatus),
],
},
'epoch',
() => epoch
);
const parsed = parseXtreamControlState(input);
epoch = 2;
manifestBytes = 0;
occurrenceAction = 'unknown';
ledgerStatus = 'completed';
assert.equal(parsed.epoch, 1);
assert.equal(parsed.prepared?.bytes, MANIFEST.bytes);
assert.equal(parsed.occurrences[0]?.action, 'get_account_info');
assert.equal(parsed.ledger[0]?.status, 'arrived');
assert.ok(Object.isFrozen(parsed));
assert.ok(Object.isFrozen(parsed.prepared));
assert.ok(Object.isFrozen(parsed.prepared?.counts));
assert.ok(Object.isFrozen(parsed.occurrences));
assert.ok(Object.isFrozen(parsed.occurrences[0]));
assert.ok(Object.isFrozen(parsed.ledger));
assert.ok(Object.isFrozen(parsed.ledger[0]));
});
it('sanitizes proxy and nested getter failures', () => {
const secret = 'must-not-escape-control-state';
const proxy = new Proxy(
{},
{
ownKeys() {
throw new Error(secret);
},
}
);
const nested = state();
Object.defineProperty(nested.prepared, 'bytes', {
enumerable: true,
get() {
throw new Error(secret);
},
});
for (const invalid of [proxy, nested]) {
assert.throws(
() => parseXtreamControlState(invalid),
(error: unknown) =>
error instanceof Error &&
error.message === 'invalid control response' &&
!error.message.includes(secret)
);
}
});
});
function state(): XtreamControlState {
return {
epoch: 1,
prepared: structuredClone(MANIFEST),
rules: [],
heldIds: [],
heldCount: 0,
occurrences: [{ ...OCCURRENCE }],
ledger: [{ ...LEDGER }],
};
}
function withAccessor<T extends object, K extends keyof T>(
value: T,
key: K,
get: () => T[K]
): T {
Object.defineProperty(value, key, { enumerable: true, get });
return value;
}
@@ -0,0 +1,314 @@
import type {
XtreamCatalogCounts,
XtreamControlState,
XtreamLedgerEntry,
XtreamOccurrence,
XtreamPerformanceManifest,
} from './xtream-benchmark-contract';
const LIFECYCLE_STATUSES = [
'aborted',
'arrived',
'blocked',
'delayed',
'responded',
] as const;
const STATE_KEYS = [
'epoch',
'prepared',
'rules',
'heldIds',
'heldCount',
'occurrences',
'ledger',
] as const;
const MANIFEST_KEYS = [
'epoch',
'scenario',
'seed',
'counts',
'bytes',
'catalogSha256',
] as const;
const MAX_CONTROL_ARRAY_LENGTH = 4_096;
export function parseXtreamControlState(value: unknown): XtreamControlState {
try {
const input = snapshotExactRecord(value, STATE_KEYS);
const heldIds = snapshotArray(input['heldIds']);
const occurrences = snapshotArray(input['occurrences']).map(
snapshotOccurrence
);
const ledger = snapshotArray(input['ledger']).map(snapshotLedger);
const rules = snapshotArray(input['rules']).map((entry) =>
snapshotJsonValue(entry, new WeakSet())
);
if (
!isPositiveSafeInteger(input['epoch']) ||
!heldIds.every((entry) => typeof entry === 'string') ||
!isNonNegativeSafeInteger(input['heldCount']) ||
input['heldCount'] !== heldIds.length
) {
invalid();
}
const prepared =
input['prepared'] === null
? null
: snapshotManifest(input['prepared']);
return freezeDeep({
epoch: input['epoch'],
prepared,
rules,
heldIds: heldIds as string[],
heldCount: input['heldCount'],
occurrences,
ledger,
}) as XtreamControlState;
} catch {
invalid();
}
}
export function parseXtreamManifest(value: unknown): XtreamPerformanceManifest {
try {
return freezeDeep(snapshotManifest(value));
} catch {
throw invalidManifest();
}
}
export function assertXtreamManifest(
value: unknown
): asserts value is XtreamPerformanceManifest {
parseXtreamManifest(value);
}
export function assertXtreamManifestIdentity(
expected: XtreamPerformanceManifest,
actual: unknown
): asserts actual is XtreamPerformanceManifest {
const expectedSnapshot = parseXtreamManifest(expected);
const actualSnapshot = parseXtreamManifest(actual);
const identity = (manifest: XtreamPerformanceManifest) => [
manifest.scenario,
manifest.seed,
manifest.counts,
manifest.bytes,
manifest.catalogSha256,
];
if (
JSON.stringify(identity(expectedSnapshot)) !==
JSON.stringify(identity(actualSnapshot))
) {
throw new Error('Xtream performance fixture identity changed');
}
}
function snapshotManifest(value: unknown): XtreamPerformanceManifest {
const input = snapshotExactRecord(value, MANIFEST_KEYS);
const counts = snapshotExactRecord(input['counts'], [
'categories',
'items',
]);
const categories = snapshotCounts(counts['categories'], [60, 20, 20, 100]);
const items = snapshotCounts(
counts['items'],
[60_000, 20_000, 20_000, 100_000]
);
if (
!isPositiveSafeInteger(input['epoch']) ||
input['scenario'] !== 'performance-100k' ||
input['seed'] !== 91_001 ||
!isPositiveSafeInteger(input['bytes']) ||
typeof input['catalogSha256'] !== 'string' ||
!/^[a-f0-9]{64}$/u.test(input['catalogSha256'])
) {
throw invalidManifest();
}
return {
epoch: input['epoch'],
scenario: input['scenario'],
seed: input['seed'],
counts: { categories, items },
bytes: input['bytes'],
catalogSha256: input['catalogSha256'],
};
}
function snapshotCounts(
value: unknown,
expected: readonly number[]
): XtreamCatalogCounts {
const input = snapshotExactRecord(value, [
'live',
'vod',
'series',
'total',
]);
const actual = [
input['live'],
input['vod'],
input['series'],
input['total'],
];
if (actual.some((entry, index) => entry !== expected[index])) {
throw invalidManifest();
}
return {
live: input['live'] as number,
vod: input['vod'] as number,
series: input['series'] as number,
total: input['total'] as number,
};
}
function snapshotOccurrence(value: unknown): XtreamOccurrence {
const input = snapshotExactRecord(value, [
'scenario',
'transport',
'action',
'categoryId',
'count',
]);
if (
!['scenario', 'transport', 'action', 'categoryId'].every(
(key) => typeof input[key] === 'string'
) ||
!isPositiveSafeInteger(input['count'])
) {
invalid();
}
return input as unknown as XtreamOccurrence;
}
function snapshotLedger(value: unknown): XtreamLedgerEntry {
const input = snapshotExactRecord(value, [
'scenario',
'transport',
'action',
'categoryId',
'epoch',
'occurrence',
'status',
'atMs',
]);
if (
!['scenario', 'transport', 'action', 'categoryId'].every(
(key) => typeof input[key] === 'string'
) ||
typeof input['status'] !== 'string' ||
!LIFECYCLE_STATUSES.includes(input['status'] as never) ||
!isPositiveSafeInteger(input['epoch']) ||
!isPositiveSafeInteger(input['occurrence']) ||
!isFiniteNonNegative(input['atMs'])
) {
invalid();
}
return input as unknown as XtreamLedgerEntry;
}
function snapshotExactRecord(
value: unknown,
expectedKeys: readonly string[]
): Record<string, unknown> {
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
invalid();
}
const keys = Reflect.ownKeys(value);
if (
keys.length !== expectedKeys.length ||
keys.some(
(key) => typeof key !== 'string' || !expectedKeys.includes(key)
)
) {
invalid();
}
return Object.fromEntries(
expectedKeys.map((key) => [key, Reflect.get(value, key)])
);
}
function snapshotArray(value: unknown): unknown[] {
if (!Array.isArray(value)) invalid();
const length = Reflect.get(value, 'length') as unknown;
if (
!isNonNegativeSafeInteger(length) ||
length > MAX_CONTROL_ARRAY_LENGTH
) {
invalid();
}
const expected = new Set([
'length',
...Array.from({ length }, (_, index) => String(index)),
]);
const keys = Reflect.ownKeys(value);
if (
keys.length !== expected.size ||
keys.some((key) => typeof key !== 'string' || !expected.has(key))
) {
invalid();
}
return Array.from({ length }, (_, index) =>
Reflect.get(value, String(index))
);
}
function snapshotJsonValue(value: unknown, stack: WeakSet<object>): unknown {
if (
value === null ||
typeof value === 'string' ||
typeof value === 'boolean' ||
(typeof value === 'number' && Number.isFinite(value))
) {
return value;
}
if (typeof value !== 'object') invalid();
if (stack.has(value)) invalid();
stack.add(value);
try {
if (Array.isArray(value)) {
return snapshotArray(value).map((entry) =>
snapshotJsonValue(entry, stack)
);
}
const keys = Reflect.ownKeys(value);
if (keys.some((key) => typeof key !== 'string')) invalid();
const input = snapshotExactRecord(value, keys as string[]);
return Object.fromEntries(
(keys as string[]).map((key) => [
key,
snapshotJsonValue(input[key], stack),
])
);
} finally {
stack.delete(value);
}
}
function freezeDeep<T>(value: T): T {
if (value && typeof value === 'object' && !Object.isFrozen(value)) {
Object.values(value).forEach(freezeDeep);
Object.freeze(value);
}
return value;
}
function isPositiveSafeInteger(value: unknown): value is number {
return Number.isSafeInteger(value) && Number(value) > 0;
}
function isNonNegativeSafeInteger(value: unknown): value is number {
return Number.isSafeInteger(value) && Number(value) >= 0;
}
function isFiniteNonNegative(value: unknown): value is number {
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
}
function invalid(): never {
throw new Error('invalid control response');
}
function invalidManifest(): Error {
return new Error('invalid Xtream performance manifest');
}
@@ -0,0 +1,141 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_MAIN_PERFORMANCE_PHASE,
XTREAM_PRELOAD_PERFORMANCE_METHOD,
XtreamCodeActions,
} from '@iptvnator/shared/interfaces';
import {
createXtreamIpcMarkerCapture,
type XtreamIpcMarkerCaptureOptions,
} from './xtream-ipc-marker-events';
const options: XtreamIpcMarkerCaptureOptions = {
actions: Object.values(XtreamCodeActions),
mainPhases: Object.values(XTREAM_MAIN_PERFORMANCE_PHASE),
methods: Object.values(XTREAM_PRELOAD_PERFORMANCE_METHOD),
schemaVersion: 1,
};
describe('Xtream playlist delete correlation', () => {
it('correlates the follow-up playlist delete without fabricating an operation ID', () => {
const capture = createXtreamIpcMarkerCapture(options);
capture.start(42, 90);
assert.equal(capture.acceptPreload(42, 100, deleteMarker()), true);
assert.deepEqual(capture.matchDatabaseRequest(deleteRequest()), {
ipcCallId: 1,
operationId: 'operation-1',
operationIdUnavailableReason: null,
sourceEpochMs: 100,
});
assert.equal(
capture.acceptPreload(
42,
102,
deleteMarker({
boundary: 'end',
outcome: 'success',
sourceEpochMs: 101,
})
),
true
);
const followUp = deleteMarker({
ipcCallId: 2,
operationId: null,
sourceEpochMs: 103,
});
assert.equal(capture.acceptPreload(42, 104, followUp), true);
assert.deepEqual(
capture.matchDatabaseRequest(
deleteRequest({ operationId: undefined })
),
{
ipcCallId: 2,
operationId: null,
operationIdUnavailableReason: null,
sourceEpochMs: 103,
}
);
assert.equal(
capture.acceptPreload(
42,
106,
deleteMarker({
...followUp,
boundary: 'end',
outcome: 'success',
sourceEpochMs: 105,
})
),
true
);
assert.deepEqual(capture.stop().invalidReasons, []);
});
it('quarantines overlapping deletes that share the explicit no-operation-ID key', () => {
const capture = createXtreamIpcMarkerCapture(options);
capture.start(42, 90);
const first = deleteMarker({ operationId: null });
assert.equal(capture.acceptPreload(42, 100, first), true);
assert.equal(
capture.acceptPreload(
42,
101,
deleteMarker({
ipcCallId: 2,
operationId: null,
sourceEpochMs: 101,
})
),
false
);
assert.deepEqual(
capture.matchDatabaseRequest(deleteRequest({ operationId: null })),
{
ipcCallId: null,
operationId: null,
operationIdUnavailableReason:
'xtream-preload-performance-marker-ambiguous',
sourceEpochMs: null,
}
);
assert.equal(capture.stop().quarantinedKeyCount, 1);
});
});
function deleteMarker(overrides: Record<string, unknown> = {}) {
return {
action: null,
boundary: 'start',
categoryType: null,
contentType: null,
ipcCallId: 1,
itemCount: null,
method: 'dbDeletePlaylist',
operationId: 'operation-1',
outcome: null,
playlistId: 'playlist-1',
schemaVersion: 1,
sessionId: null,
sourceEpochMs: 100,
...overrides,
};
}
function deleteRequest(
payloadOverrides: Record<string, unknown> = {}
): Record<string, unknown> {
return {
operation: 'DB_DELETE_PLAYLIST',
payload: {
operationId: 'operation-1',
playlistId: 'playlist-1',
...payloadOverrides,
},
};
}
@@ -0,0 +1,143 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_ITERATION_KIND,
XTREAM_SCENARIO_ID,
type XtreamIterationDefinition,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import { iteration } from './xtream-benchmark-report.fixtures';
import { assertXtreamIterationResult } from './xtream-iteration-validity';
import type {
XtreamCancellationEvidence,
XtreamRawIterationResult,
} from './xtream-summary-contract';
describe('Xtream raw descriptor integrity', () => {
it('rejects symbol and non-enumerable top-level extras', () => {
for (const key of [Symbol('extra'), 'hiddenExtra'] as const) {
const raw = createIteration();
Object.defineProperty(raw, key, { value: true });
assert.throws(
() => assertXtreamIterationResult(raw),
/invalid Xtream iteration/
);
}
});
it('rejects symbol extras on cancellation records', () => {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const evidence = cancellationEvidence(raw);
Object.defineProperty(evidence.timeline[0], Symbol('extra'), {
value: true,
});
assert.throws(
() => assertXtreamIterationResult(raw),
/invalid Xtream iteration/
);
});
it('rejects a cancellation timeline accessor without invoking it', () => {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const evidence = cancellationEvidence(raw);
let invocations = 0;
const accessorEvidence = {};
Object.defineProperty(accessorEvidence, 'timeline', {
enumerable: true,
get() {
invocations += 1;
return evidence.timeline;
},
});
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
cancellationEvidence:
accessorEvidence as XtreamCancellationEvidence,
}),
/invalid Xtream iteration/
);
assert.equal(invocations, 0);
});
it('rejects cancellation record accessors without invoking them', () => {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const evidence = cancellationEvidence(raw);
const original = evidence.timeline[0];
let invocations = 0;
const accessorRecord = { ...original };
Object.defineProperty(accessorRecord, 'epochMs', {
enumerable: true,
get() {
invocations += 1;
return original.epochMs;
},
});
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
cancellationEvidence: {
timeline: [
accessorRecord,
...evidence.timeline.slice(1),
],
},
}),
/invalid Xtream iteration/
);
assert.equal(invocations, 0);
});
it('rejects every own cancellation timeline key beyond dense indices and length', () => {
for (const extraKey of [
Symbol('extra'),
'hiddenExtra',
'map',
] as const) {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const evidence = cancellationEvidence(raw);
const timeline = [...evidence.timeline];
Object.defineProperty(timeline, extraKey, {
value:
extraKey === 'map'
? Array.prototype.map.bind(timeline)
: true,
});
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
cancellationEvidence: { timeline },
}),
/invalid Xtream iteration/
);
}
});
});
function cancellationEvidence(
raw: XtreamRawIterationResult
): XtreamCancellationEvidence {
assert.ok(raw.cancellationEvidence);
return raw.cancellationEvidence;
}
function createIteration(
scenarioId: XtreamScenarioId = XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE
): XtreamRawIterationResult {
const definition: XtreamIterationDefinition = {
eligibleForComparison: true,
kind: XTREAM_ITERATION_KIND.MEASURED,
runId: 'run-01',
scenarioId,
};
return iteration(definition, 1);
}
@@ -0,0 +1,392 @@
import assert from 'node:assert/strict';
import {
mkdir,
mkdtemp,
rm,
symlink,
unlink,
writeFile,
} from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, describe, it } from 'node:test';
import { CPU_PROFILE } from './initial-import-diagnostic-test-fixtures';
import {
assertXtreamDiagnosticArtifactEvidence,
validateXtreamDiagnosticArtifacts,
type XtreamDiagnosticCapture,
} from './xtream-diagnostic-artifacts';
const HEAP_SNAPSHOT = {
edges: [0, 0, 0],
nodes: [0, 0, 1, 0, 1, 0],
snapshot: {
meta: {
edge_fields: ['type', 'name_or_index', 'to_node'],
edge_types: [['context'], 'string_or_number', 'node'],
node_fields: [
'type',
'name',
'id',
'self_size',
'edge_count',
'detachedness',
],
node_types: [
['hidden'],
'string',
'number',
'number',
'number',
'number',
],
},
},
strings: ['', 'root'],
};
const RENDERER_TRACE = {
traceEvents: [{ name: 'xtream-diagnostic', ph: 'X', ts: 1 }],
};
const directories: string[] = [];
afterEach(async () => {
await Promise.all(
directories
.splice(0)
.map((directory) => rm(directory, { force: true, recursive: true }))
);
});
describe('Xtream diagnostic artifacts', () => {
it('accepts one complete main, renderer, and database-worker artifact set', async () => {
const directory = await createDirectory('valid');
await writeValidArtifacts(directory);
const evidence = await validateXtreamDiagnosticArtifacts(
capture(directory),
directory
);
assertXtreamDiagnosticArtifactEvidence(evidence);
assert.equal(evidence.artifacts.length, 7);
assert.match(evidence.directorySha256, /^[a-f0-9]{64}$/u);
assert.ok(
evidence.artifacts.every(
({ bytes, filename, label, sha256 }) =>
bytes > 0 &&
filename.length > 0 &&
label.length > 0 &&
/^[a-f0-9]{64}$/u.test(sha256)
)
);
assert.ok(Object.isFrozen(evidence));
assert.ok(Object.isFrozen(evidence.artifacts));
assert.ok(evidence.artifacts.every(Object.isFrozen));
assert.throws(
() =>
assertXtreamDiagnosticArtifactEvidence(
structuredClone(evidence)
),
/validated Xtream diagnostic artifact evidence/
);
});
it('fails closed for malformed or missing process artifacts', async () => {
const directory = await createDirectory('invalid');
await writeValidArtifacts(directory);
await writeFile(join(directory, 'renderer.trace.json'), '{');
await assert.rejects(
() =>
validateXtreamDiagnosticArtifacts(
capture(directory),
directory
),
/xtream-diagnostic-artifact-invalid:renderer-trace/
);
await writeFile(
join(directory, 'renderer.trace.json'),
JSON.stringify(RENDERER_TRACE)
);
const missing: XtreamDiagnosticCapture = {
...capture(directory),
main: {
...capture(directory).main,
cpuProfilePath: null,
},
};
await assert.rejects(
() => validateXtreamDiagnosticArtifacts(missing, directory),
/xtream-diagnostic-artifact-missing:main-cpu-profile/
);
});
it('rejects escaped paths and symlinks', async () => {
const directory = await createDirectory('contained');
const outside = await createDirectory('outside');
await writeValidArtifacts(directory);
await writeFile(
join(outside, 'main.cpuprofile'),
JSON.stringify(CPU_PROFILE)
);
const escaped: XtreamDiagnosticCapture = {
...capture(directory),
main: {
...capture(directory).main,
cpuProfilePath: join(outside, 'main.cpuprofile'),
},
};
await assert.rejects(
() => validateXtreamDiagnosticArtifacts(escaped, directory),
/xtream-diagnostic-artifact-path-invalid:main-cpu-profile/
);
const rendererProfile = join(directory, 'renderer.cpuprofile');
await unlink(rendererProfile);
await symlink(join(outside, 'main.cpuprofile'), rendererProfile);
await assert.rejects(
() =>
validateXtreamDiagnosticArtifacts(
capture(directory),
directory
),
/xtream-diagnostic-artifact-path-invalid:renderer-cpu-profile/
);
const symlinkRoot = await createDirectory('directory-symlink');
const realDirectory = join(symlinkRoot, 'real');
const symlinkDirectory = join(symlinkRoot, 'alias');
await mkdir(realDirectory);
await writeValidArtifacts(realDirectory);
await symlink(realDirectory, symlinkDirectory, 'dir');
await assert.rejects(
() =>
validateXtreamDiagnosticArtifacts(
capture(symlinkDirectory),
symlinkDirectory
),
/xtream-diagnostic-artifact-path-invalid:iteration-directory/
);
});
it('requires exactly one database worker and no playlist-refresh worker', async () => {
const directory = await createDirectory('workers');
await writeValidArtifacts(directory);
await writeFile(
join(directory, 'database.worker-9.cpuprofile'),
JSON.stringify(CPU_PROFILE)
);
await assert.rejects(
() =>
validateXtreamDiagnosticArtifacts(
capture(directory),
directory
),
/xtream-diagnostic-database-profile-cardinality-invalid/
);
await unlink(join(directory, 'database.worker-9.cpuprofile'));
await writeFile(
join(directory, 'playlist-refresh.worker-2.cpuprofile'),
JSON.stringify(CPU_PROFILE)
);
await assert.rejects(
() =>
validateXtreamDiagnosticArtifacts(
capture(directory),
directory
),
/xtream-diagnostic-playlist-profile-unexpected/
);
});
it('rejects every rogue top-level profile, snapshot, and trace artifact', async () => {
const filenames = [
'main-extra.cpuprofile',
'main-extra.heapsnapshot',
'renderer-extra.cpuprofile',
'renderer-extra.heapsnapshot',
'renderer-extra.trace.json',
'rogue.cpuprofile',
'rogue.heapsnapshot',
'rogue.trace.json',
'database.worker-evil.cpuprofile',
'database.worker-4.trace.json',
'playlist-refresh.worker-2.trace.json',
'rogue.CPUPROFILE',
'rogue.HeapSnapshot',
'rogue.TRACE.JSON',
] as const;
for (const filename of filenames) {
const directory = await createDirectory(filename);
await writeValidArtifacts(directory);
await writeFile(
join(directory, filename),
JSON.stringify(
filename.endsWith('.cpuprofile')
? CPU_PROFILE
: filename.endsWith('.heapsnapshot')
? HEAP_SNAPSHOT
: RENDERER_TRACE
)
);
await assert.rejects(
() =>
validateXtreamDiagnosticArtifacts(
capture(directory),
directory
),
/xtream-diagnostic-artifact-cardinality-invalid/
);
}
});
it('rejects mixed-case rogue artifacts nested anywhere in the iteration tree', async () => {
const directory = await createDirectory('nested-rogue');
const nested = join(directory, 'nested');
await writeValidArtifacts(directory);
await mkdir(nested);
await writeFile(
join(nested, 'rogue.CpuProfile'),
JSON.stringify(CPU_PROFILE)
);
await assert.rejects(
() =>
validateXtreamDiagnosticArtifacts(
capture(directory),
directory
),
/^Error: xtream-diagnostic-artifact-cardinality-invalid$/
);
});
it('snapshots the validated database worker ordinal before constructing paths', async () => {
const directory = await createDirectory('ordinal-getter');
await writeValidArtifacts(directory);
let reads = 0;
const worker = {
kind: 'database.worker',
get ordinal(): number {
reads += 1;
return reads === 1 ? 4 : ('../../outside' as unknown as number);
},
profilePath: join(directory, 'database.worker-4.cpuprofile'),
snapshotPath: join(directory, 'database.worker-4.heapsnapshot'),
};
const getterCapture: XtreamDiagnosticCapture = {
...capture(directory),
main: {
...capture(directory).main,
workers: [worker],
},
};
await assert.doesNotReject(() =>
validateXtreamDiagnosticArtifacts(getterCapture, directory)
);
assert.equal(reads, 1);
});
it('sanitizes capture Proxy failures before filesystem access', async () => {
const secret = 'must-not-escape-diagnostic-capture';
const directory = await createDirectory('proxy-capture');
const captureProxy = new Proxy(
{},
{
ownKeys() {
throw new Error(secret);
},
}
) as XtreamDiagnosticCapture;
await assert.rejects(
() => validateXtreamDiagnosticArtifacts(captureProxy, directory),
(error: unknown) =>
error instanceof Error &&
error.message === 'xtream-diagnostic-capture-invalid' &&
!error.message.includes(secret)
);
});
});
function capture(
directory: string,
databaseOrdinal = 4
): XtreamDiagnosticCapture {
return {
main: {
cpuProfilePath: join(directory, 'main.cpuprofile'),
heapSnapshotPath: join(directory, 'main.heapsnapshot'),
workers: [
{
kind: 'database.worker',
ordinal: databaseOrdinal,
profilePath: join(
directory,
`database.worker-${databaseOrdinal}.cpuprofile`
),
snapshotPath: join(
directory,
`database.worker-${databaseOrdinal}.heapsnapshot`
),
},
],
},
renderer: {
cpuProfilePath: join(directory, 'renderer.cpuprofile'),
heapSnapshotPath: join(directory, 'renderer.heapsnapshot'),
tracePath: join(directory, 'renderer.trace.json'),
},
};
}
async function createDirectory(label: string): Promise<string> {
const directory = await mkdtemp(
join(tmpdir(), `iptvnator-xtream-diagnostic-${label}-`)
);
directories.push(directory);
return directory;
}
async function writeValidArtifacts(
directory: string,
databaseOrdinal = 4
): Promise<void> {
await Promise.all([
writeFile(
join(directory, 'main.cpuprofile'),
JSON.stringify(CPU_PROFILE)
),
writeFile(
join(directory, 'renderer.cpuprofile'),
JSON.stringify(CPU_PROFILE)
),
writeFile(
join(directory, `database.worker-${databaseOrdinal}.cpuprofile`),
JSON.stringify(CPU_PROFILE)
),
writeFile(
join(directory, `database.worker-${databaseOrdinal}.heapsnapshot`),
JSON.stringify(HEAP_SNAPSHOT)
),
writeFile(
join(directory, 'main.heapsnapshot'),
JSON.stringify(HEAP_SNAPSHOT)
),
writeFile(
join(directory, 'renderer.heapsnapshot'),
JSON.stringify(HEAP_SNAPSHOT)
),
writeFile(
join(directory, 'renderer.trace.json'),
JSON.stringify(RENDERER_TRACE)
),
]);
}
@@ -0,0 +1,324 @@
import { lstat, readdir, realpath } from 'node:fs/promises';
import { isAbsolute, join, relative, resolve, sep } from 'node:path';
import {
isCpuProfile,
isHeapSnapshot,
isRendererTrace,
readCpuProfileDurationMicros,
} from './initial-import-diagnostic-artifact-content-validation';
import {
assertXtreamManifest,
assertXtreamManifestIdentity,
} from './xtream-control-state-schema';
import {
snapshotXtreamDiagnosticCapture,
type XtreamDiagnosticCapture,
type XtreamDiagnosticWorkerArtifact,
} from './xtream-diagnostic-capture-schema';
import {
assertXtreamArtifactRedacted,
createXtreamDiagnosticEvidenceAuthority,
serializeXtreamArtifactForPersistence,
type XtreamDiagnosticArtifactEvidence,
type XtreamValidatedArtifactContent,
} from './xtream-diagnostic-evidence';
import {
isXtreamUnsafeFileError,
readXtreamSafeRegularFile,
} from './xtream-safe-file-read';
export {
assertXtreamArtifactRedacted,
assertXtreamManifest,
assertXtreamManifestIdentity,
serializeXtreamArtifactForPersistence,
};
export type {
XtreamDiagnosticArtifactEvidence,
XtreamDiagnosticArtifactReceipt,
} from './xtream-diagnostic-evidence';
export type { XtreamDiagnosticCapture } from './xtream-diagnostic-capture-schema';
interface ArtifactDescription {
readonly capturesCpuProfileDuration: boolean;
readonly filename: string;
readonly label: string;
readonly path: string | null;
readonly validate: (value: unknown) => boolean;
}
const EVIDENCE_AUTHORITY = createXtreamDiagnosticEvidenceAuthority();
export async function validateXtreamDiagnosticArtifacts(
capture: XtreamDiagnosticCapture,
iterationDirectory: string
): Promise<XtreamDiagnosticArtifactEvidence> {
const snapshot = snapshotXtreamDiagnosticCapture(capture);
if (typeof iterationDirectory !== 'string') {
throw artifactPathError('iteration-directory');
}
const directory = resolve(iterationDirectory);
let realDirectory: string;
try {
const stats = await lstat(directory);
if (!stats.isDirectory() || stats.isSymbolicLink()) {
throw new Error('unsafe-iteration-directory');
}
realDirectory = await realpath(directory);
} catch {
throw artifactPathError('iteration-directory');
}
const databaseWorker = requireExactDatabaseWorker(snapshot.main.workers);
const artifacts: readonly ArtifactDescription[] = [
artifact(
'main.cpuprofile',
'main-cpu-profile',
snapshot.main.cpuProfilePath,
isCpuProfile,
true
),
artifact(
'renderer.cpuprofile',
'renderer-cpu-profile',
snapshot.renderer.cpuProfilePath,
isCpuProfile,
true
),
artifact(
'renderer.trace.json',
'renderer-trace',
snapshot.renderer.tracePath,
isRendererTrace
),
artifact(
'main.heapsnapshot',
'main-heap-snapshot',
snapshot.main.heapSnapshotPath,
isHeapSnapshot
),
artifact(
'renderer.heapsnapshot',
'renderer-heap-snapshot',
snapshot.renderer.heapSnapshotPath,
isHeapSnapshot
),
artifact(
`database.worker-${databaseWorker.ordinal}.cpuprofile`,
'database-cpu-profile',
databaseWorker.profilePath,
isCpuProfile,
true
),
artifact(
`database.worker-${databaseWorker.ordinal}.heapsnapshot`,
'database-heap-snapshot',
databaseWorker.snapshotPath,
isHeapSnapshot
),
];
await assertWorkerArtifactCardinality(
directory,
artifacts.map(({ filename }) => filename)
);
const validated: XtreamValidatedArtifactContent[] = [];
for (const description of artifacts) {
validated.push(
await validateJsonArtifact(directory, realDirectory, description)
);
}
await assertWorkerArtifactCardinality(
directory,
artifacts.map(({ filename }) => filename)
);
return EVIDENCE_AUTHORITY.issue(
realDirectory,
validated,
databaseWorker.ordinal
);
}
export function assertXtreamDiagnosticArtifactEvidence(
value: unknown
): asserts value is XtreamDiagnosticArtifactEvidence {
if (!EVIDENCE_AUTHORITY.is(value)) {
throw new Error(
'expected validated Xtream diagnostic artifact evidence'
);
}
}
function requireExactDatabaseWorker(
workers: readonly XtreamDiagnosticWorkerArtifact[]
): XtreamDiagnosticWorkerArtifact {
if (workers.some((worker) => worker.kind === 'playlist-refresh.worker')) {
throw new Error('xtream-diagnostic-playlist-profile-unexpected');
}
const databaseWorkers = workers.filter(
(worker) => worker.kind === 'database.worker'
);
const worker = databaseWorkers[0];
if (
databaseWorkers.length !== 1 ||
workers.length !== 1 ||
!worker ||
!Number.isSafeInteger(worker.ordinal) ||
worker.ordinal <= 0
) {
throw new Error(
'xtream-diagnostic-database-profile-cardinality-invalid'
);
}
return worker;
}
async function assertWorkerArtifactCardinality(
directory: string,
expectedArtifacts: readonly string[]
): Promise<void> {
const entries = await listDiagnosticArtifactEntries(directory);
if (
entries.some((entry) =>
/^playlist-refresh\.worker-\d+\.(?:cpuprofile|heapsnapshot)$/iu.test(
entry
)
)
) {
throw new Error('xtream-diagnostic-playlist-profile-unexpected');
}
for (const extension of ['cpuprofile', 'heapsnapshot']) {
if (
entries.filter((entry) =>
new RegExp(
`^database\\.worker-\\d+\\.${extension}$`,
'iu'
).test(entry)
).length !== 1
) {
throw new Error(
`xtream-diagnostic-database-${extension === 'cpuprofile' ? 'profile' : 'snapshot'}-cardinality-invalid`
);
}
}
if (
entries.length !== expectedArtifacts.length ||
entries.some((entry) => !expectedArtifacts.includes(entry)) ||
expectedArtifacts.some((entry) => !entries.includes(entry))
) {
throw new Error('xtream-diagnostic-artifact-cardinality-invalid');
}
}
async function listDiagnosticArtifactEntries(
directory: string
): Promise<readonly string[]> {
const artifacts: string[] = [];
const walk = async (current: string): Promise<void> => {
const entries = await readdir(current, { withFileTypes: true });
for (const entry of entries) {
const path = join(current, entry.name);
if (
/(?:\.cpuprofile|\.heapsnapshot|\.trace\.json)$/iu.test(
entry.name
)
) {
artifacts.push(relative(directory, path));
}
if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
const stats = await lstat(path);
if (stats.isSymbolicLink()) continue;
if (!stats.isDirectory()) {
throw new Error('unsafe-artifact-tree-entry');
}
await walk(path);
}
};
try {
await walk(directory);
return artifacts;
} catch {
throw artifactPathError('iteration-directory');
}
}
async function validateJsonArtifact(
directory: string,
realDirectory: string,
description: ArtifactDescription
): Promise<XtreamValidatedArtifactContent> {
if (description.path === null) {
throw new Error(
`xtream-diagnostic-artifact-missing:${description.label}`
);
}
const expectedPath = join(directory, description.filename);
if (resolve(description.path) !== expectedPath) {
throw artifactPathError(description.label);
}
let content: Buffer;
let value: unknown;
try {
const snapshot = await readXtreamSafeRegularFile(expectedPath);
const realArtifactPath = snapshot.realPath;
if (!isContained(realDirectory, realArtifactPath)) {
throw new Error('escaped-artifact');
}
content = snapshot.content;
value = JSON.parse(content.toString('utf8')) as unknown;
} catch (error) {
if (
isXtreamUnsafeFileError(error) ||
(error instanceof Error && error.message === 'escaped-artifact')
) {
throw artifactPathError(description.label);
}
throw new Error(
`xtream-diagnostic-artifact-invalid:${description.label}`
);
}
if (!description.validate(value)) {
throw new Error(
`xtream-diagnostic-artifact-invalid:${description.label}`
);
}
return {
content,
cpuProfileDurationMicros: description.capturesCpuProfileDuration
? readCpuProfileDurationMicros(value)
: null,
filename: description.filename,
label: description.label,
};
}
function artifact(
filename: string,
label: string,
path: string | null,
validate: (value: unknown) => boolean,
capturesCpuProfileDuration = false
): ArtifactDescription {
return {
capturesCpuProfileDuration,
filename,
label,
path,
validate,
};
}
function isContained(directory: string, artifactPath: string): boolean {
const relativePath = relative(directory, artifactPath);
return (
relativePath.length > 0 &&
!isAbsolute(relativePath) &&
relativePath !== '..' &&
!relativePath.startsWith(`..${sep}`)
);
}
function artifactPathError(label: string): Error {
return new Error(`xtream-diagnostic-artifact-path-invalid:${label}`);
}
@@ -0,0 +1,61 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
snapshotXtreamDiagnosticCapture,
type XtreamDiagnosticWorkerArtifact,
} from './xtream-diagnostic-capture-schema';
const WORKER: XtreamDiagnosticWorkerArtifact = {
kind: 'database.worker',
ordinal: 4,
profilePath: '/tmp/database.worker-4.cpuprofile',
snapshotPath: '/tmp/database.worker-4.heapsnapshot',
};
describe('Xtream diagnostic capture schema', () => {
it('reads a workers accessor once before validating and freezing it', () => {
let reads = 0;
const capture = {
main: {
cpuProfilePath: '/tmp/main.cpuprofile',
heapSnapshotPath: '/tmp/main.heapsnapshot',
get workers() {
reads += 1;
return [{ ...WORKER }];
},
},
renderer: {
cpuProfilePath: '/tmp/renderer.cpuprofile',
heapSnapshotPath: '/tmp/renderer.heapsnapshot',
tracePath: '/tmp/renderer.trace.json',
},
};
const snapshot = snapshotXtreamDiagnosticCapture(capture);
assert.equal(reads, 1);
assert.deepEqual(snapshot.main.workers, [WORKER]);
assert.ok(Object.isFrozen(snapshot.main.workers));
assert.ok(Object.isFrozen(snapshot.main.workers[0]));
});
it('rejects the producer-impossible zero worker ordinal', () => {
assert.throws(
() =>
snapshotXtreamDiagnosticCapture({
main: {
cpuProfilePath: '/tmp/main.cpuprofile',
heapSnapshotPath: '/tmp/main.heapsnapshot',
workers: [{ ...WORKER, ordinal: 0 }],
},
renderer: {
cpuProfilePath: '/tmp/renderer.cpuprofile',
heapSnapshotPath: '/tmp/renderer.heapsnapshot',
tracePath: '/tmp/renderer.trace.json',
},
}),
/xtream-diagnostic-capture-invalid/
);
});
});
@@ -0,0 +1,149 @@
export interface XtreamDiagnosticWorkerArtifact {
readonly kind: string;
readonly ordinal: number;
readonly profilePath: string | null;
readonly snapshotPath: string | null;
}
export interface XtreamDiagnosticCapture {
readonly main: {
readonly cpuProfilePath: string | null;
readonly heapSnapshotPath: string | null;
readonly workers: readonly XtreamDiagnosticWorkerArtifact[];
};
readonly renderer: {
readonly cpuProfilePath: string | null;
readonly heapSnapshotPath: string | null;
readonly tracePath: string | null;
};
}
export function snapshotXtreamDiagnosticCapture(
value: unknown
): XtreamDiagnosticCapture {
try {
return snapshotCapture(value);
} catch {
throw new Error('xtream-diagnostic-capture-invalid');
}
}
function snapshotCapture(value: unknown): XtreamDiagnosticCapture {
if (!isExactRecord(value, ['main', 'renderer'])) invalid();
const main = value['main'];
const renderer = value['renderer'];
const workerValues =
typeof main === 'object' && main !== null
? Reflect.get(main, 'workers')
: null;
if (
!isExactRecord(main, [
'cpuProfilePath',
'heapSnapshotPath',
'workers',
]) ||
!isExactRecord(renderer, [
'cpuProfilePath',
'heapSnapshotPath',
'tracePath',
]) ||
!Array.isArray(workerValues)
) {
invalid();
}
const workers = snapshotWorkers(workerValues);
const snapshot = {
main: {
cpuProfilePath: snapshotPath(main['cpuProfilePath']),
heapSnapshotPath: snapshotPath(main['heapSnapshotPath']),
workers: Object.freeze(workers),
},
renderer: {
cpuProfilePath: snapshotPath(renderer['cpuProfilePath']),
heapSnapshotPath: snapshotPath(renderer['heapSnapshotPath']),
tracePath: snapshotPath(renderer['tracePath']),
},
};
Object.freeze(snapshot.main);
Object.freeze(snapshot.renderer);
return Object.freeze(snapshot);
}
function snapshotWorkers(value: unknown): XtreamDiagnosticWorkerArtifact[] {
if (!Array.isArray(value)) invalid();
const length = Reflect.get(value, 'length') as unknown;
if (
!Number.isSafeInteger(length) ||
Number(length) < 0 ||
Number(length) > 64
) {
invalid();
}
const expected = new Set([
'length',
...Array.from({ length: Number(length) }, (_, index) => String(index)),
]);
const keys = Reflect.ownKeys(value);
if (
keys.length !== expected.size ||
keys.some((key) => typeof key !== 'string' || !expected.has(key))
) {
invalid();
}
return Array.from({ length: Number(length) }, (_, index) =>
snapshotWorker(Reflect.get(value, String(index)))
);
}
function snapshotWorker(value: unknown): XtreamDiagnosticWorkerArtifact {
if (
!isExactRecord(value, [
'kind',
'ordinal',
'profilePath',
'snapshotPath',
])
) {
invalid();
}
const kind = value['kind'];
const ordinal = value['ordinal'];
const profilePath = snapshotPath(value['profilePath']);
const snapshotPathValue = snapshotPath(value['snapshotPath']);
if (
typeof kind !== 'string' ||
!Number.isSafeInteger(ordinal) ||
Number(ordinal) <= 0
) {
invalid();
}
return Object.freeze({
kind,
ordinal: ordinal as number,
profilePath,
snapshotPath: snapshotPathValue,
});
}
function snapshotPath(value: unknown): string | null {
if (value !== null && typeof value !== 'string') invalid();
return value as string | null;
}
function isExactRecord(
value: unknown,
keys: readonly string[]
): value is Record<string, unknown> {
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
return false;
}
const actual = Reflect.ownKeys(value);
return (
actual.length === keys.length &&
actual.every((key) => typeof key === 'string' && keys.includes(key))
);
}
function invalid(): never {
throw new Error('invalid diagnostic capture');
}
@@ -0,0 +1,198 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
assertXtreamArtifactRedacted,
serializeXtreamArtifactForPersistence,
} from './xtream-diagnostic-artifacts';
import type { XtreamArtifactSafetyContext } from './xtream-summary-contract';
const TOKEN = 'diagnostic-control-token';
const SAFETY: XtreamArtifactSafetyContext = {
controlToken: TOKEN,
syntheticCredentials: {
password: 'performance',
username: 'performance',
},
};
const SAFE_ERROR = 'Xtream artifact must remain credential-safe';
describe('Xtream diagnostic persistence safety', () => {
it('rejects single- and double-percent-encoded synthetic credentials', () => {
for (const endpoint of [
'http://127.0.0.1/player_api.php?%75sername%3D%70erformance%26%70assword%3D%70erformance',
'http://127.0.0.1/player_api.php?%2575sername%253D%2570erformance%2526%2570assword%253D%2570erformance',
'http://%70erformance%3A%70erformance%40127.0.0.1/player_api.php',
'http://%2570erformance%253A%2570erformance%2540127.0.0.1/player_api.php',
]) {
assert.throws(
() =>
serializeXtreamArtifactForPersistence({ endpoint }, SAFETY),
exactSafeError
);
}
});
it('rejects triple encoding and fails closed beyond the decode cap', () => {
const userInfo =
'http://performance:performance@127.0.0.1/player_api.php';
for (const endpoint of [
encodeTimes(userInfo, 3),
encodeTimes(userInfo, 9),
]) {
assert.throws(
() =>
serializeXtreamArtifactForPersistence({ endpoint }, SAFETY),
exactSafeError
);
}
});
it('preserves benign malformed percent text', () => {
assert.equal(
serializeXtreamArtifactForPersistence(
{ label: 'progress is 100% complete' },
SAFETY
),
'{"label":"progress is 100% complete"}'
);
});
it('does not let malformed percent text mask encoded credentials', () => {
assert.throws(
() =>
serializeXtreamArtifactForPersistence(
{
endpoint:
'http://%ZZ%70erformance%3A%70erformance%40127.0.0.1/player_api.php',
},
SAFETY
),
exactSafeError
);
});
it('does not trust an array own forEach during standalone redaction', () => {
const unsafe = [
'http://mock.invalid/player_api.php?username=performance',
];
Object.defineProperty(unsafe, 'forEach', {
value: () => undefined,
});
assert.throws(
() => assertXtreamArtifactRedacted(unsafe),
exactSafeError
);
});
it('revalidates the serialized JSON emitted by toJSON hooks', () => {
assert.equal(
serializeXtreamArtifactForPersistence(
{
visible: true,
toJSON() {
return { visible: true };
},
},
SAFETY
),
'{"visible":true}'
);
for (const unsafe of [
{
toJSON() {
return { username: 'injected-after-first-validation' };
},
},
{
toJSON() {
return {
endpoint:
'http://mock.invalid/player_api.php?token=late',
};
},
},
]) {
assert.throws(
() => serializeXtreamArtifactForPersistence(unsafe, SAFETY),
exactSafeError
);
}
});
it('sanitizes ownKeys, getter, and revoked Proxy failures', () => {
const ownKeysProxy = new Proxy(
{},
{
ownKeys() {
throw new Error(TOKEN);
},
}
);
const safetyProxy = new Proxy(SAFETY, {
get() {
throw new Error(TOKEN);
},
});
const getterValue = Object.defineProperty({}, 'visible', {
enumerable: true,
get() {
throw new Error(TOKEN);
},
});
const throwingJson = {
toJSON() {
throw new Error(TOKEN);
},
};
const revocable = Proxy.revocable({}, {});
revocable.revoke();
assert.throws(
() => assertXtreamArtifactRedacted(ownKeysProxy, [TOKEN]),
exactSafeError
);
assert.throws(
() => assertXtreamArtifactRedacted(revocable.proxy, [TOKEN]),
exactSafeError
);
assert.throws(
() =>
serializeXtreamArtifactForPersistence(
{ visible: true },
safetyProxy
),
exactSafeError
);
assert.throws(
() => serializeXtreamArtifactForPersistence(ownKeysProxy, SAFETY),
exactSafeError
);
assert.throws(
() => serializeXtreamArtifactForPersistence(getterValue, SAFETY),
exactSafeError
);
assert.throws(
() => serializeXtreamArtifactForPersistence(throwingJson, SAFETY),
exactSafeError
);
});
});
function exactSafeError(error: unknown): boolean {
return (
error instanceof Error &&
error.message === SAFE_ERROR &&
!error.message.includes(TOKEN)
);
}
function encodeTimes(value: string, count: number): string {
let encoded = value;
for (let pass = 0; pass < count; pass += 1) {
encoded = encodeURIComponent(encoded);
}
return encoded;
}
@@ -0,0 +1,266 @@
import { createHash } from 'node:crypto';
import type { XtreamArtifactSafetyContext } from './xtream-summary-contract';
export interface XtreamDiagnosticArtifactReceipt {
readonly bytes: number;
readonly filename: string;
readonly label: string;
readonly sha256: string;
}
declare const EVIDENCE_BRAND: unique symbol;
export interface XtreamDiagnosticArtifactEvidence {
readonly [EVIDENCE_BRAND]: true;
readonly artifacts: readonly XtreamDiagnosticArtifactReceipt[];
readonly directorySha256: string;
readonly profiles: XtreamDiagnosticProfileEvidence;
}
export interface XtreamDiagnosticProfileEvidence {
readonly databaseWorker: {
readonly durationMicros: number;
readonly ordinal: number;
};
readonly main: {
readonly durationMicros: number;
};
readonly renderer: {
readonly durationMicros: number;
};
}
export interface XtreamValidatedArtifactContent {
readonly content: Uint8Array;
readonly cpuProfileDurationMicros: number | null;
readonly filename: string;
readonly label: string;
}
interface XtreamDiagnosticEvidenceAuthority {
is(value: unknown): value is XtreamDiagnosticArtifactEvidence;
issue(
realDirectory: string,
artifacts: readonly XtreamValidatedArtifactContent[],
databaseWorkerOrdinal: number
): XtreamDiagnosticArtifactEvidence;
}
const SENSITIVE_KEYS = new Set([
'authorization',
'credential',
'credentials',
'password',
'playlisturl',
'serverurl',
'token',
'username',
]);
const MAX_PERCENT_DECODE_PASSES = 8;
export function createXtreamDiagnosticEvidenceAuthority(): XtreamDiagnosticEvidenceAuthority {
const validated = new WeakSet<object>();
return {
is(value): value is XtreamDiagnosticArtifactEvidence {
return (
typeof value === 'object' &&
value !== null &&
validated.has(value)
);
},
issue(realDirectory, artifacts, databaseWorkerOrdinal) {
const receipts = Object.freeze(
artifacts.map(({ content, filename, label }) =>
Object.freeze({
bytes: content.byteLength,
filename,
label,
sha256: sha256(content),
})
)
);
const duration = (label: string): number => {
const value = artifacts.find(
(artifact) => artifact.label === label
)?.cpuProfileDurationMicros;
if (!Number.isSafeInteger(value) || Number(value) <= 0) {
throw new Error('invalid diagnostic profile evidence');
}
return Number(value);
};
if (
!Number.isSafeInteger(databaseWorkerOrdinal) ||
databaseWorkerOrdinal <= 0
) {
throw new Error('invalid diagnostic worker identity');
}
const profiles = Object.freeze({
databaseWorker: Object.freeze({
durationMicros: duration('database-cpu-profile'),
ordinal: databaseWorkerOrdinal,
}),
main: Object.freeze({
durationMicros: duration('main-cpu-profile'),
}),
renderer: Object.freeze({
durationMicros: duration('renderer-cpu-profile'),
}),
});
const directorySha256 = sha256(
Buffer.from(
`${realDirectory}\0${JSON.stringify(receipts)}`,
'utf8'
)
);
const evidence = Object.freeze({
artifacts: receipts,
directorySha256,
profiles,
}) as XtreamDiagnosticArtifactEvidence;
validated.add(evidence);
return evidence;
},
};
}
export function assertXtreamArtifactRedacted(
value: unknown,
forbiddenValues: readonly string[] = []
): void {
try {
assertArtifactRedacted(value, forbiddenValues);
} catch {
throw unsafeArtifact();
}
}
function assertArtifactRedacted(
value: unknown,
forbiddenValues: readonly string[]
): void {
const secrets: string[] = [];
for (let index = 0; index < forbiddenValues.length; index += 1) {
const entry = Reflect.get(forbiddenValues, String(index)) as unknown;
if (typeof entry === 'string' && entry.length > 0) {
secrets.push(entry);
}
}
const visit = (input: unknown): void => {
if (typeof input === 'string') {
for (const candidate of decodedVariants(input)) {
if (
secrets.some((secret) => candidate.includes(secret)) ||
/[?&](?:username|password|token)=/iu.test(candidate) ||
/:\/\/[^/\s]+@/u.test(candidate)
) {
throw unsafeArtifact();
}
}
return;
}
if (Array.isArray(input)) {
const length = input.length;
for (let index = 0; index < length; index += 1) {
visit(Reflect.get(input, String(index)));
}
return;
}
if (!input || typeof input !== 'object') return;
for (const [key, entry] of Object.entries(input)) {
if (SENSITIVE_KEYS.has(key.replace(/[-_]/gu, '').toLowerCase())) {
throw unsafeArtifact();
}
visit(entry);
}
};
visit(value);
}
function decodedVariants(value: string): readonly string[] {
const variants = [value];
let current = value;
for (let pass = 0; pass < MAX_PERCENT_DECODE_PASSES; pass += 1) {
const decoded = decodePercentPass(current);
if (decoded === current) break;
variants.push(decoded);
current = decoded;
}
const afterCap = decodePercentPass(current);
if (afterCap !== current) throw unsafeArtifact();
return variants;
}
function decodePercentPass(value: string): string {
try {
return decodeURIComponent(value);
} catch {
return value.replace(/%([a-f0-9]{2})/giu, (_match, hex: string) =>
String.fromCharCode(Number.parseInt(hex, 16))
);
}
}
export function serializeXtreamArtifactForPersistence(
value: unknown,
safety: XtreamArtifactSafetyContext
): string {
try {
return serializeArtifact(value, safety);
} catch {
throw unsafeArtifact();
}
}
function serializeArtifact(
value: unknown,
safety: XtreamArtifactSafetyContext
): string {
const controlToken = safety.controlToken;
const credentials = safety.syntheticCredentials;
const username = credentials?.username;
const password = credentials?.password;
if (
typeof controlToken !== 'string' ||
controlToken.length === 0 ||
username !== 'performance' ||
password !== 'performance'
) {
throw unsafeArtifact();
}
assertXtreamArtifactRedacted(value, [controlToken]);
let serialized: string | undefined;
try {
serialized = JSON.stringify(value);
} catch {
throw unsafeArtifact();
}
if (typeof serialized !== 'string') throw unsafeArtifact();
let canonical: unknown;
try {
canonical = JSON.parse(serialized) as unknown;
} catch {
throw unsafeArtifact();
}
assertXtreamArtifactRedacted(canonical, [controlToken]);
if (
JSON.stringify(canonical) !== serialized ||
serialized.includes(controlToken) ||
/performance(?::|%3a)performance/iu.test(serialized) ||
/[?&](?:username=performance[^"#]*&password=performance|password=performance[^"#]*&username=performance)/iu.test(
serialized
) ||
/:\/\/performance(?::|%3a)performance@/iu.test(serialized)
) {
throw unsafeArtifact();
}
return serialized;
}
function sha256(value: Uint8Array): string {
return createHash('sha256').update(value).digest('hex');
}
function unsafeArtifact(): Error {
return new Error('Xtream artifact must remain credential-safe');
}
@@ -0,0 +1,321 @@
/* eslint-disable playwright/expect-expect -- These are Node assertion-based performance contract tests. */
import assert from 'node:assert/strict';
import { test } from 'node:test';
import {
createXtreamIterationDefinitions,
XTREAM_SCENARIO_ID,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import { iteration } from './xtream-benchmark-report.fixtures';
import { assertXtreamIterationResult } from './xtream-iteration-validity';
import type { XtreamRawIterationResult } from './xtream-summary-contract';
import { validXtreamWorkerRequestIdentity } from './xtream-worker-request-identity';
test('enforces producer-coherent request identities and source-to-worker chronology', () => {
const raw = createRaw(XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE);
assert.doesNotThrow(() => assertXtreamIterationResult(raw));
const correlated = request(raw, 'DB_GET_CATEGORIES');
const nonApplicable = request(raw, 'DB_GET_APP_STATE');
const requiredOperationId = request(raw, 'DB_SAVE_CONTENT');
const receivedEpochMs = requireEpoch(correlated.requestReceivedEpochMs);
assert.equal(
validXtreamWorkerRequestIdentity({
...correlated,
sourceEpochMs: receivedEpochMs + 0.006,
}),
true
);
assert.equal(
validXtreamWorkerRequestIdentity({
...correlated,
sourceEpochMs: receivedEpochMs + 1,
}),
false
);
assert.equal(nonApplicable.ipcCallId, null);
assert.equal(nonApplicable.operationId, null);
assert.equal(
nonApplicable.operationIdUnavailableReason,
'preload-performance-marker-not-applicable'
);
assert.equal(nonApplicable.sourceEpochMs, null);
const invalidRequests = [
replaceRequest(raw, correlated, {
ipcCallId: null,
operationIdUnavailableReason:
'preload-performance-marker-not-applicable',
sourceEpochMs: null,
}),
replaceRequest(raw, nonApplicable, {
ipcCallId: 900_001,
operationId: 'forged-operation',
operationIdUnavailableReason: null,
sourceEpochMs:
requireEpoch(nonApplicable.requestReceivedEpochMs) - 1,
}),
replaceRequest(raw, requiredOperationId, {
operationId: null,
operationIdUnavailableReason:
'preload-performance-marker-uncorrelated',
}),
replaceRequest(raw, correlated, {
operationId: 'forged-operation',
operationIdUnavailableReason: null,
}),
replaceRequest(raw, correlated, {
sourceEpochMs: receivedEpochMs + 1,
}),
];
for (const requests of invalidRequests) {
assert.throws(
() => assertXtreamIterationResult(withRequests(raw, requests)),
/invalid Xtream iteration/
);
}
});
test('binds populated and empty playlist deletes to their real producer identities', () => {
const raw = createRaw(XTREAM_SCENARIO_ID.DELETE_LARGE);
const deletes = raw.databaseWorker.requests.evidence.filter(
({ operation }) => operation === 'DB_DELETE_PLAYLIST'
);
const populated = deletes.find(
(candidate) =>
JSON.stringify(requestItemCounts(candidate)) ===
JSON.stringify([100_100, 100_101])
);
const emptyFollowUp = deletes.find(
(candidate) =>
JSON.stringify(requestItemCounts(candidate)) ===
JSON.stringify([0, 1])
);
assert.ok(populated?.operationId);
assert.ok(emptyFollowUp);
const producerCoherent = replaceRequest(raw, emptyFollowUp, {
operationId: null,
operationIdUnavailableReason: null,
});
assert.doesNotThrow(() =>
assertXtreamIterationResult(withRequests(raw, producerCoherent))
);
const missingPopulatedIdentity = replaceRequest(raw, populated, {
operationId: null,
operationIdUnavailableReason: null,
});
assert.throws(
() =>
assertXtreamIterationResult(
withRequests(raw, missingPopulatedIdentity)
),
/invalid Xtream iteration/
);
const fabricatedFollowUpIdentity = replaceRequest(raw, emptyFollowUp, {
operationId: 'fabricated-follow-up-operation',
operationIdUnavailableReason: null,
});
assert.throws(
() =>
assertXtreamIterationResult(
withRequests(raw, fabricatedFollowUpIdentity)
),
/invalid Xtream iteration/
);
});
test('requires producer IPC IDs to preserve per-producer source chronology', () => {
const raw = createRaw(XTREAM_SCENARIO_ID.DELETE_LARGE);
const [first, second] = raw.databaseWorker.requests.evidence;
assert.ok(first);
assert.ok(second);
assert.ok(first.ipcCallId !== null);
assert.ok(second.ipcCallId !== null);
assert.ok(first.sourceEpochMs !== null);
assert.ok(second.sourceEpochMs !== null);
const laterSourceEpochMs = first.sourceEpochMs + 0.25;
const chronologicalRequests = raw.databaseWorker.requests.evidence.map(
(candidate) =>
candidate === second
? { ...candidate, sourceEpochMs: laterSourceEpochMs }
: candidate
);
const chronologicalIpcSpans = raw.phaseCapture.ipcSpans.map((span) =>
span.ipcCallId === second.ipcCallId
? { ...span, sourceEpochMs: laterSourceEpochMs }
: span
);
const swapped = chronologicalRequests.map((candidate) => {
if (candidate === first) {
return { ...candidate, ipcCallId: second.ipcCallId };
}
return candidate.ipcCallId === second.ipcCallId
? { ...candidate, ipcCallId: first.ipcCallId }
: candidate;
});
assert.throws(
() =>
assertXtreamIterationResult({
...withRequests(raw, swapped),
phaseCapture: {
...raw.phaseCapture,
ipcSpans: chronologicalIpcSpans,
},
}),
/invalid Xtream iteration/
);
const gapped = raw.databaseWorker.requests.evidence.map(
(candidate, index) => ({
...candidate,
ipcCallId: index === 0 ? 10 : 30,
})
);
const gappedIpcSpans = raw.phaseCapture.ipcSpans.map((span) => ({
...span,
ipcCallId: span.ipcCallId === first.ipcCallId ? 10 : 30,
}));
assert.doesNotThrow(() =>
assertXtreamIterationResult({
...withRequests(raw, gapped),
phaseCapture: {
...raw.phaseCapture,
ipcSpans: gappedIpcSpans,
},
})
);
const tied = raw.databaseWorker.requests.evidence.map((candidate) =>
candidate === second
? { ...candidate, sourceEpochMs: first.sourceEpochMs }
: candidate
);
const tiedIpcSpans = raw.phaseCapture.ipcSpans.map((span) =>
span.ipcCallId === second.ipcCallId
? { ...span, sourceEpochMs: first.sourceEpochMs as number }
: span
);
assert.doesNotThrow(() =>
assertXtreamIterationResult({
...withRequests(raw, tied),
phaseCapture: {
...raw.phaseCapture,
ipcSpans: tiedIpcSpans,
},
})
);
});
test('does not let caller-owned evidence methods hide a missing populated delete identity', () => {
const raw = createRaw(XTREAM_SCENARIO_ID.DELETE_LARGE);
const pristine = raw.databaseWorker.requests.evidence;
const populated = pristine.find(
(candidate) =>
candidate.operation === 'DB_DELETE_PLAYLIST' &&
JSON.stringify(requestItemCounts(candidate)) ===
JSON.stringify([100_100, 100_101])
);
assert.ok(populated);
const forged = replaceRequest(raw, populated, {
operationId: null,
operationIdUnavailableReason: null,
});
const invoked: string[] = [];
for (const method of ['filter', 'flatMap', 'map', 'some'] as const) {
Object.defineProperty(forged, method, {
configurable: true,
value(...args: unknown[]) {
invoked.push(method);
return Reflect.apply(Array.prototype[method], pristine, args);
},
});
}
assert.throws(
() => assertXtreamIterationResult(withRequests(raw, forged)),
/invalid Xtream iteration/
);
assert.deepEqual(invoked, []);
});
test('requires the database-worker isolate heap to fit inside main-process RSS only', () => {
const raw = createRaw(XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE);
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
databaseWorker: {
...raw.databaseWorker,
peakHeapUsedBytes: raw.main.peakRssBytes + 1,
},
}),
/invalid Xtream iteration/
);
assert.doesNotThrow(() =>
assertXtreamIterationResult({
...raw,
databaseWorker: {
...raw.databaseWorker,
peakExternalBytes: raw.main.peakRssBytes + 1,
},
})
);
});
function createRaw(scenarioId: XtreamScenarioId): XtreamRawIterationResult {
const definition = createXtreamIterationDefinitions(false).find(
(candidate) => candidate.scenarioId === scenarioId
);
assert.ok(definition);
return iteration(definition, 1);
}
function request(raw: XtreamRawIterationResult, operation: string) {
const value = raw.databaseWorker.requests.evidence.find(
(candidate) => candidate.operation === operation
);
assert.ok(value);
return value;
}
function replaceRequest(
raw: XtreamRawIterationResult,
target: (typeof raw.databaseWorker.requests.evidence)[number],
replacement: Partial<typeof target>
) {
return raw.databaseWorker.requests.evidence.map((candidate) =>
candidate === target ? { ...candidate, ...replacement } : candidate
);
}
function withRequests(
raw: XtreamRawIterationResult,
evidence: typeof raw.databaseWorker.requests.evidence
): XtreamRawIterationResult {
return {
...raw,
databaseWorker: {
...raw.databaseWorker,
requests: { ...raw.databaseWorker.requests, evidence },
},
};
}
function requireEpoch(value: number | null): number {
assert.ok(value !== null);
return value;
}
function requestItemCounts(
request: XtreamRawIterationResult['databaseWorker']['requests']['evidence'][number]
): readonly (number | null)[] {
return request.phaseEvents
.filter(({ boundary }) => boundary === 'end')
.map(({ metadata }) => metadata?.itemCount ?? null);
}
@@ -0,0 +1,369 @@
import {
XTREAM_ITERATION_KIND,
type XtreamIterationDefinition,
} from './xtream-benchmark-contract';
import {
XTREAM_IDENTIFIER,
XTREAM_SHA256,
} from './xtream-benchmark-manifest-schema';
import {
XTREAM_NOT_APPLICABLE,
type XtreamRawIterationResult,
type XtreamValidatedIterationResult,
} from './xtream-summary-contract';
export {
assertXtreamBenchmarkManifest,
parseXtreamBenchmarkManifest,
XTREAM_IDENTIFIER,
XTREAM_SHA256,
} from './xtream-benchmark-manifest-schema';
export const XTREAM_RAW_ITERATION_KEYS = [
'cancellation',
'cancellationEvidence',
'catalogVerification',
'databaseWorker',
'eligibleForComparison',
'kind',
'main',
'phaseCapture',
'phases',
'playlistRefreshWorker',
'processIdentity',
'renderer',
'runId',
'scenarioId',
'validity',
] as const;
export const XTREAM_PHASE_NUMBER_KEYS = [
'angularRenderingMs',
'dataAcquisitionMs',
'deserializationMs',
'jsonParsingMs',
'normalizationMs',
'serializationMs',
'sqliteReadMs',
'sqliteWriteMs',
'storeUpdateMs',
'structuredCloneProxyMs',
'totalMs',
] as const;
export const XTREAM_PHASE_KEYS = [
...XTREAM_PHASE_NUMBER_KEYS,
'backgroundSearchMarkerMs',
'backgroundSearchMarkerReason',
'indexesMs',
'indexesReason',
'restoreUserDataMs',
'restoreUserDataReason',
'structuredCloneAttribution',
'transactionCommitMs',
'transactionCommitReason',
] as const;
export const XTREAM_PROFILE_KEYS = [
'cpuProfileDurationMicros',
'cpuProfileUnavailableReason',
] as const;
export const XTREAM_RENDERER_NUMBER_KEYS = [
'frameGapMaxMs',
'frameGapP95Ms',
'heartbeatMaxMs',
'heartbeatP95Ms',
'longTaskCount',
'longTaskMaxMs',
'peakHeapUsedBytes',
'peakRssBytes',
'postGcHeapUsedBytes',
'storeToPaintMs',
] as const;
export const XTREAM_MAIN_NUMBER_KEYS = [
'browserWindowId',
'cpuSystemMicros',
'cpuUserMicros',
'eventLoopDelayMaxMs',
'eventLoopDelayP95Ms',
'eventLoopDelayP99Ms',
'peakHeapUsedBytes',
'peakRssBytes',
'postGcHeapUsedBytes',
'responsiveEvents',
'unresponsiveEvents',
'webContentsId',
] as const;
export const XTREAM_WORKER_NUMBER_KEYS = [
'cpuSystemMicros',
'cpuUserMicros',
'eventLoopDelayMaxMs',
'eventLoopDelayP95Ms',
'eventLoopDelayP99Ms',
'eventLoopUtilization',
'ordinal',
'peakExternalBytes',
'peakHeapUsedBytes',
'postGcHeapUsedBytes',
] as const;
export const XTREAM_CANCEL_TIME_KEYS = [
'acknowledgementLatencyMs',
'authoritativeTerminalEpochMs',
'clickEpochMs',
'clickToDatabaseDispatchMs',
'clickToPaintMs',
'clickToPreloadReturnMs',
'databaseDispatchEpochMs',
'paintedEpochMs',
'preloadReturnEpochMs',
'preloadStartEpochMs',
'workerReceiptEpochMs',
'workerReceiptLatencyMs',
] as const;
export function assertFreshXtreamProcessIdentities(
iterations: readonly XtreamValidatedIterationResult[]
): void {
const unique = (select: (run: XtreamValidatedIterationResult) => unknown) =>
new Set(iterations.map(select)).size === iterations.length;
if (
!unique((run) => run.processIdentity.electronPid) ||
!unique((run) => run.processIdentity.launchId) ||
!unique((run) => run.processIdentity.profileDirectorySha256) ||
!unique((run) => run.processIdentity.generationIdentitySha256)
) {
throw new Error('Xtream benchmark requires a fresh process identity');
}
}
export function snapshotXtreamIterations(
value: unknown
): readonly XtreamValidatedIterationResult[] {
try {
if (!Array.isArray(value)) invalidIterationCollection();
const lengthDescriptor = Reflect.getOwnPropertyDescriptor(
value,
'length'
);
const length = lengthDescriptor?.value;
if (
!Number.isSafeInteger(length) ||
Number(length) < 0 ||
Number(length) > 128
) {
invalidIterationCollection();
}
const snapshot: XtreamValidatedIterationResult[] = [];
for (let index = 0; index < Number(length); index += 1) {
const descriptor = Reflect.getOwnPropertyDescriptor(
value,
String(index)
);
if (
!descriptor ||
!Object.prototype.hasOwnProperty.call(descriptor, 'value')
) {
invalidIterationCollection();
}
snapshot.push(descriptor.value as XtreamValidatedIterationResult);
}
return Object.freeze(snapshot);
} catch {
throw new Error('invalid Xtream iteration collection');
}
}
export function assertOrderedXtreamSchedule(
iterations: readonly XtreamValidatedIterationResult[],
expected: readonly XtreamIterationDefinition[],
mode: 'formal' | 'smoke'
): void {
if (iterations.length !== expected.length) scheduleError(mode);
for (let index = 0; index < expected.length; index += 1) {
const actual = iterations[index];
const definition = expected[index];
assertXtreamSafePathIdentifier(actual?.runId, 'run-id');
assertXtreamSafePathIdentifier(definition?.runId, 'run-id');
if (
!actual ||
!definition ||
actual.scenarioId !== definition.scenarioId ||
actual.runId !== definition.runId ||
actual.kind !== definition.kind ||
actual.eligibleForComparison !== definition.eligibleForComparison
) {
throw new Error('invalid ordered Xtream benchmark schedule');
}
}
}
export function assertXtreamSafePathIdentifier(
value: unknown,
label: string
): asserts value is string {
if (typeof value !== 'string' || !XTREAM_IDENTIFIER.test(value)) {
throw new Error(`benchmark requires a safe Xtream ${label}`);
}
}
export function toXtreamRawIteration(
value: XtreamValidatedIterationResult
): XtreamRawIterationResult {
const raw: Record<string, unknown> = { ...value };
delete raw['persistence'];
delete raw['validationStatus'];
return raw as unknown as XtreamRawIterationResult;
}
export function freezeDeep<T>(value: T): T {
if (value && typeof value === 'object' && !Object.isFrozen(value)) {
Object.freeze(value);
Object.values(value).forEach(freezeDeep);
}
return value;
}
export function isExactRecord(
value: unknown,
keys: readonly string[]
): value is Record<string, unknown> {
try {
if (
typeof value !== 'object' ||
value === null ||
Array.isArray(value) ||
![Object.prototype, null].includes(Reflect.getPrototypeOf(value))
) {
return false;
}
const ownKeys = Reflect.ownKeys(value);
if (
ownKeys.length !== keys.length ||
ownKeys.some(
(key) => typeof key !== 'string' || !keys.includes(key)
)
) {
return false;
}
return keys.every((key) => {
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
return (
descriptor !== undefined &&
Object.prototype.hasOwnProperty.call(descriptor, 'value')
);
});
} catch {
return false;
}
}
export function isFiniteNonNegative(value: unknown): value is number {
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
}
export function isSafeNonNegativeInteger(value: unknown): boolean {
return Number.isSafeInteger(value) && Number(value) >= 0;
}
export function isPositiveSafeInteger(value: unknown): value is number {
return Number.isSafeInteger(value) && Number(value) > 0;
}
export function isUtilization(value: unknown): boolean {
return isFiniteNonNegative(value) && value <= 1;
}
export function hasFiniteNonNegativeKeys(
value: Record<string, unknown>,
keys: readonly string[]
): boolean {
return keys.every((key) => isFiniteNonNegative(value[key]));
}
export function hasOrderedEventLoopDelay(
value: Record<string, unknown>
): boolean {
return (
(value['eventLoopDelayP95Ms'] as number) <=
(value['eventLoopDelayP99Ms'] as number) &&
(value['eventLoopDelayP99Ms'] as number) <=
(value['eventLoopDelayMaxMs'] as number)
);
}
export function hasMatchingEventLoopDelay(
worker: Record<string, unknown>
): boolean {
const requests = worker['requests'];
if (typeof requests !== 'object' || requests === null) return false;
return [
'eventLoopDelayMaxMs',
'eventLoopDelayP95Ms',
'eventLoopDelayP99Ms',
].every(
(key) => worker[key] === (requests as Record<string, unknown>)[key]
);
}
export function isExactXtreamProcessIdentity(value: unknown): boolean {
const keys = [
'captureGeneration',
'electronPid',
'freshProcess',
'generationIdentitySha256',
'launchId',
'profileDirectorySha256',
] as const;
return (
isExactRecord(value, keys) &&
isPositiveSafeInteger(value['captureGeneration']) &&
isPositiveSafeInteger(value['electronPid']) &&
value['freshProcess'] === true &&
typeof value['launchId'] === 'string' &&
XTREAM_IDENTIFIER.test(value['launchId']) &&
typeof value['generationIdentitySha256'] === 'string' &&
XTREAM_SHA256.test(value['generationIdentitySha256']) &&
typeof value['profileDirectorySha256'] === 'string' &&
XTREAM_SHA256.test(value['profileDirectorySha256'])
);
}
export function isXtreamProfile(
value: Record<string, unknown>,
kind: unknown
): boolean {
return kind === XTREAM_ITERATION_KIND.DIAGNOSTIC
? isPositiveSafeInteger(value['cpuProfileDurationMicros']) &&
value['cpuProfileUnavailableReason'] === null
: value['cpuProfileDurationMicros'] === null &&
value['cpuProfileUnavailableReason'] ===
XTREAM_NOT_APPLICABLE.PROFILE_OUTSIDE_DIAGNOSTIC;
}
export function sameValues(
left: readonly unknown[],
right: readonly unknown[]
): boolean {
return JSON.stringify(left) === JSON.stringify(right);
}
export function sameMaps(
left: ReadonlyMap<string, unknown>,
right: ReadonlyMap<string, unknown>
): boolean {
return sameValues([...left.entries()].sort(), [...right.entries()].sort());
}
function scheduleError(mode: 'formal' | 'smoke'): never {
throw new Error(
`Xtream benchmark requires exactly ${mode === 'formal' ? 'five' : 'one'} measured runs per scenario`
);
}
function invalidIterationCollection(): never {
throw new Error('invalid iteration collection');
}
@@ -0,0 +1,88 @@
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import { mkdtemp, readFile, rm, symlink, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, describe, it } from 'node:test';
import { writeXtreamExclusiveArtifact } from './xtream-exclusive-artifact-writer';
const directories: string[] = [];
afterEach(async () => {
await Promise.all(
directories
.splice(0)
.map((directory) => rm(directory, { force: true, recursive: true }))
);
});
describe('Xtream exclusive artifact writer', () => {
it('durably writes exact bytes and returns their receipt', async () => {
const directory = await createDirectory();
const path = join(directory, 'raw.json');
const content = '{"safe":true}';
const receipt = await writeXtreamExclusiveArtifact(path, content);
assert.deepEqual(receipt, {
absolutePath: path,
bytes: Buffer.byteLength(content),
sha256: sha256(content),
});
assert.equal(await readFile(path, 'utf8'), content);
});
it('never truncates or replaces an existing artifact', async () => {
const directory = await createDirectory();
const path = join(directory, 'raw.json');
await writeFile(path, 'original', 'utf8');
await assert.rejects(
writeXtreamExclusiveArtifact(path, 'replacement'),
/Xtream artifact path is not exclusively writable/
);
assert.equal(await readFile(path, 'utf8'), 'original');
});
it('rejects a final-component symlink and relative paths', async () => {
const directory = await createDirectory();
const target = join(directory, 'target.json');
const alias = join(directory, 'alias.json');
await writeFile(target, 'target', 'utf8');
await symlink(target, alias);
await assert.rejects(
writeXtreamExclusiveArtifact(alias, 'replacement'),
/Xtream artifact path is not exclusively writable/
);
await assert.rejects(
writeXtreamExclusiveArtifact('relative.json', '{}'),
/Xtream artifact path is not exclusively writable/
);
assert.equal(await readFile(target, 'utf8'), 'target');
});
it('rejects empty payloads before creating a file', async () => {
const directory = await createDirectory();
const path = join(directory, 'empty.json');
await assert.rejects(
writeXtreamExclusiveArtifact(path, ''),
/Xtream artifact path is not exclusively writable/
);
await assert.rejects(readFile(path), { code: 'ENOENT' });
});
});
async function createDirectory(): Promise<string> {
const directory = await mkdtemp(
join(tmpdir(), 'iptvnator-xtream-exclusive-')
);
directories.push(directory);
return directory;
}
function sha256(value: string): string {
return createHash('sha256').update(value).digest('hex');
}
@@ -0,0 +1,49 @@
import { createHash } from 'node:crypto';
import { open } from 'node:fs/promises';
import { isAbsolute } from 'node:path';
import type { XtreamPersistenceReceipt } from './xtream-summary-contract';
export async function writeXtreamExclusiveArtifact(
absolutePath: string,
serialized: string
): Promise<XtreamPersistenceReceipt> {
try {
if (
typeof absolutePath !== 'string' ||
!isAbsolute(absolutePath) ||
typeof serialized !== 'string' ||
serialized.length === 0
) {
invalid();
}
const content = Buffer.from(serialized, 'utf8');
const handle = await open(absolutePath, 'wx', 0o600);
try {
await handle.writeFile(content);
await handle.sync();
const stats = await handle.stat();
if (
!stats.isFile() ||
stats.isSymbolicLink() ||
stats.nlink !== 1 ||
stats.size !== content.byteLength
) {
invalid();
}
} finally {
await handle.close();
}
return Object.freeze({
absolutePath,
bytes: content.byteLength,
sha256: createHash('sha256').update(content).digest('hex'),
});
} catch {
throw new Error('Xtream artifact path is not exclusively writable');
}
}
function invalid(): never {
throw new Error('invalid');
}
@@ -0,0 +1,154 @@
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import { link, mkdtemp, rm, unlink, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, describe, it } from 'node:test';
import { CPU_PROFILE } from './initial-import-diagnostic-test-fixtures';
import {
validateXtreamDiagnosticArtifacts,
type XtreamDiagnosticCapture,
} from './xtream-diagnostic-artifacts';
import { verifyXtreamPersistenceReceipt } from './xtream-raw-persistence-receipt';
const HEAP_SNAPSHOT = {
edges: [0, 0, 0],
nodes: [0, 0, 1, 0, 1, 0],
snapshot: {
meta: {
edge_fields: ['type', 'name_or_index', 'to_node'],
edge_types: [['context'], 'string_or_number', 'node'],
node_fields: [
'type',
'name',
'id',
'self_size',
'edge_count',
'detachedness',
],
node_types: [
['hidden'],
'string',
'number',
'number',
'number',
'number',
],
},
},
strings: ['', 'root'],
};
const RENDERER_TRACE = {
traceEvents: [{ name: 'xtream-diagnostic', ph: 'X', ts: 1 }],
};
const directories: string[] = [];
afterEach(async () => {
await Promise.all(
directories
.splice(0)
.map((directory) => rm(directory, { force: true, recursive: true }))
);
});
describe('Xtream filesystem evidence integrity', () => {
it('rejects a raw persistence file with an external hard-link alias', async () => {
const directory = await createDirectory('raw');
const outside = await createDirectory('raw-outside');
const serialized = '{"safe":true}';
const rawPath = join(directory, 'raw.json');
const externalAlias = join(outside, 'external-alias.json');
await writeFile(rawPath, serialized, 'utf8');
await link(rawPath, externalAlias);
await assert.rejects(
() =>
verifyXtreamPersistenceReceipt(serialized, {
absolutePath: rawPath,
bytes: Buffer.byteLength(serialized),
sha256: sha256(serialized),
}),
/^Error: invalid Xtream persistence receipt$/
);
});
it('rejects a diagnostic artifact with an external hard-link alias', async () => {
const directory = await createDirectory('diagnostic');
const outside = await createDirectory('outside');
await writeValidArtifacts(directory);
const tracePath = join(directory, 'renderer.trace.json');
const externalTrace = join(outside, 'renderer.trace.json');
await unlink(tracePath);
await writeFile(externalTrace, JSON.stringify(RENDERER_TRACE));
await link(externalTrace, tracePath);
await assert.rejects(
() =>
validateXtreamDiagnosticArtifacts(
capture(directory),
directory
),
/^Error: xtream-diagnostic-artifact-path-invalid:renderer-trace$/
);
});
});
function capture(directory: string): XtreamDiagnosticCapture {
return {
main: {
cpuProfilePath: join(directory, 'main.cpuprofile'),
heapSnapshotPath: join(directory, 'main.heapsnapshot'),
workers: [
{
kind: 'database.worker',
ordinal: 4,
profilePath: join(
directory,
'database.worker-4.cpuprofile'
),
snapshotPath: join(
directory,
'database.worker-4.heapsnapshot'
),
},
],
},
renderer: {
cpuProfilePath: join(directory, 'renderer.cpuprofile'),
heapSnapshotPath: join(directory, 'renderer.heapsnapshot'),
tracePath: join(directory, 'renderer.trace.json'),
},
};
}
async function createDirectory(label: string): Promise<string> {
const directory = await mkdtemp(
join(tmpdir(), `iptvnator-xtream-fs-${label}-`)
);
directories.push(directory);
return directory;
}
async function writeValidArtifacts(directory: string): Promise<void> {
await Promise.all([
writeJson(join(directory, 'main.cpuprofile'), CPU_PROFILE),
writeJson(join(directory, 'renderer.cpuprofile'), CPU_PROFILE),
writeJson(join(directory, 'database.worker-4.cpuprofile'), CPU_PROFILE),
writeJson(
join(directory, 'database.worker-4.heapsnapshot'),
HEAP_SNAPSHOT
),
writeJson(join(directory, 'main.heapsnapshot'), HEAP_SNAPSHOT),
writeJson(join(directory, 'renderer.heapsnapshot'), HEAP_SNAPSHOT),
writeJson(join(directory, 'renderer.trace.json'), RENDERER_TRACE),
]);
}
function writeJson(path: string, value: unknown): Promise<void> {
return writeFile(path, JSON.stringify(value));
}
function sha256(value: string): string {
return createHash('sha256').update(value).digest('hex');
}
@@ -0,0 +1,239 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_ITERATION_KIND,
XTREAM_SCENARIO_ID,
} from './xtream-benchmark-contract';
import { iteration } from './xtream-benchmark-report.fixtures';
import {
xtreamIpcProducerIdentityKey,
xtreamIpcProducerNamespaceForMethod,
xtreamIpcProducerNamespaceForWorkerOperation,
} from './xtream-ipc-producer-identity';
import { attributeXtreamPhases } from './xtream-phase-attribution';
import { scenarioCapture } from './xtream-phase-attribution.fixtures';
import { assertXtreamIterationResult } from './xtream-iteration-validity';
const DB_METHOD_OPERATION = new Map([
['dbDeletePlaylist', 'DB_DELETE_PLAYLIST'],
['dbDeleteXtreamContent', 'DB_DELETE_XTREAM_CONTENT'],
['dbGetAppPlaylist', 'DB_GET_APP_PLAYLIST'],
['dbGetCategories', 'DB_GET_CATEGORIES'],
['dbGetContent', 'DB_GET_CONTENT'],
['dbRestoreXtreamUserData', 'DB_RESTORE_XTREAM_USER_DATA'],
['dbSaveCategories', 'DB_SAVE_CATEGORIES'],
['dbSaveContent', 'DB_SAVE_CONTENT'],
['dbUpsertAppPlaylist', 'DB_UPSERT_APP_PLAYLIST'],
]);
describe('Xtream IPC attribution producer identity', () => {
it('requires exact pairs, distinct call IDs, and source chronology', () => {
const initial = scenarioCapture(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE
);
const requests = initial.ipcSpans
.filter(
({ boundary, method }) =>
boundary === 'request' && method === 'dbGetCategories'
)
.sort((left, right) => left.ipcCallId - right.ipcCallId);
const first = requests[0];
const second = requests[1];
assert.ok(first);
assert.ok(second);
const pairDrift = initial.ipcSpans.map((span) =>
span.correlationId === first.correlationId &&
span.boundary === 'response'
? { ...span, ipcCallId: span.ipcCallId + 1 }
: span
);
const sourcePairDrift = initial.ipcSpans.map((span) =>
span.correlationId === first.correlationId &&
span.boundary === 'response'
? { ...span, sourceEpochMs: span.sourceEpochMs + 0.01 }
: span
);
const duplicate = initial.ipcSpans.map((span) =>
span.correlationId === second.correlationId
? { ...span, ipcCallId: first.ipcCallId }
: span
);
const chronologyRegression = initial.ipcSpans.map((span) =>
span.correlationId === first.correlationId
? { ...span, sourceEpochMs: 100.75 }
: span
);
for (const ipcSpans of [
pairDrift,
sourcePairDrift,
duplicate,
chronologyRegression,
]) {
assert.throws(
() => attributeXtreamPhases({ ...initial, ipcSpans }),
/invalid Xtream phase capture/
);
}
});
it('accepts one numeric call ID in each independent preload producer namespace', () => {
const raw = iteration(
{
eligibleForComparison: true,
kind: XTREAM_ITERATION_KIND.MEASURED,
runId: 'run-01',
scenarioId: XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE,
},
1
);
const legacy = raw.phaseCapture.ipcSpans.find(
({ boundary, method }) =>
boundary === 'request' && method === 'dbUpsertAppPlaylist'
);
const xtream = raw.phaseCapture.ipcSpans.find(
({ boundary, method }) =>
boundary === 'request' && method === 'dbGetCategories'
);
assert.ok(legacy);
assert.ok(xtream);
assert.equal(legacy.ipcCallId, xtream.ipcCallId);
const legacySourceEpochMs = legacy.sourceEpochMs + 0.25;
const ipcSpans = raw.phaseCapture.ipcSpans.map((span) => {
if (
xtreamIpcProducerNamespaceForMethod(span.method) ===
'legacy-preload'
) {
return { ...span, sourceEpochMs: legacySourceEpochMs };
}
return span.correlationId === xtream.correlationId
? { ...span, ipcCallId: legacy.ipcCallId }
: span;
});
const requests = raw.databaseWorker.requests.evidence.map((request) => {
if (
xtreamIpcProducerNamespaceForWorkerOperation(
request.operation ?? ''
) === 'legacy-preload'
) {
return { ...request, sourceEpochMs: legacySourceEpochMs };
}
return request.ipcCallId === xtream.ipcCallId &&
request.operation === 'DB_GET_CATEGORIES'
? { ...request, ipcCallId: legacy.ipcCallId }
: request;
});
assert.doesNotThrow(() =>
assertXtreamIterationResult({
...raw,
databaseWorker: {
...raw.databaseWorker,
requests: {
...raw.databaseWorker.requests,
evidence: requests,
},
},
phaseCapture: { ...raw.phaseCapture, ipcSpans },
})
);
});
it('does not collide a cancellation call with the legacy preload namespace', () => {
const raw = iteration(
{
eligibleForComparison: true,
kind: XTREAM_ITERATION_KIND.MEASURED,
runId: 'run-01',
scenarioId: XTREAM_SCENARIO_ID.CANCEL_IMPORT,
},
1
);
const cancellation = raw.phaseCapture.ipcSpans.find(
({ boundary, method }) =>
boundary === 'request' && method === 'dbCancelOperation'
);
const legacy = raw.phaseCapture.ipcSpans.find(
({ boundary, method }) =>
boundary === 'request' && method === 'dbUpsertAppPlaylist'
);
assert.ok(cancellation);
assert.ok(legacy);
const ipcSpans = raw.phaseCapture.ipcSpans.map((span) =>
span.correlationId === legacy.correlationId
? { ...span, ipcCallId: cancellation.ipcCallId }
: span
);
const requests = raw.databaseWorker.requests.evidence.map((request) =>
request.operation === 'DB_UPSERT_APP_PLAYLIST' &&
request.ipcCallId === legacy.ipcCallId
? { ...request, ipcCallId: cancellation.ipcCallId }
: request
);
assert.doesNotThrow(() =>
assertXtreamIterationResult({
...raw,
databaseWorker: {
...raw.databaseWorker,
requests: {
...raw.databaseWorker.requests,
evidence: requests,
},
},
phaseCapture: { ...raw.phaseCapture, ipcSpans },
})
);
});
it('shares each database preload identity with its worker request', () => {
for (const scenarioId of Object.values(XTREAM_SCENARIO_ID)) {
const raw = iteration(
{
eligibleForComparison: true,
kind: XTREAM_ITERATION_KIND.MEASURED,
runId: 'run-01',
scenarioId,
},
1
);
const workersByProducerIdentity = new Map(
raw.databaseWorker.requests.evidence.flatMap((request) =>
request.ipcCallId === null
? []
: [
[
workerIdentityKey(
request.operation ?? '',
request.ipcCallId
),
request,
] as const,
]
)
);
for (const span of raw.phaseCapture.ipcSpans) {
if (span.boundary !== 'request') continue;
const operation = DB_METHOD_OPERATION.get(span.method);
if (!operation) continue;
const namespace = xtreamIpcProducerNamespaceForMethod(
span.method
);
assert.ok(namespace);
const worker = workersByProducerIdentity.get(
xtreamIpcProducerIdentityKey(namespace, span.ipcCallId)
);
assert.ok(worker);
assert.equal(worker.operation, operation);
assert.equal(worker.sourceEpochMs, span.sourceEpochMs);
}
}
});
});
function workerIdentityKey(operation: string, ipcCallId: number): string {
const namespace = xtreamIpcProducerNamespaceForWorkerOperation(operation);
assert.ok(namespace);
return xtreamIpcProducerIdentityKey(namespace, ipcCallId);
}
@@ -0,0 +1,67 @@
export interface XtreamIpcMarkerCaptureOptions {
readonly actions: readonly string[];
readonly mainPhases: readonly string[];
readonly methods: readonly string[];
readonly schemaVersion: number;
}
export interface XtreamIpcRequestIdentity {
ipcCallId: number | null;
operationId: string | null;
operationIdUnavailableReason: string | null;
sourceEpochMs: number | null;
}
export interface XtreamIpcCallState {
completionOutcome: 'error' | 'success' | null;
downstreamMatched: boolean;
ended: boolean;
key: string;
marker: import('./xtream-ipc-marker-protocol').SafeXtreamPreloadMarker;
quarantined: boolean;
receivedEpochMs: number;
}
export interface XtreamMainPhaseState {
endEpochMs: number | null;
startEpochMs: number;
}
export interface XtreamIpcTimelineRecord {
readonly action?: string | null;
readonly boundary: 'end' | 'start';
readonly categoryType?: string | null;
readonly contentType?: string | null;
readonly durationMs?: number | null;
readonly epochMs: number;
readonly ipcCallId?: number;
readonly itemCount?: number | null;
readonly method?: string;
readonly operationId?: string | null;
readonly outcome?: 'error' | 'success' | null;
readonly phase?: string;
readonly playlistId?: string | null;
readonly requestId?: string;
readonly sessionId?: string | null;
readonly sourceEpochMs?: number;
readonly type: 'xtream-main-phase' | 'xtream-preload-marker';
}
export interface XtreamIpcMarkerCaptureSnapshot {
readonly invalidReasons: readonly string[];
readonly quarantinedKeyCount: number;
readonly timeline: readonly XtreamIpcTimelineRecord[];
}
export interface XtreamIpcMarkerCapture {
acceptMainPhase(input: unknown): boolean;
acceptPreload(
senderWebContentsId: number,
receivedEpochMs: number,
input: unknown
): boolean;
matchDatabaseCancel(input: unknown): XtreamIpcRequestIdentity | null;
matchDatabaseRequest(input: unknown): XtreamIpcRequestIdentity | null;
start(expectedWebContentsId: number, captureStartedEpochMs: number): void;
stop(): XtreamIpcMarkerCaptureSnapshot;
}
@@ -0,0 +1,379 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_MAIN_PERFORMANCE_PHASE,
XTREAM_PRELOAD_PERFORMANCE_METHOD,
XtreamCodeActions,
} from '@iptvnator/shared/interfaces';
import {
createXtreamIpcMarkerCapture,
type XtreamIpcMarkerCaptureOptions,
} from './xtream-ipc-marker-events';
import { createXtreamIpcMarkerProtocol } from './xtream-ipc-marker-protocol';
import { createXtreamMainLifecycleValidator } from './xtream-main-lifecycle';
const options: XtreamIpcMarkerCaptureOptions = {
actions: Object.values(XtreamCodeActions),
mainPhases: Object.values(XTREAM_MAIN_PERFORMANCE_PHASE),
methods: Object.values(XTREAM_PRELOAD_PERFORMANCE_METHOD),
schemaVersion: 1,
};
function marker(overrides: Record<string, unknown> = {}) {
return {
schemaVersion: 1,
sourceEpochMs: 100,
ipcCallId: 1,
method: 'dbSaveContent',
boundary: 'start',
outcome: null,
playlistId: 'playlist-1',
operationId: 'operation-1',
sessionId: null,
action: null,
categoryType: null,
contentType: 'live',
itemCount: 60_000,
...overrides,
};
}
describe('Xtream preload marker capture', () => {
it('restores both factories without module closures for Electron-main injection', () => {
const restore = <T>(source: string): T =>
new Function(`"use strict"; return (${source});`)() as T;
const protocolFactory = restore<typeof createXtreamIpcMarkerProtocol>(
createXtreamIpcMarkerProtocol.toString()
);
const captureFactory = restore<typeof createXtreamIpcMarkerCapture>(
createXtreamIpcMarkerCapture.toString()
);
const lifecycleFactory = restore<
typeof createXtreamMainLifecycleValidator
>(createXtreamMainLifecycleValidator.toString());
const capture = captureFactory(
options,
protocolFactory(options),
lifecycleFactory()
);
capture.start(42, 90);
assert.equal(capture.acceptPreload(42, 101, marker()), true);
});
it('accepts only the exact 13-key safe schema from the bound webContents', () => {
const capture = createXtreamIpcMarkerCapture(options);
capture.start(42, 90);
assert.equal(capture.acceptPreload(42, 101, marker()), true);
assert.equal(
capture.acceptPreload(
42,
102,
marker({
boundary: 'end',
outcome: 'success',
sourceEpochMs: 101,
})
),
true
);
const snapshot = capture.stop();
assert.deepEqual(snapshot.invalidReasons, []);
assert.equal(snapshot.quarantinedKeyCount, 0);
assert.equal(snapshot.timeline.length, 2);
assert.deepEqual(snapshot.timeline[0], {
action: null,
boundary: 'start',
categoryType: null,
contentType: 'live',
epochMs: 101,
ipcCallId: 1,
itemCount: 60_000,
method: 'dbSaveContent',
operationId: 'operation-1',
outcome: null,
playlistId: 'playlist-1',
sessionId: null,
sourceEpochMs: 100,
type: 'xtream-preload-marker',
});
});
it('normalizes sub-millisecond cross-process clock skew and rejects larger reversals', () => {
const capture = createXtreamIpcMarkerCapture(options);
capture.start(42, 90);
assert.equal(
capture.acceptPreload(42, 100, marker({ sourceEpochMs: 100.006 })),
true
);
assert.equal(
capture.acceptPreload(
42,
101,
marker({
boundary: 'end',
outcome: 'success',
sourceEpochMs: 101.006,
})
),
true
);
const snapshot = capture.stop();
assert.deepEqual(snapshot.invalidReasons, []);
assert.equal(snapshot.timeline[0]?.epochMs, 100.006);
assert.equal(snapshot.timeline[1]?.epochMs, 101.006);
const reversed = createXtreamIpcMarkerCapture(options);
reversed.start(42, 90);
assert.equal(
reversed.acceptPreload(42, 100, marker({ sourceEpochMs: 101.001 })),
false
);
assert.ok(
reversed
.stop()
.invalidReasons.includes('preload-marker-source-after-receipt')
);
});
it('rejects delayed preload markers from a completed capture generation', () => {
const capture = createXtreamIpcMarkerCapture(options);
capture.start(42, 90);
capture.stop();
capture.start(42, 200);
assert.equal(capture.acceptPreload(42, 210, marker()), false);
assert.equal(
capture.acceptPreload(
42,
211,
marker({
boundary: 'end',
outcome: 'success',
sourceEpochMs: 101,
})
),
false
);
assert.ok(
capture
.stop()
.invalidReasons.includes('preload-marker-before-capture-start')
);
});
it('rejects another sender, extra or missing keys, malformed IDs, and regressing epochs', () => {
const invalidCases: Array<{
first?: Record<string, unknown>;
input: Record<string, unknown>;
receivedEpochMs?: number;
sender?: number;
}> = [
{ input: marker(), sender: 7 },
{ input: { ...marker(), password: 'provider-secret' } },
{
input: Object.fromEntries(
Object.entries(marker()).filter(
([key]) => key !== 'itemCount'
)
),
},
{ input: marker({ playlistId: ' playlist-1' }) },
{ input: marker({ ipcCallId: 0 }) },
{ input: marker({ outcome: 'success' }) },
{
first: marker(),
input: marker({
boundary: 'end',
outcome: 'success',
sourceEpochMs: 99,
}),
receivedEpochMs: 102,
},
{
input: marker({ sourceEpochMs: 102 }),
receivedEpochMs: 101,
},
];
for (const testCase of invalidCases) {
const capture = createXtreamIpcMarkerCapture(options);
capture.start(42, 90);
if (testCase.first) {
assert.equal(
capture.acceptPreload(42, 101, testCase.first),
true
);
}
assert.equal(
capture.acceptPreload(
testCase.sender ?? 42,
testCase.receivedEpochMs ?? 101,
testCase.input
),
false
);
assert.notEqual(capture.stop().invalidReasons.length, 0);
}
});
it('correlates DB requests FIFO and quarantines overlapping duplicate keys', () => {
const capture = createXtreamIpcMarkerCapture(options);
capture.start(42, 90);
assert.equal(capture.acceptPreload(42, 100, marker()), true);
const identity = capture.matchDatabaseRequest({
operation: 'DB_SAVE_CONTENT',
payload: {
operationId: 'operation-1',
playlistId: 'playlist-1',
type: 'live',
},
});
assert.deepEqual(identity, {
ipcCallId: 1,
operationId: 'operation-1',
operationIdUnavailableReason: null,
sourceEpochMs: 100,
});
assert.equal(
capture.matchDatabaseRequest({
operation: 'DB_GET_APP_PLAYLIST',
payload: { playlistId: 'playlist-1' },
}),
null
);
const duplicateCapture = createXtreamIpcMarkerCapture(options);
duplicateCapture.start(42, 90);
assert.equal(duplicateCapture.acceptPreload(42, 100, marker()), true);
assert.equal(
duplicateCapture.acceptPreload(
42,
101,
marker({ ipcCallId: 2, sourceEpochMs: 101 })
),
false
);
assert.deepEqual(
duplicateCapture.matchDatabaseRequest({
operation: 'DB_SAVE_CONTENT',
payload: {
operationId: 'operation-1',
playlistId: 'playlist-1',
type: 'live',
},
}),
{
ipcCallId: null,
operationId: null,
operationIdUnavailableReason:
'xtream-preload-performance-marker-ambiguous',
sourceEpochMs: null,
}
);
assert.equal(duplicateCapture.stop().quarantinedKeyCount, 1);
});
it('retains a mutable missing identity when a valid preload start arrives after the worker request', () => {
const capture = createXtreamIpcMarkerCapture(options);
capture.start(42, 90);
const identity = capture.matchDatabaseRequest({
operation: 'DB_SAVE_CONTENT',
payload: {
operationId: 'operation-1',
playlistId: 'playlist-1',
type: 'live',
},
});
assert.deepEqual(identity, {
ipcCallId: null,
operationId: null,
operationIdUnavailableReason:
'xtream-preload-performance-marker-missing',
sourceEpochMs: null,
});
assert.equal(capture.acceptPreload(42, 100, marker()), true);
assert.deepEqual(identity, {
ipcCallId: 1,
operationId: 'operation-1',
operationIdUnavailableReason: null,
sourceEpochMs: 100,
});
});
it('correlates read-only content requests without inventing an operation ID', () => {
const capture = createXtreamIpcMarkerCapture(options);
capture.start(42, 90);
assert.equal(
capture.acceptPreload(
42,
100,
marker({
ipcCallId: 3,
itemCount: null,
method: 'dbGetContent',
operationId: null,
})
),
true
);
assert.deepEqual(
capture.matchDatabaseRequest({
operation: 'DB_GET_CONTENT',
payload: { playlistId: 'playlist-1', type: 'live' },
}),
{
ipcCallId: 3,
operationId: null,
operationIdUnavailableReason: null,
sourceEpochMs: 100,
}
);
});
it('correlates the preload cancel call separately from the active DB request', () => {
const capture = createXtreamIpcMarkerCapture(options);
capture.start(42, 90);
const cancelMarker = marker({
contentType: null,
ipcCallId: 4,
itemCount: null,
method: 'dbCancelOperation',
playlistId: null,
});
assert.equal(capture.acceptPreload(42, 100, cancelMarker), true);
assert.deepEqual(
capture.matchDatabaseCancel({
operationId: 'operation-1',
type: 'cancel',
}),
{
ipcCallId: 4,
operationId: 'operation-1',
operationIdUnavailableReason: null,
sourceEpochMs: 100,
}
);
assert.equal(
capture.acceptPreload(
42,
102,
marker({
...cancelMarker,
boundary: 'end',
outcome: 'success',
sourceEpochMs: 101,
})
),
true
);
assert.deepEqual(capture.stop().invalidReasons, []);
});
});
@@ -0,0 +1,399 @@
import {
createXtreamIpcMarkerProtocol,
type XtreamIpcMarkerProtocol,
} from './xtream-ipc-marker-protocol';
import type {
XtreamIpcCallState,
XtreamIpcMarkerCapture,
XtreamIpcMarkerCaptureOptions,
XtreamIpcRequestIdentity,
XtreamIpcTimelineRecord,
XtreamMainPhaseState,
} from './xtream-ipc-marker-events.model';
import {
createXtreamMainLifecycleValidator,
type XtreamMainLifecycleValidator,
} from './xtream-main-lifecycle';
export { deriveXtreamAcquisitionDurationMs } from './xtream-acquisition-duration';
export type * from './xtream-ipc-marker-events.model';
export function createXtreamIpcMarkerCapture(
options: XtreamIpcMarkerCaptureOptions,
protocol: XtreamIpcMarkerProtocol = createXtreamIpcMarkerProtocol(options),
mainLifecycle: XtreamMainLifecycleValidator = createXtreamMainLifecycleValidator()
): XtreamIpcMarkerCapture {
let active = false;
let captureStartedEpochMs = 0;
let expectedWebContentsId: number | null = null;
let lastMainEpochMs = 0;
let lastReceivedEpochMs = 0;
let lastSourceEpochMs = 0;
let timeline: XtreamIpcTimelineRecord[] = [];
let invalidReasons: string[] = [];
const preloadSourceReceiptSkewToleranceMs = 1;
const calls = new Map<number, XtreamIpcCallState>();
const activeByKey = new Map<string, XtreamIpcCallState>();
const pendingRequests = new Map<string, XtreamIpcRequestIdentity[]>();
const quarantinedKeys = new Set<string>();
const mainPhases = new Map<string, XtreamMainPhaseState>();
const mainRequestCalls = new Map<string, XtreamIpcCallState>();
const helpers = {
invalidate(reason: string): false {
invalidReasons.push(reason);
return false;
},
mainPhasesForRequest(
requestId: string
): readonly (XtreamMainPhaseState & { readonly phase: string })[] {
const prefix = `${requestId}\u0000`;
return [...mainPhases.entries()]
.filter(([key]) => key.startsWith(prefix))
.map(([key, state]) => ({
...state,
phase: key.slice(prefix.length),
}));
},
matchKey(
key: string | null | undefined
): XtreamIpcRequestIdentity | null {
if (key === undefined) {
return null;
}
if (key === null || quarantinedKeys.has(key)) {
return protocol.unavailableIdentity(
'xtream-preload-performance-marker-ambiguous'
);
}
const call = activeByKey.get(key);
if (call && !call.downstreamMatched && !call.quarantined) {
call.downstreamMatched = true;
const identity = protocol.unavailableIdentity(
'xtream-preload-performance-marker-missing'
);
protocol.applyMarkerIdentity(identity, call.marker);
return identity;
}
const identity = protocol.unavailableIdentity(
'xtream-preload-performance-marker-missing'
);
const waiting = pendingRequests.get(key) ?? [];
waiting.push(identity);
pendingRequests.set(key, waiting);
if (waiting.length > 1) {
helpers.quarantine(key);
}
return identity;
},
quarantine(key: string): void {
quarantinedKeys.add(key);
const activeCall = activeByKey.get(key);
if (activeCall) {
activeCall.quarantined = true;
activeByKey.delete(key);
}
for (const identity of pendingRequests.get(key) ?? []) {
Object.assign(
identity,
protocol.unavailableIdentity(
'xtream-preload-performance-marker-ambiguous'
)
);
}
pendingRequests.delete(key);
},
};
return {
acceptMainPhase(input) {
if (!active) return false;
const event = protocol.parseMainPhase(input);
if (!event) {
return helpers.invalidate('main-phase-invalid');
}
const { boundary, durationMs, epochMs, phase, requestId } = event;
if (epochMs < captureStartedEpochMs) {
return helpers.invalidate('main-phase-before-capture-start');
}
if (epochMs < lastMainEpochMs) {
return helpers.invalidate('main-phase-invalid');
}
lastMainEpochMs = epochMs;
const boundaryKey = `${requestId}\u0000${phase}`;
const phaseState = mainPhases.get(boundaryKey);
if (boundary === 'start') {
if (phaseState) {
return helpers.invalidate('main-phase-duplicate-boundary');
}
mainPhases.set(boundaryKey, {
endEpochMs: null,
startEpochMs: epochMs,
});
} else {
if (
!phaseState ||
phaseState.endEpochMs !== null ||
epochMs < phaseState.startEpochMs
) {
return helpers.invalidate('main-phase-duplicate-boundary');
}
phaseState.endEpochMs = epochMs;
}
let call = mainRequestCalls.get(requestId);
if (
!call &&
boundary === 'start' &&
(phase === 'xtream.network.total' ||
phase === 'xtream.cancel-session')
) {
const method =
phase === 'xtream.network.total'
? 'xtreamRequest'
: 'xtreamCancelSession';
call = [...calls.values()]
.filter(
(candidate) =>
!candidate.ended &&
!candidate.quarantined &&
!candidate.downstreamMatched &&
candidate.marker.method === method
)
.sort(
(left, right) =>
left.receivedEpochMs - right.receivedEpochMs ||
left.marker.ipcCallId - right.marker.ipcCallId
)[0];
if (call) {
call.downstreamMatched = true;
mainRequestCalls.set(requestId, call);
} else {
invalidReasons.push(
'main-phase-preload-performance-marker-missing'
);
}
}
timeline.push({
...(call
? {
action: call.marker.action,
categoryType: call.marker.categoryType,
contentType: call.marker.contentType,
ipcCallId: call.marker.ipcCallId,
}
: {}),
boundary,
durationMs: durationMs as number | null,
epochMs,
phase,
requestId,
type: 'xtream-main-phase',
});
return true;
},
acceptPreload(senderWebContentsId, receivedEpochMs, input) {
if (
!active ||
senderWebContentsId !== expectedWebContentsId ||
!protocol.isEpoch(receivedEpochMs)
) {
return helpers.invalidate(
'preload-marker-sender-or-epoch-invalid'
);
}
if (receivedEpochMs < captureStartedEpochMs) {
return helpers.invalidate(
'preload-marker-before-capture-start'
);
}
if (receivedEpochMs < lastReceivedEpochMs) {
return helpers.invalidate(
'preload-marker-sender-or-epoch-invalid'
);
}
const marker = protocol.parseMarker(input);
if (!marker) {
return helpers.invalidate('preload-marker-invalid-schema');
}
if (marker.sourceEpochMs < captureStartedEpochMs) {
return helpers.invalidate(
'preload-marker-before-capture-start'
);
}
if (
marker.sourceEpochMs - receivedEpochMs >=
preloadSourceReceiptSkewToleranceMs
) {
return helpers.invalidate(
'preload-marker-source-after-receipt'
);
}
const normalizedReceivedEpochMs = Math.max(
receivedEpochMs,
marker.sourceEpochMs
);
if (marker.sourceEpochMs < lastSourceEpochMs) {
return helpers.invalidate(
'preload-marker-source-epoch-regressed'
);
}
const key = protocol.correlationKey(marker);
if (!key) {
return helpers.invalidate(
'preload-marker-correlation-key-invalid'
);
}
lastReceivedEpochMs = receivedEpochMs;
lastSourceEpochMs = marker.sourceEpochMs;
if (marker.boundary === 'start') {
if (calls.has(marker.ipcCallId) || activeByKey.has(key)) {
helpers.quarantine(key);
return helpers.invalidate('preload-marker-duplicate-key');
}
const call: XtreamIpcCallState = {
completionOutcome: null,
downstreamMatched: false,
ended: false,
key,
marker,
quarantined: false,
receivedEpochMs: normalizedReceivedEpochMs,
};
calls.set(marker.ipcCallId, call);
activeByKey.set(key, call);
const waiting = pendingRequests.get(key) ?? [];
if (waiting.length === 1 && waiting[0]) {
protocol.applyMarkerIdentity(waiting[0], marker);
call.downstreamMatched = true;
pendingRequests.delete(key);
} else if (waiting.length > 1) {
helpers.quarantine(key);
return helpers.invalidate('preload-marker-duplicate-key');
}
} else {
const call = calls.get(marker.ipcCallId);
if (
!call ||
call.ended ||
call.quarantined ||
call.key !== key ||
!protocol.sameMarkerIdentity(call.marker, marker)
) {
return helpers.invalidate('preload-marker-unmatched-end');
}
call.ended = true;
call.completionOutcome = marker.outcome;
activeByKey.delete(key);
}
timeline.push({
action: marker.action,
boundary: marker.boundary,
categoryType: marker.categoryType,
contentType: marker.contentType,
epochMs: normalizedReceivedEpochMs,
ipcCallId: marker.ipcCallId,
itemCount: marker.itemCount,
method: marker.method,
operationId: marker.operationId,
outcome: marker.outcome,
playlistId: marker.playlistId,
sessionId: marker.sessionId,
sourceEpochMs: marker.sourceEpochMs,
type: 'xtream-preload-marker',
});
return true;
},
matchDatabaseCancel(input) {
if (!active) {
return null;
}
try {
return helpers.matchKey(protocol.readCancelKey(input));
} catch {
helpers.invalidate('preload-marker-correlation-input-invalid');
return protocol.unavailableIdentity(
'xtream-preload-performance-marker-ambiguous'
);
}
},
matchDatabaseRequest(input) {
if (!active) {
return null;
}
try {
return helpers.matchKey(protocol.readRequestKey(input));
} catch {
helpers.invalidate('preload-marker-correlation-input-invalid');
return protocol.unavailableIdentity(
'xtream-preload-performance-marker-ambiguous'
);
}
},
start(webContentsId, startedEpochMs) {
const validStart = protocol.isEpoch(startedEpochMs);
active = true;
captureStartedEpochMs = validStart
? startedEpochMs
: Number.POSITIVE_INFINITY;
expectedWebContentsId = webContentsId;
lastMainEpochMs = captureStartedEpochMs;
lastReceivedEpochMs = captureStartedEpochMs;
lastSourceEpochMs = captureStartedEpochMs;
timeline = [];
invalidReasons = [];
if (!validStart) {
invalidReasons.push('capture-start-epoch-invalid');
}
calls.clear();
activeByKey.clear();
pendingRequests.clear();
quarantinedKeys.clear();
mainPhases.clear();
mainRequestCalls.clear();
},
stop() {
for (const call of calls.values()) {
if (!call.ended && !call.quarantined) {
invalidReasons.push('preload-marker-unclosed');
}
if (
call.ended &&
(call.marker.method === 'xtreamRequest' ||
call.marker.method === 'xtreamCancelSession')
) {
const linkedRequest = [...mainRequestCalls.entries()].find(
([, candidate]) => candidate === call
);
if (!linkedRequest) {
invalidReasons.push('preload-main-linkage-missing');
continue;
}
const lifecycleInvalidReason = mainLifecycle.validate({
method: call.marker.method,
outcome: call.completionOutcome,
phases: helpers.mainPhasesForRequest(linkedRequest[0]),
});
if (lifecycleInvalidReason) {
invalidReasons.push(lifecycleInvalidReason);
}
}
}
for (const phase of mainPhases.values()) {
if (phase.endEpochMs === null) {
invalidReasons.push('main-phase-unclosed');
}
}
for (const key of mainPhases.keys()) {
const requestId = key.slice(0, key.indexOf('\u0000'));
if (!mainRequestCalls.has(requestId)) {
invalidReasons.push(
'main-phase-preload-performance-marker-missing'
);
}
}
active = false;
expectedWebContentsId = null;
return Object.freeze({
invalidReasons: Object.freeze([...invalidReasons]),
quarantinedKeyCount: quarantinedKeys.size,
timeline: Object.freeze([...timeline]),
});
},
};
}
@@ -0,0 +1,333 @@
import type { XtreamIpcMarkerCaptureOptions } from './xtream-ipc-marker-events.model';
import type { XtreamIpcRequestIdentity } from './xtream-ipc-marker-events.model';
export interface SafeXtreamPreloadMarker {
action: string | null;
boundary: 'end' | 'start';
categoryType: string | null;
contentType: string | null;
ipcCallId: number;
itemCount: number | null;
method: string;
operationId: string | null;
outcome: 'error' | 'success' | null;
playlistId: string | null;
schemaVersion: number;
sessionId: string | null;
sourceEpochMs: number;
}
export interface SafeXtreamMainPhase {
boundary: 'end' | 'start';
durationMs: number | null;
epochMs: number;
phase: string;
requestId: string;
}
export interface XtreamIpcMarkerProtocol {
applyMarkerIdentity(
identity: XtreamIpcRequestIdentity,
marker: SafeXtreamPreloadMarker
): void;
correlationKey(marker: SafeXtreamPreloadMarker): string | null;
isEpoch(value: unknown): value is number;
parseMainPhase(input: unknown): SafeXtreamMainPhase | null;
parseMarker(input: unknown): SafeXtreamPreloadMarker | null;
readCancelKey(input: unknown): string | null | undefined;
readRequestKey(input: unknown): string | null | undefined;
sameMarkerIdentity(
start: SafeXtreamPreloadMarker,
end: SafeXtreamPreloadMarker
): boolean;
unavailableIdentity(reason: string): XtreamIpcRequestIdentity;
}
export function createXtreamIpcMarkerProtocol(
options: XtreamIpcMarkerCaptureOptions
): XtreamIpcMarkerProtocol {
type JsonRecord = Record<string, unknown>;
const markerKeys = new Set([
'schemaVersion',
'sourceEpochMs',
'ipcCallId',
'method',
'boundary',
'outcome',
'playlistId',
'operationId',
'sessionId',
'action',
'categoryType',
'contentType',
'itemCount',
]);
const actions = new Set(options.actions);
const mainPhases = new Set(options.mainPhases);
const methods = new Set(options.methods);
const categoryTypes = new Set(['live', 'movies', 'series']);
const contentTypes = new Set(['live', 'movie', 'series']);
const identifierPattern = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
const rendererRequestId = /^xtream-[0-9a-z]+-[1-9][0-9]*$/;
const internalRequestId =
/^xtream-main-(?:fallback-[1-9][0-9]*|[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})$/;
const operationToMethod: Readonly<Record<string, string>> = {
DB_DELETE_PLAYLIST: 'dbDeletePlaylist',
DB_DELETE_XTREAM_CONTENT: 'dbDeleteXtreamContent',
DB_GET_CATEGORIES: 'dbGetCategories',
DB_GET_CONTENT: 'dbGetContent',
DB_GLOBAL_SEARCH: 'dbGlobalSearch',
DB_RESTORE_XTREAM_USER_DATA: 'dbRestoreXtreamUserData',
DB_SAVE_CATEGORIES: 'dbSaveCategories',
DB_SAVE_CONTENT: 'dbSaveContent',
DB_SEARCH_CONTENT: 'dbSearchContent',
};
const helpers = {
correlationKey(marker: SafeXtreamPreloadMarker): string | null {
const values: Array<number | string | null> = [marker.method];
switch (marker.method) {
case 'xtreamRequest':
if (marker.action === null) return null;
values.push(marker.ipcCallId);
break;
case 'xtreamCancelSession':
values.push(marker.sessionId);
break;
case 'dbGetCategories':
case 'dbSaveCategories':
values.push(marker.playlistId, marker.categoryType);
break;
case 'dbGetContent':
values.push(marker.playlistId, marker.contentType);
break;
case 'dbSaveContent':
values.push(
marker.playlistId,
marker.contentType,
marker.operationId
);
break;
case 'dbDeletePlaylist':
values.push(
marker.playlistId,
marker.operationId ?? '<no-operation-id>'
);
break;
case 'dbDeleteXtreamContent':
case 'dbRestoreXtreamUserData':
values.push(marker.playlistId, marker.operationId);
break;
case 'dbSearchContent':
values.push(marker.playlistId);
break;
case 'dbGlobalSearch':
break;
case 'dbCancelOperation':
values.push(marker.operationId);
break;
default:
return null;
}
return values.some((value) => value === null)
? null
: JSON.stringify(values);
},
isEpoch(value: unknown): value is number {
return (
typeof value === 'number' && Number.isFinite(value) && value > 0
);
},
isIdentifier(value: unknown): value is string {
return typeof value === 'string' && identifierPattern.test(value);
},
isNullableIdentifier(value: unknown): value is string | null {
return value === null || helpers.isIdentifier(value);
},
isNullableMember(
value: unknown,
allowed: ReadonlySet<string>
): value is string | null {
return (
value === null ||
(typeof value === 'string' && allowed.has(value))
);
},
isRecord(value: unknown): value is JsonRecord {
return (
typeof value === 'object' &&
value !== null &&
!Array.isArray(value)
);
},
};
return {
applyMarkerIdentity(identity, marker): void {
identity.ipcCallId = marker.ipcCallId;
identity.operationId = marker.operationId;
identity.operationIdUnavailableReason = null;
identity.sourceEpochMs = marker.sourceEpochMs;
},
correlationKey(marker): string | null {
return helpers.correlationKey(marker);
},
isEpoch(value): value is number {
return helpers.isEpoch(value);
},
parseMainPhase(input): SafeXtreamMainPhase | null {
try {
if (!helpers.isRecord(input)) {
return null;
}
const boundary = input['boundary'];
const durationMs = input['durationMs'];
const epochMs = input['epochMs'];
const phase = input['phase'];
const requestId = input['requestId'];
if (
(boundary !== 'start' && boundary !== 'end') ||
!helpers.isEpoch(epochMs) ||
typeof phase !== 'string' ||
!mainPhases.has(phase) ||
typeof requestId !== 'string' ||
requestId.length > 64 ||
(!rendererRequestId.test(requestId) &&
!internalRequestId.test(requestId)) ||
(boundary === 'start'
? durationMs !== null
: typeof durationMs !== 'number' ||
!Number.isFinite(durationMs) ||
durationMs < 0)
) {
return null;
}
return {
boundary,
durationMs: durationMs as number | null,
epochMs,
phase,
requestId,
};
} catch {
return null;
}
},
parseMarker(input): SafeXtreamPreloadMarker | null {
try {
if (
!helpers.isRecord(input) ||
Reflect.ownKeys(input).length !== markerKeys.size ||
Reflect.ownKeys(input).some(
(key) => typeof key !== 'string' || !markerKeys.has(key)
)
) {
return null;
}
const boundary = input['boundary'];
const outcome = input['outcome'];
const itemCount = input['itemCount'];
if (
input['schemaVersion'] !== options.schemaVersion ||
!helpers.isEpoch(input['sourceEpochMs']) ||
!Number.isSafeInteger(input['ipcCallId']) ||
Number(input['ipcCallId']) < 1 ||
typeof input['method'] !== 'string' ||
!methods.has(input['method']) ||
(boundary !== 'start' && boundary !== 'end') ||
(boundary === 'start'
? outcome !== null
: outcome !== 'success' && outcome !== 'error') ||
!helpers.isNullableIdentifier(input['playlistId']) ||
!helpers.isNullableIdentifier(input['operationId']) ||
!helpers.isNullableIdentifier(input['sessionId']) ||
!helpers.isNullableMember(input['action'], actions) ||
!helpers.isNullableMember(
input['categoryType'],
categoryTypes
) ||
!helpers.isNullableMember(
input['contentType'],
contentTypes
) ||
(itemCount !== null &&
(!Number.isSafeInteger(itemCount) ||
Number(itemCount) < 0 ||
Number(itemCount) > 1_000_000))
) {
return null;
}
return input as unknown as SafeXtreamPreloadMarker;
} catch {
return null;
}
},
readCancelKey(input): string | null | undefined {
if (!helpers.isRecord(input) || input['type'] !== 'cancel') {
return undefined;
}
return helpers.correlationKey({
method: 'dbCancelOperation',
operationId:
typeof input['operationId'] === 'string'
? input['operationId']
: null,
} as SafeXtreamPreloadMarker);
},
readRequestKey(input): string | null | undefined {
if (
!helpers.isRecord(input) ||
typeof input['operation'] !== 'string'
) {
return undefined;
}
const method = operationToMethod[input['operation']];
if (!method) {
return undefined;
}
const payload = helpers.isRecord(input['payload'])
? input['payload']
: {};
return helpers.correlationKey({
method,
playlistId:
typeof payload['playlistId'] === 'string'
? payload['playlistId']
: null,
operationId:
typeof payload['operationId'] === 'string'
? payload['operationId']
: null,
categoryType:
typeof payload['type'] === 'string' &&
categoryTypes.has(payload['type'])
? payload['type']
: null,
contentType:
typeof payload['type'] === 'string' &&
contentTypes.has(payload['type'])
? payload['type']
: null,
} as SafeXtreamPreloadMarker);
},
sameMarkerIdentity(start, end): boolean {
return (
start.ipcCallId === end.ipcCallId &&
start.method === end.method &&
start.playlistId === end.playlistId &&
start.operationId === end.operationId &&
start.sessionId === end.sessionId &&
start.action === end.action &&
start.categoryType === end.categoryType &&
start.contentType === end.contentType &&
start.itemCount === end.itemCount
);
},
unavailableIdentity(reason): XtreamIpcRequestIdentity {
return {
ipcCallId: null,
operationId: null,
operationIdUnavailableReason: reason,
sourceEpochMs: null,
};
},
};
}
@@ -0,0 +1,96 @@
import {
XTREAM_WORKER_REQUEST_IDENTITY_KIND,
xtreamWorkerRequestIdentityKind,
} from './xtream-worker-request-identity';
export const XTREAM_IPC_PRODUCER_NAMESPACE = {
LEGACY_PRELOAD: 'legacy-preload',
XTREAM_PRELOAD: 'xtream-preload',
} as const;
export type XtreamIpcProducerNamespace =
(typeof XTREAM_IPC_PRODUCER_NAMESPACE)[keyof typeof XTREAM_IPC_PRODUCER_NAMESPACE];
export interface XtreamIpcProducerIdentity {
readonly ipcCallId: number;
readonly namespace: XtreamIpcProducerNamespace;
readonly sourceEpochMs: number;
}
const LEGACY_PRELOAD_METHODS = new Set<string>([
'dbGetAppPlaylist',
'dbUpsertAppPlaylist',
]);
const XTREAM_PRELOAD_METHODS = new Set<string>([
'dbCancelOperation',
'dbDeletePlaylist',
'dbDeleteXtreamContent',
'dbGetCategories',
'dbGetContent',
'dbGlobalSearch',
'dbRestoreXtreamUserData',
'dbSaveCategories',
'dbSaveContent',
'dbSearchContent',
'xtreamCancelSession',
'xtreamRequest',
]);
export function xtreamIpcProducerNamespaceForMethod(
method: string
): XtreamIpcProducerNamespace | null {
if (LEGACY_PRELOAD_METHODS.has(method)) {
return XTREAM_IPC_PRODUCER_NAMESPACE.LEGACY_PRELOAD;
}
if (XTREAM_PRELOAD_METHODS.has(method)) {
return XTREAM_IPC_PRODUCER_NAMESPACE.XTREAM_PRELOAD;
}
return null;
}
export function xtreamIpcProducerNamespaceForWorkerOperation(
operation: string
): XtreamIpcProducerNamespace | null {
const kind = xtreamWorkerRequestIdentityKind(operation);
if (kind === XTREAM_WORKER_REQUEST_IDENTITY_KIND.LEGACY_PRELOAD) {
return XTREAM_IPC_PRODUCER_NAMESPACE.LEGACY_PRELOAD;
}
if (
kind === XTREAM_WORKER_REQUEST_IDENTITY_KIND.PRODUCER_IPC ||
kind === XTREAM_WORKER_REQUEST_IDENTITY_KIND.PRODUCER_OPERATION
) {
return XTREAM_IPC_PRODUCER_NAMESPACE.XTREAM_PRELOAD;
}
return null;
}
export function xtreamIpcProducerIdentityKey(
namespace: XtreamIpcProducerNamespace,
ipcCallId: number
): string {
return `${namespace}\0${ipcCallId}`;
}
export function hasDistinctMonotonicXtreamIpcProducerIdentities(
identities: readonly XtreamIpcProducerIdentity[]
): boolean {
const keys = identities.map(({ ipcCallId, namespace }) =>
xtreamIpcProducerIdentityKey(namespace, ipcCallId)
);
if (new Set(keys).size !== keys.length) return false;
for (const namespace of Object.values(XTREAM_IPC_PRODUCER_NAMESPACE)) {
const ordered = identities
.filter((identity) => identity.namespace === namespace)
.sort((left, right) => left.ipcCallId - right.ipcCallId);
if (
ordered.some(
({ sourceEpochMs }, index) =>
index > 0 &&
sourceEpochMs < Number(ordered[index - 1]?.sourceEpochMs)
)
) {
return false;
}
}
return true;
}
@@ -0,0 +1,78 @@
import type { WorkerRequestPerformanceMetrics } from './m3u-refresh-cancellation-contract';
import type { XtreamIpcAttributionSpan } from './xtream-phase-attribution';
import {
xtreamIpcProducerIdentityKey,
xtreamIpcProducerNamespaceForMethod,
xtreamIpcProducerNamespaceForWorkerOperation,
} from './xtream-ipc-producer-identity';
const DB_METHOD_OPERATION = Object.freeze({
dbDeletePlaylist: 'DB_DELETE_PLAYLIST',
dbDeleteXtreamContent: 'DB_DELETE_XTREAM_CONTENT',
dbGetAppPlaylist: 'DB_GET_APP_PLAYLIST',
dbGetCategories: 'DB_GET_CATEGORIES',
dbGetContent: 'DB_GET_CONTENT',
dbRestoreXtreamUserData: 'DB_RESTORE_XTREAM_USER_DATA',
dbSaveCategories: 'DB_SAVE_CATEGORIES',
dbSaveContent: 'DB_SAVE_CONTENT',
dbUpsertAppPlaylist: 'DB_UPSERT_APP_PLAYLIST',
});
const WORKER_OPERATIONS = new Set<string>(Object.values(DB_METHOD_OPERATION));
export function xtreamWorkerOperationForIpcMethod(
method: string
): string | null {
return (
DB_METHOD_OPERATION[method as keyof typeof DB_METHOD_OPERATION] ?? null
);
}
export function assertXtreamIpcWorkerIdentityBinding(
spans: readonly XtreamIpcAttributionSpan[],
requests: readonly WorkerRequestPerformanceMetrics[]
): void {
const workerByIdentity = new Map<string, WorkerRequestPerformanceMetrics>();
for (const request of requests) {
if (request.ipcCallId === null) continue;
const namespace = xtreamIpcProducerNamespaceForWorkerOperation(
typeof request.operation === 'string' ? request.operation : ''
);
if (namespace === null) invalid();
const key = xtreamIpcProducerIdentityKey(namespace, request.ipcCallId);
if (workerByIdentity.has(key)) invalid();
workerByIdentity.set(key, request);
}
const boundWorkerIdentities = new Set<string>();
for (const span of spans) {
if (span.boundary !== 'request') continue;
const operation = xtreamWorkerOperationForIpcMethod(span.method);
if (operation === null) continue;
const namespace = xtreamIpcProducerNamespaceForMethod(span.method);
if (namespace === null) invalid();
const key = xtreamIpcProducerIdentityKey(namespace, span.ipcCallId);
const worker = workerByIdentity.get(key);
if (
!worker ||
worker.operation !== operation ||
worker.sourceEpochMs !== span.sourceEpochMs
) {
invalid();
}
boundWorkerIdentities.add(key);
}
if (
boundWorkerIdentities.size !== workerByIdentity.size ||
[...workerByIdentity].some(
([key, request]) =>
!boundWorkerIdentities.has(key) ||
typeof request.operation !== 'string' ||
!WORKER_OPERATIONS.has(request.operation)
)
) {
invalid();
}
}
function invalid(): never {
throw new Error('invalid Xtream IPC worker identity binding');
}
@@ -0,0 +1,85 @@
import type { WorkerRequestPerformanceMetrics } from './m3u-refresh-cancellation-contract';
import type {
XtreamIpcAttributionSpan,
XtreamPhaseAttributionInput,
} from './xtream-phase-attribution';
import { xtreamWorkerOperationForIpcMethod } from './xtream-ipc-worker-identity-binding';
interface ProducerIdentity {
readonly ipcCallId: number;
readonly sourceEpochMs: number;
}
export function bindFixtureIpcWorkerIdentities(
input: XtreamPhaseAttributionInput,
requests: readonly WorkerRequestPerformanceMetrics[]
): {
readonly phaseCapture: XtreamPhaseAttributionInput;
readonly requests: readonly WorkerRequestPerformanceMetrics[];
} {
const identities = new Map<
WorkerRequestPerformanceMetrics,
ProducerIdentity
>();
const methods = new Set(
input.ipcSpans
.filter(({ boundary }) => boundary === 'request')
.map(({ method }) => method)
.filter(
(method) => xtreamWorkerOperationForIpcMethod(method) !== null
)
);
for (const method of methods) {
const operation = xtreamWorkerOperationForIpcMethod(method);
if (operation === null) fixtureError();
const calls = requestSpans(input.ipcSpans, method);
const workers = requests
.filter((request) => request.operation === operation)
.sort(
(left, right) =>
Number(left.requestReceivedEpochMs) -
Number(right.requestReceivedEpochMs) ||
String(left.requestId).localeCompare(
String(right.requestId)
)
);
if (calls.length !== workers.length) fixtureError();
calls.forEach((call, index) => {
const worker = workers[index];
if (
!worker ||
call.outcome !== (worker.success ? 'success' : 'error') ||
worker.requestReceivedEpochMs === null ||
call.sourceEpochMs > worker.requestReceivedEpochMs
) {
fixtureError();
}
identities.set(worker, {
ipcCallId: call.ipcCallId,
sourceEpochMs: call.sourceEpochMs,
});
});
}
const bound = requests.map((request) => {
const identity = identities.get(request);
if (identity) return { ...request, ...identity };
if (request.ipcCallId !== null || request.sourceEpochMs !== null) {
fixtureError();
}
return request;
});
return { phaseCapture: input, requests: bound };
}
function requestSpans(
spans: readonly XtreamIpcAttributionSpan[],
method: string
): readonly XtreamIpcAttributionSpan[] {
return spans
.filter((span) => span.boundary === 'request' && span.method === method)
.sort((left, right) => left.ipcCallId - right.ipcCallId);
}
function fixtureError(): never {
throw new Error('invalid Xtream IPC worker identity fixture');
}
@@ -0,0 +1,201 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { XTREAM_SCENARIO_ID } from './xtream-benchmark-contract';
import { createXtreamAssemblerFixture } from './xtream-iteration-assembler.fixture';
import { assembleXtreamRawIteration } from './xtream-iteration-assembler';
import { summarizeXtreamUiActionSamples } from './xtream-ui-action-probe';
describe('Xtream raw iteration assembler background UI evidence', () => {
it('binds samples to the full refresh lifecycle after the delete prelude', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.BACKGROUND_UI
);
const request = input.mainCapture.requests.find(
({ operation }) => operation === 'DB_DELETE_XTREAM_CONTENT'
);
const background = input.terminal.backgroundProbe;
const operation = input.terminal.operation;
const storeTerminalEpochMs =
input.rendererCapture.probe.storeTerminalEpochMs;
assert.ok(request?.workStartedEpochMs);
assert.ok(request.workEndedEpochMs);
assert.ok(background);
assert.ok(operation);
assert.ok(storeTerminalEpochMs);
const step = (storeTerminalEpochMs - request.workEndedEpochMs) / 12;
assert.ok(step > 0);
const samples = background.result.samples.map((sample, index) => {
const startEpochMs =
Number(request.workEndedEpochMs) + step * (index * 2 + 1);
const endEpochMs = startEpochMs + step;
return {
...sample,
endEpochMs,
latencyMs: step,
startEpochMs,
};
});
const summary = summarizeXtreamUiActionSamples(samples);
assert.doesNotThrow(() =>
assembleXtreamRawIteration({
...input,
terminal: {
...input.terminal,
backgroundProbe: {
...background,
completedEpochMs: samples.at(-1)?.endEpochMs ?? 0,
result: {
...summary,
dashboardPaintVisibility: 'visible-without-overlay',
samples,
},
startedEpochMs: request.workStartedEpochMs,
},
operation: {
...operation,
terminalEpochMs: request.workEndedEpochMs,
},
},
})
);
});
it('accepts samples that finish before the delete prelude completes', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.BACKGROUND_UI
);
const request = input.mainCapture.requests.find(
({ operation }) => operation === 'DB_DELETE_XTREAM_CONTENT'
);
const background = input.terminal.backgroundProbe;
const operation = input.terminal.operation;
assert.ok(request?.workStartedEpochMs);
assert.ok(request.workEndedEpochMs);
assert.ok(background);
assert.ok(operation);
const step =
(request.workEndedEpochMs - background.startedEpochMs) / 12;
assert.ok(step > 0);
const samples = background.result.samples.map((sample, index) => {
const startEpochMs =
background.startedEpochMs + step * (index * 2 + 1);
const endEpochMs = startEpochMs + step;
return {
...sample,
endEpochMs,
latencyMs: step,
startEpochMs,
};
});
const summary = summarizeXtreamUiActionSamples(samples);
assert.ok(
Number(samples.at(-1)?.endEpochMs) < request.workEndedEpochMs
);
assert.doesNotThrow(() =>
assembleXtreamRawIteration({
...input,
terminal: {
...input.terminal,
backgroundProbe: {
...background,
completedEpochMs: samples.at(-1)?.endEpochMs ?? 0,
result: {
...summary,
dashboardPaintVisibility: 'visible-without-overlay',
samples,
},
},
operation: {
...operation,
terminalEpochMs: request.workEndedEpochMs,
},
},
})
);
});
it('rejects overlapping samples', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.BACKGROUND_UI
);
const background = input.terminal.backgroundProbe;
assert.ok(background);
const samples = background.result.samples.map((sample, index, all) => {
if (index !== 1) return sample;
const previous = all[0];
assert.ok(previous);
const startEpochMs = previous.endEpochMs - 0.1;
return {
...sample,
latencyMs: sample.endEpochMs - startEpochMs,
startEpochMs,
};
});
const summary = summarizeXtreamUiActionSamples(samples);
assert.throws(
() =>
assembleXtreamRawIteration({
...input,
terminal: {
...input.terminal,
backgroundProbe: {
...background,
result: {
...summary,
dashboardPaintVisibility:
'visible-without-overlay',
samples,
},
},
},
}),
/xtream-iteration-assembly-invalid/
);
});
it('rejects a sample after the final refresh store terminal', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.BACKGROUND_UI
);
const background = input.terminal.backgroundProbe;
const storeTerminalEpochMs =
input.rendererCapture.probe.storeTerminalEpochMs;
assert.ok(background);
assert.ok(storeTerminalEpochMs);
const samples = background.result.samples.map((sample, index, all) => {
if (index !== all.length - 1) return sample;
const endEpochMs = storeTerminalEpochMs + 0.1;
return {
...sample,
endEpochMs,
latencyMs: endEpochMs - sample.startEpochMs,
};
});
const summary = summarizeXtreamUiActionSamples(samples);
assert.throws(
() =>
assembleXtreamRawIteration({
...input,
terminal: {
...input.terminal,
backgroundProbe: {
...background,
completedEpochMs: samples.at(-1)?.endEpochMs ?? 0,
result: {
...summary,
dashboardPaintVisibility:
'visible-without-overlay',
samples,
},
},
},
}),
/xtream-iteration-assembly-invalid/
);
});
});
@@ -0,0 +1,319 @@
import type { RendererPerformancePhaseEvent } from '@iptvnator/shared/logging';
import {
XTREAM_SCENARIO_ID,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import type {
MainTimelineRecord,
WorkerRequestPerformanceMetrics,
} from './m3u-refresh-cancellation-contract';
import {
XTREAM_IPC_PRODUCER_NAMESPACE,
xtreamIpcProducerNamespaceForWorkerOperation,
} from './xtream-ipc-producer-identity';
import type { XtreamRawIterationResult } from './xtream-summary-contract';
import type {
XtreamBackgroundProbeEvidence,
XtreamScenarioTerminalEvidence,
} from './xtream-scenario-driver';
import {
summarizeXtreamUiActionSamples,
type XtreamUiActionProbeResult,
type XtreamUiActionSample,
} from './xtream-ui-action-probe';
const STORE_PREFIX = 'store.';
export function createLegacyTimeline(
requests: readonly WorkerRequestPerformanceMetrics[]
): MainTimelineRecord[] {
const legacy = requests.filter(
(request) =>
xtreamIpcProducerNamespaceForWorkerOperation(
request.operation ?? ''
) === XTREAM_IPC_PRODUCER_NAMESPACE.LEGACY_PRELOAD
);
return legacy.flatMap((request) => {
const source = requireFixtureValue(request.sourceEpochMs);
const received = requireFixtureValue(request.requestReceivedEpochMs);
const response = request.responseEpochMs;
const completion = response + 0.1;
const shared = {
ipcCallId: requireFixtureValue(request.ipcCallId),
operation: requireFixtureValue(request.operation),
playlistId: requireFixtureValue(request.playlistId),
};
return [
{
...shared,
epochMs: (source + received) / 2,
requestId: requireFixtureValue(request.requestId),
sourceEpochMs: source,
type: 'db-request',
},
{
...shared,
epochMs: response,
requestId: requireFixtureValue(request.requestId),
success: true,
type: 'db-response',
},
{
...shared,
epochMs: completion,
sourceEpochMs: completion,
success: true,
type: 'preload-performance-success',
},
];
});
}
export function createRendererCapture(
raw: XtreamRawIterationResult,
background: XtreamUiActionProbeResult | undefined
) {
const storeEvents = raw.phaseCapture.events.filter(({ phase }) =>
phase.startsWith(STORE_PREFIX)
);
const itemsByPhaseId = new Map(
storeEvents
.filter(({ boundary }) => boundary === 'end')
.map(({ correlationId, itemCount }) => [correlationId, itemCount])
);
const performancePhaseEvents = storeEvents.map(
(event): RendererPerformancePhaseEvent => {
const itemCount = itemsByPhaseId.get(event.correlationId) ?? null;
return {
boundary: event.boundary,
epochMs: event.epochMs,
...(itemCount === null
? {}
: { metadata: { items: itemCount } }),
monotonicMs: event.epochMs,
...(event.boundary === 'end' ? { outcome: 'success' } : {}),
phase: event.phase as RendererPerformancePhaseEvent['phase'],
phaseId: event.correlationId,
schemaVersion: 1,
};
}
);
const probe = {
cancelEligibleProgressEpochMs:
raw.cancellation.clickEpochMs === null
? null
: raw.cancellation.clickEpochMs - 0.1,
cancellationClickEpochMs: raw.cancellation.clickEpochMs,
dbCancellationTerminalEpochMs:
raw.cancellation.authoritativeTerminalEpochMs,
dbOperationEvents: [],
domReadyEpochMs: raw.phaseCapture.uiPaintEpochMs - 0.1,
frameGapsMs: [20, 45],
heartbeatDelaysMs: [5, 12],
invalidReason: null,
longTasksMs: [30, 75],
operationStartEpochMs: raw.phaseCapture.operationStartEpochMs,
performancePhaseEvents,
routeReadyEpochMs: raw.phaseCapture.operationStartEpochMs + 0.1,
scenarioId: raw.scenarioId,
storeTerminalEpochMs: Math.max(
...storeEvents
.filter(({ boundary }) => boundary === 'end')
.map(({ epochMs }) => epochMs)
),
terminalEpochMs: raw.phaseCapture.terminalEpochMs,
uiPaintedEpochMs: raw.phaseCapture.uiPaintEpochMs,
};
return {
captureCutoffEpochMs: raw.phaseCapture.terminalEpochMs + 0.5,
consoleErrorBreakdown:
raw.scenarioId === XTREAM_SCENARIO_ID.CANCEL_IMPORT
? {
databaseSaveCancellation: 1,
fetchContentCancellation: 1,
initializationCancellation: 1,
unexpected: 0,
}
: {
databaseSaveCancellation: 0,
fetchContentCancellation: 0,
initializationCancellation: 0,
unexpected: 0,
},
consoleErrorCount:
raw.scenarioId === XTREAM_SCENARIO_ID.CANCEL_IMPORT ? 3 : 0,
cpuProfilePath: null,
frameGap: {
count: 2,
max: 45,
mean: 32.5,
median: 32.5,
min: 20,
p95: 43.75,
p99: 44.75,
},
heapSnapshotPath: null,
heartbeatDelay: {
count: 2,
max: 12,
mean: 8.5,
median: 8.5,
min: 5,
p95: 11.65,
p99: 11.93,
},
longTask: {
count: 2,
max: 75,
mean: 52.5,
median: 52.5,
min: 30,
p95: 72.75,
p99: 74.55,
},
measurementStartEpochMs: raw.phaseCapture.operationStartEpochMs,
pageErrorCount: 0,
peakHeapUsedBytes: raw.renderer.peakHeapUsedBytes,
postGcHeapUsedBytes: raw.renderer.postGcHeapUsedBytes,
probe,
storeToPaintMs:
raw.phaseCapture.uiPaintEpochMs - probe.storeTerminalEpochMs,
targetId: raw.renderer.targetId,
tracePath: null,
...(background ? { background } : {}),
};
}
export function createBackgroundEvidence(
raw: XtreamRawIterationResult,
requests: readonly WorkerRequestPerformanceMetrics[]
): XtreamBackgroundProbeEvidence<XtreamUiActionProbeResult> | null {
if (raw.scenarioId !== XTREAM_SCENARIO_ID.BACKGROUND_UI) return null;
const request = requireFixtureValue(
requests.find(
({ operation }) => operation === 'DB_DELETE_XTREAM_CONTENT'
)
);
const start = requireFixtureValue(request.workStartedEpochMs);
const deleteEnd = requireFixtureValue(request.workEndedEpochMs);
const refreshEnd = Math.max(
...raw.phaseCapture.events
.filter(
({ boundary, phase }) =>
boundary === 'end' &&
phase === 'store.xtream-import-terminal'
)
.map(({ epochMs }) => epochMs)
);
const step = (refreshEnd - deleteEnd) / 12;
const categories = [
'action',
'navigation',
'navigation',
'action',
'search',
] as const;
const kinds = [
'type-filter',
'dashboard',
'sources',
'name-a-z',
'global-search',
] as const;
const samples: XtreamUiActionSample[] = kinds.map((kind, index) => ({
activeAfter: true,
activeBefore: true,
category: requireFixtureValue(categories[index]),
endEpochMs: deleteEnd + step * (index * 2 + 2),
kind,
latencyMs: step,
startEpochMs: deleteEnd + step * (index * 2 + 1),
}));
const summary = summarizeXtreamUiActionSamples(samples);
return {
completedEpochMs: requireFixtureValue(samples.at(-1)).endEpochMs,
operation: 'delete-xtream-content',
operationId: requireFixtureValue(request.operationId),
playlistId: requireFixtureValue(request.playlistId),
result: {
...summary,
dashboardPaintVisibility: 'visible-without-overlay',
samples,
},
startedEpochMs: start,
};
}
export function createTerminal(
raw: XtreamRawIterationResult,
background: XtreamBackgroundProbeEvidence<XtreamUiActionProbeResult> | null
): XtreamScenarioTerminalEvidence {
const cancellation =
raw.cancellation.clickEpochMs === null
? null
: {
armedEpochMs: raw.phaseCapture.operationStartEpochMs - 0.5,
clickEpochMs: raw.cancellation.clickEpochMs,
current: 6_000,
operationId: requireFixtureValue(
raw.cancellation.failedOperationId
),
progressEpochMs: raw.cancellation.clickEpochMs - 0.1,
threshold: 6_000,
total: 60_000,
};
const operation =
background === null
? null
: {
active: false,
operation: 'delete-xtream-content' as const,
operationId: background.operationId,
playlistId: background.playlistId,
startedEpochMs: background.startedEpochMs - 0.1,
terminalEpochMs:
requireFixtureValue(background.result.samples[0])
.startEpochMs -
requireFixtureValue(background.result.samples[0])
.latencyMs,
terminalStatus: 'completed' as const,
};
return {
backgroundProbe: background,
cancellation,
operation,
scenarioId: raw.scenarioId,
terminalEpochMs: raw.phaseCapture.terminalEpochMs - 0.1,
};
}
export function operationOutcomes(
requests: readonly WorkerRequestPerformanceMetrics[]
) {
const counts = new Map<string, number>();
for (const request of requests) {
const outcome = request.success ? 'success' : 'error';
const key = `${request.operation}\0${outcome}`;
counts.set(key, (counts.get(key) ?? 0) + 1);
}
return [...counts].map(([key, count]) => {
const [operation, outcome] = key.split('\0');
return {
count,
operation: requireFixtureValue(operation),
outcome: outcome as 'error' | 'success',
};
});
}
export function scenarioOrdinal(scenarioId: XtreamScenarioId): number {
return Object.values(XTREAM_SCENARIO_ID).indexOf(scenarioId) + 1;
}
function requireFixtureValue<T>(value: T | null | undefined): T {
if (value === null || value === undefined) {
throw new Error('invalid Xtream assembler fixture');
}
return value;
}
@@ -0,0 +1,337 @@
import {
XTREAM_ITERATION_KIND,
type XtreamIterationDefinition,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import { iteration } from './xtream-benchmark-report.fixtures';
import type {
WorkerCaptureMetrics,
WorkerRequestPerformanceMetrics,
} from './m3u-refresh-cancellation-contract';
import type {
XtreamIpcAttributionSpan,
XtreamPhaseAttributionInput,
} from './xtream-phase-attribution';
import { XTREAM_ATTRIBUTION_PHASE as PHASE } from './xtream-phase-inventory';
import {
XTREAM_IPC_PRODUCER_NAMESPACE,
xtreamIpcProducerNamespaceForMethod,
xtreamIpcProducerNamespaceForWorkerOperation,
} from './xtream-ipc-producer-identity';
import type { XtreamIterationAssemblyInput } from './xtream-iteration-assembler';
import {
createBackgroundEvidence,
createLegacyTimeline,
createRendererCapture,
createTerminal,
operationOutcomes,
scenarioOrdinal,
} from './xtream-iteration-assembler-fixture-runtime';
import type { XtreamIpcTimelineRecord } from './xtream-ipc-marker-events.model';
import type { XtreamRawIterationResult } from './xtream-summary-contract';
const MAIN_PHASES = new Set<string>([
PHASE.CANCEL_SESSION,
PHASE.JSON_TRANSFORM,
PHASE.NETWORK_TOTAL,
PHASE.RESPONSE_READY,
]);
export function createXtreamAssemblerFixture(
scenarioId: XtreamScenarioId
): XtreamIterationAssemblyInput {
const definition: XtreamIterationDefinition = {
eligibleForComparison: true,
kind: XTREAM_ITERATION_KIND.MEASURED,
runId: 'run-01',
scenarioId,
};
const raw = iteration(definition, scenarioOrdinal(scenarioId));
const worker = createWorker(raw);
const background = createBackgroundEvidence(raw, worker.requests);
const captureStartedEpochMs = raw.phaseCapture.operationStartEpochMs - 1;
const captureCutoffEpochMs = raw.phaseCapture.terminalEpochMs + 1;
const rendererCapture = createRendererCapture(raw, background?.result);
return {
catalogVerification: {
databaseStateValid: true,
fixtureIdentityValid: true,
providerCategoryCount:
raw.catalogVerification.providerCategoryCount,
providerItemCount: raw.catalogVerification.providerItemCount,
verifiedAfterCapture: true,
},
definition,
diagnosticArtifacts: null,
mainCapture: {
cancelTimeline:
raw.cancellationEvidence?.timeline.map((entry) => ({
...entry,
})) ?? [],
capture: {
cpuProfilePath: null,
cpuSystemMicros: raw.main.cpuSystemMicros,
cpuUserMicros: raw.main.cpuUserMicros,
eventLoopDelay: {
maxMs: raw.main.eventLoopDelayMaxMs,
p95Ms: raw.main.eventLoopDelayP95Ms,
p99Ms: raw.main.eventLoopDelayP99Ms,
},
eventLoopUtilization: null,
eventLoopUtilizationUnavailableReason:
raw.main.eventLoopUtilizationUnavailableReason,
heapSnapshotPath: null,
memory: {
peakHeapUsedBytes: raw.main.peakHeapUsedBytes,
peakRssBytes: raw.main.peakRssBytes,
postGcHeapUsedBytes: raw.main.postGcHeapUsedBytes,
postGcRssBytes: raw.main.peakRssBytes - 1,
},
rendererWindow: {
responsiveEvents: raw.main.responsiveEvents,
rss: {
identity: { creationTime: 1, pid: 42 },
missingSampleCount: 0,
peakRssBytes: raw.renderer.peakRssBytes,
unavailableReason: null,
validSampleCount: 2,
},
unresponsiveEvents: raw.main.unresponsiveEvents,
windowIdentity: {
browserWindowId: raw.main.browserWindowId,
webContentsId: raw.main.webContentsId,
},
},
rssScope:
'electron-main-process-including-worker-threads-and-native-memory',
timeline: createLegacyTimeline(worker.requests),
workers: [worker],
},
captureCutoffEpochMs,
captureGeneration: 1,
captureStartedEpochMs,
captureStoppedEpochMs: captureCutoffEpochMs + 1,
databaseWorkerCount: 1,
invalidReasons: {
capture: [],
databaseWorkerCancel: [],
xtreamIpc: [],
},
ipcTimeline: createXtreamTimeline(raw),
lateDatabaseRequestCount: 0,
lateEventCount: 0,
measurementStartedEpochMs:
raw.phaseCapture.operationStartEpochMs - 0.5,
operationOutcomes: operationOutcomes(worker.requests),
playlistRefreshWorkerCount: 0,
quarantinedIpcMarkerCount: 0,
requests: worker.requests,
rollover: null,
workers: [worker],
},
process: {
electronPid: 20_000 + scenarioOrdinal(scenarioId),
freshProcessVerified: true,
launchId: `launch-${scenarioOrdinal(scenarioId)}`,
profileDirectorySha256: String(scenarioOrdinal(scenarioId)).repeat(
64
),
},
rendererCapture,
terminal: createTerminal(raw, background),
trigger: {
scenarioId,
triggerEpochMs: raw.phaseCapture.operationStartEpochMs + 0.1,
},
};
}
function createWorker(raw: XtreamRawIterationResult): WorkerCaptureMetrics {
const metric = raw.databaseWorker;
return {
cancelPostedEpochMs: raw.cancellation.databaseDispatchEpochMs,
cpuSystemMicros: metric.cpuSystemMicros,
cpuUserMicros: metric.cpuUserMicros,
eventLoopDelay: {
maxMs: metric.eventLoopDelayMaxMs,
p95Ms: metric.eventLoopDelayP95Ms,
p99Ms: metric.eventLoopDelayP99Ms,
},
eventLoopDelayUnavailableReason: null,
eventLoopUtilization: metric.eventLoopUtilization,
externalMemorySampleCount: 2,
heapUsedSampleCount: 2,
kind: 'database.worker',
operationId: null,
ordinal: metric.ordinal,
peakExternalBytes: metric.peakExternalBytes,
peakExternalUnavailableReason: null,
peakHeapUsedBytes: metric.peakHeapUsedBytes,
peakHeapUsedUnavailableReason: null,
playlistId: null,
postGcHeapUnavailableReason: null,
postGcHeapUsedBytes: metric.postGcHeapUsedBytes,
profilePath: null,
requests: metric.requests.evidence.map(cloneRequest),
responseEpochMs: null,
snapshotPath: null,
terminatedEpochMs: null,
};
}
function cloneRequest(
request: WorkerRequestPerformanceMetrics
): WorkerRequestPerformanceMetrics {
return {
...request,
eventLoopDelay:
request.eventLoopDelay === null
? null
: { ...request.eventLoopDelay },
phaseEvents: request.phaseEvents.map((event) => ({
...event,
...(event.metadata ? { metadata: { ...event.metadata } } : {}),
})),
};
}
function createXtreamTimeline(
raw: XtreamRawIterationResult
): XtreamIpcTimelineRecord[] {
const main = raw.phaseCapture.events
.filter(({ phase }) => MAIN_PHASES.has(phase))
.map((event): XtreamIpcTimelineRecord => ({
action: event.providerAction,
boundary: event.boundary,
categoryType: event.categoryType,
contentType: event.contentType,
durationMs: event.durationMs,
epochMs: event.epochMs,
phase: event.phase,
requestId: event.correlationId,
type: 'xtream-main-phase',
}));
const markers = xtreamCalls(raw).flatMap(({ request, response }) => [
marker(raw, request, 'start'),
marker(raw, response, 'end'),
]);
return [...main, ...markers].sort((left, right) => {
return left.epochMs - right.epochMs;
});
}
function marker(
raw: XtreamRawIterationResult,
span: XtreamIpcAttributionSpan,
boundary: 'end' | 'start'
): XtreamIpcTimelineRecord {
const semantic = markerSemantic(raw, span);
return {
action: semantic.providerAction,
boundary,
categoryType: semantic.categoryType,
contentType: semantic.contentType,
epochMs: span.endEpochMs,
ipcCallId: span.ipcCallId,
itemCount: null,
method: span.method,
operationId:
span.method === 'dbCancelOperation'
? raw.cancellation.failedOperationId
: semantic.operationId,
outcome: boundary === 'start' ? null : span.outcome,
playlistId: semantic.playlistId,
sessionId: span.method.startsWith('xtream') ? 'session-1' : null,
sourceEpochMs:
boundary === 'start' ? span.sourceEpochMs : span.startEpochMs,
type: 'xtream-preload-marker',
};
}
function markerSemantic(
raw: XtreamRawIterationResult,
span: XtreamIpcAttributionSpan
) {
if (span.method === 'xtreamRequest') {
const providers = providerGroups(raw.phaseCapture);
const calls = xtreamCalls(raw).filter(
({ request }) => request.method === 'xtreamRequest'
);
const index = calls.findIndex(
({ request }) => request.ipcCallId === span.ipcCallId
);
const provider = providers[index]?.[0];
return {
categoryType: null,
contentType: null,
operationId: null,
playlistId: null,
providerAction: provider?.providerAction ?? null,
};
}
const request = raw.databaseWorker.requests.evidence.find(
(candidate) =>
candidate.ipcCallId === span.ipcCallId &&
xtreamIpcProducerNamespaceForWorkerOperation(
candidate.operation ?? ''
) === XTREAM_IPC_PRODUCER_NAMESPACE.XTREAM_PRELOAD
);
const event = raw.phaseCapture.events.find(
(candidate) =>
candidate.correlationId === request?.requestId &&
candidate.boundary === 'start'
);
return {
categoryType: event?.categoryType ?? null,
contentType: event?.contentType ?? null,
operationId: request?.operationId ?? null,
playlistId: request?.playlistId ?? null,
providerAction: null,
};
}
function xtreamCalls(raw: XtreamRawIterationResult) {
return pairIpc(raw.phaseCapture.ipcSpans).filter(
({ request }) =>
xtreamIpcProducerNamespaceForMethod(request.method) ===
XTREAM_IPC_PRODUCER_NAMESPACE.XTREAM_PRELOAD
);
}
function pairIpc(spans: readonly XtreamIpcAttributionSpan[]) {
const groups = new Map<string, XtreamIpcAttributionSpan[]>();
for (const span of spans) {
groups.set(span.correlationId, [
...(groups.get(span.correlationId) ?? []),
span,
]);
}
return [...groups.values()].map((group) => {
const request = group.find(({ boundary }) => boundary === 'request');
const response = group.find(({ boundary }) => boundary === 'response');
if (!request || !response) {
throw new Error('invalid Xtream assembler IPC fixture');
}
return { request, response };
});
}
function providerGroups(capture: XtreamPhaseAttributionInput) {
const groups = new Map<string, typeof capture.events>();
for (const event of capture.events.filter(
({ phase }) => phase === PHASE.NETWORK_TOTAL
)) {
groups.set(event.correlationId, [
...(groups.get(event.correlationId) ?? []),
event,
]);
}
return [...groups.values()].sort((left, right) => {
const leftStart = left[0];
const rightStart = right[0];
if (!leftStart || !rightStart) {
throw new Error('invalid Xtream assembler provider fixture');
}
return leftStart.epochMs - rightStart.epochMs;
});
}
@@ -0,0 +1,330 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_SCENARIO_ID,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import { createXtreamAssemblerFixture } from './xtream-iteration-assembler.fixture';
import { assembleXtreamRawIteration } from './xtream-iteration-assembler';
import { assertXtreamIterationResult } from './xtream-iteration-validity';
describe('Xtream raw iteration assembler', () => {
for (const scenarioId of Object.values(XTREAM_SCENARIO_ID)) {
it(`assembles measured ${scenarioId} evidence without inventing fields`, () => {
const input = createXtreamAssemblerFixture(
scenarioId as XtreamScenarioId
);
const result = assembleXtreamRawIteration(input);
assert.doesNotThrow(() => assertXtreamIterationResult(result));
assert.equal(
result.processIdentity.captureGeneration,
input.mainCapture.captureGeneration
);
assert.equal(
result.databaseWorker.requests.evidence.length,
input.mainCapture.requests.length
);
assert.equal(result.validity.databaseWorkerCount, 1);
assert.equal(result.validity.playlistWorkerCount, 0);
assert.equal(result.main.cpuMetricScope, 'electron-main-thread');
assert.equal(
result.databaseWorker.cpuMetricScope,
'sum-valid-request-thread-cpu'
);
assert.equal(
result.databaseWorker.cpuUserMicros,
result.databaseWorker.requests.evidence.reduce(
(total, request) =>
total +
(request.invalidReason === null
? Number(request.threadCpuUserMicros)
: 0),
0
)
);
assert.equal(
result.cancellationEvidence === null,
scenarioId !== XTREAM_SCENARIO_ID.CANCEL_IMPORT
);
});
}
it('fails closed on capture invalidation instead of manufacturing a valid result', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE
);
assert.throws(
() =>
assembleXtreamRawIteration({
...input,
mainCapture: {
...input.mainCapture,
invalidReasons: {
...input.mainCapture.invalidReasons,
capture: ['database-worker-activity-after-cutoff'],
},
},
}),
/xtream-iteration-assembly-invalid/
);
});
it('accepts a coarse trigger clock from the same millisecond as renderer start', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE
);
const operationStartEpochMs =
input.rendererCapture.probe.operationStartEpochMs + 0.05;
assert.doesNotThrow(() =>
assembleXtreamRawIteration({
...input,
rendererCapture: {
...input.rendererCapture,
measurementStartEpochMs: operationStartEpochMs,
probe: {
...input.rendererCapture.probe,
operationStartEpochMs,
},
},
trigger: {
...input.trigger,
triggerEpochMs: Math.floor(operationStartEpochMs),
},
})
);
});
it('rejects a coarse trigger clock from the millisecond before renderer start', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE
);
const operationStartEpochMs =
input.rendererCapture.probe.operationStartEpochMs + 0.05;
assert.throws(
() =>
assembleXtreamRawIteration({
...input,
rendererCapture: {
...input.rendererCapture,
probe: {
...input.rendererCapture.probe,
operationStartEpochMs,
},
},
trigger: {
...input.trigger,
triggerEpochMs: Math.floor(operationStartEpochMs) - 1,
},
}),
/xtream-iteration-assembly-invalid/
);
});
it('accepts a late delete driver observation after renderer and main capture cutoffs', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.DELETE_LARGE
);
assert.doesNotThrow(() =>
assembleXtreamRawIteration({
...input,
terminal: {
...input.terminal,
terminalEpochMs:
input.mainCapture.captureCutoffEpochMs + 100,
},
})
);
});
it('accepts renderer cancellation delivery after the authoritative database response', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.CANCEL_IMPORT
);
const authoritativeTerminalEpochMs = input.mainCapture.requests.find(
({ operation, success }) =>
operation === 'DB_SAVE_CONTENT' && !success
)?.responseEpochMs;
assert.equal(typeof authoritativeTerminalEpochMs, 'number');
const dbCancellationTerminalEpochMs =
Number(authoritativeTerminalEpochMs) + 0.25;
assert.ok(
dbCancellationTerminalEpochMs <
Number(input.rendererCapture.probe.uiPaintedEpochMs)
);
assert.doesNotThrow(() =>
assembleXtreamRawIteration({
...input,
rendererCapture: {
...input.rendererCapture,
probe: {
...input.rendererCapture.probe,
dbCancellationTerminalEpochMs,
},
},
})
);
});
it('accepts main observing a network cancel response after the next renderer IPC starts', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.CANCEL_IMPORT
);
const databaseCancelStart = input.mainCapture.ipcTimeline.find(
({ boundary, method }) =>
boundary === 'start' && method === 'dbCancelOperation'
);
assert.ok(databaseCancelStart);
assert.equal(typeof databaseCancelStart.sourceEpochMs, 'number');
const rendererHandoffEpochMs = Number(
databaseCancelStart.sourceEpochMs
);
const delayedMainObservationEpochMs = rendererHandoffEpochMs + 0.1;
assert.ok(delayedMainObservationEpochMs < databaseCancelStart.epochMs);
assert.doesNotThrow(() =>
assembleXtreamRawIteration({
...input,
mainCapture: {
...input.mainCapture,
ipcTimeline: input.mainCapture.ipcTimeline.map((record) =>
record.boundary === 'end' &&
record.method === 'xtreamCancelSession'
? {
...record,
epochMs: delayedMainObservationEpochMs,
sourceEpochMs: rendererHandoffEpochMs,
}
: record
),
},
})
);
});
it('accepts the non-authoritative cancel IPC returning after the database acknowledgement', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.CANCEL_IMPORT
);
const authoritativeTerminalEpochMs = input.mainCapture.requests.find(
({ operation, success }) =>
operation === 'DB_SAVE_CONTENT' && !success
)?.responseEpochMs;
assert.equal(typeof authoritativeTerminalEpochMs, 'number');
const responseSourceEpochMs =
Number(authoritativeTerminalEpochMs) + 0.1;
const responseObservedEpochMs = responseSourceEpochMs + 0.1;
assert.ok(
responseObservedEpochMs <
Number(input.rendererCapture.probe.uiPaintedEpochMs)
);
assert.doesNotThrow(() =>
assembleXtreamRawIteration({
...input,
mainCapture: {
...input.mainCapture,
ipcTimeline: input.mainCapture.ipcTimeline
.map((record) =>
record.boundary === 'end' &&
record.method === 'dbCancelOperation'
? {
...record,
epochMs: responseObservedEpochMs,
sourceEpochMs: responseSourceEpochMs,
}
: record
)
.sort((left, right) => left.epochMs - right.epochMs),
},
})
);
});
it('binds store-to-paint duration to the renderer terminal and paint epochs', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.CANCEL_IMPORT
);
assert.doesNotThrow(() => assembleXtreamRawIteration(input));
assert.throws(
() =>
assembleXtreamRawIteration({
...input,
rendererCapture: {
...input.rendererCapture,
storeToPaintMs:
input.rendererCapture.storeToPaintMs + 0.1,
},
}),
/xtream-iteration-assembly-invalid/
);
});
it('includes trailing delete database and IPC evidence after the visible paint', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.DELETE_LARGE
);
const rendererTerminalEpochMs =
input.rendererCapture.probe.uiPaintedEpochMs;
const result = assembleXtreamRawIteration({
...input,
rendererCapture: {
...input.rendererCapture,
probe: {
...input.rendererCapture.probe,
terminalEpochMs: rendererTerminalEpochMs,
},
},
});
assert.ok(
result.phaseCapture.terminalEpochMs > rendererTerminalEpochMs
);
assert.equal(
result.phases.totalMs,
result.phaseCapture.terminalEpochMs -
result.phaseCapture.operationStartEpochMs
);
});
it('binds diagnostic durations and worker ordinal only from validated artifact evidence', () => {
const input = createXtreamAssemblerFixture(
XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE
);
assert.throws(
() =>
assembleXtreamRawIteration({
...input,
definition: {
...input.definition,
eligibleForComparison: false,
kind: 'diagnostic',
runId: 'diagnostic',
},
diagnosticArtifacts: {
artifacts: [],
directorySha256: '0'.repeat(64),
profiles: {
databaseWorker: {
durationMicros: 1,
ordinal: 1,
},
main: { durationMicros: 1 },
renderer: { durationMicros: 1 },
},
} as never,
}),
/xtream-iteration-assembly-invalid/
);
});
});
@@ -0,0 +1,259 @@
import { createHash } from 'node:crypto';
import type { XtreamIterationDefinition } from './xtream-benchmark-contract';
import {
XTREAM_ITERATION_KIND,
XTREAM_SCENARIO_ID,
} from './xtream-benchmark-contract';
import type { XtreamCatalogVerification } from './xtream-catalog-database-verification';
import {
assertXtreamDiagnosticArtifactEvidence,
type XtreamDiagnosticArtifactEvidence,
} from './xtream-diagnostic-artifacts';
import { freezeDeep } from './xtream-exact-schema';
import {
assertXtreamMainEvidenceGates,
createXtreamDatabaseWorkerMetrics,
createXtreamMainMetrics,
createXtreamRendererMetrics,
} from './xtream-iteration-assembly-metrics';
import { deriveXtreamPhaseCapture } from './xtream-iteration-assembly-phases';
import { assembleXtreamScenarioEvidence } from './xtream-iteration-assembly-scenarios';
import { assertXtreamIterationEvidenceBinding } from './xtream-iteration-evidence-binding';
import { assertXtreamIterationResult } from './xtream-iteration-validity';
import type { XtreamMainCaptureResult } from './m3u-refresh-main-capture';
import { attributeXtreamPhases } from './xtream-phase-attribution';
import type { XtreamRendererCaptureMetrics } from './xtream-renderer-capture';
import { validXtreamRendererConsoleErrorEvidence } from './xtream-renderer-console-errors';
import { assertCompleteXtreamRendererProbe } from './xtream-renderer-probe';
import {
XTREAM_SCENARIO_DATABASE_REQUEST_COUNT,
type XtreamScenarioTerminalEvidence,
type XtreamScenarioTriggerEvidence,
} from './xtream-scenario-driver';
import {
XTREAM_NOT_APPLICABLE,
type XtreamCatalogVerification as XtreamSummaryCatalogVerification,
type XtreamIterationProcessIdentity,
type XtreamRawIterationResult,
} from './xtream-summary-contract';
export interface XtreamIterationProcessEvidence {
readonly electronPid: number;
readonly freshProcessVerified: true;
readonly launchId: string;
readonly profileDirectorySha256: string;
}
export interface XtreamIterationAssemblyInput {
readonly catalogVerification: XtreamCatalogVerification;
readonly definition: XtreamIterationDefinition;
readonly diagnosticArtifacts: XtreamDiagnosticArtifactEvidence | null;
readonly mainCapture: XtreamMainCaptureResult;
readonly process: XtreamIterationProcessEvidence;
readonly rendererCapture: XtreamRendererCaptureMetrics;
readonly terminal: XtreamScenarioTerminalEvidence;
readonly trigger: XtreamScenarioTriggerEvidence;
}
export function assembleXtreamRawIteration(
input: XtreamIterationAssemblyInput
): XtreamRawIterationResult {
try {
return assembleStrict(input);
} catch {
throw new Error('xtream-iteration-assembly-invalid');
}
}
function assembleStrict(
input: XtreamIterationAssemblyInput
): XtreamRawIterationResult {
assertInputBoundary(input);
const diagnostic = validateDiagnosticEvidence(input);
assertXtreamMainEvidenceGates(input.mainCapture);
assertCompleteXtreamRendererProbe(input.rendererCapture.probe);
const phaseCapture = deriveXtreamPhaseCapture(
input.definition.scenarioId,
input.mainCapture,
input.rendererCapture
);
const phases = attributeXtreamPhases(phaseCapture);
const scenario = assembleXtreamScenarioEvidence({
main: input.mainCapture,
phaseCapture,
renderer: input.rendererCapture,
scenarioId: input.definition.scenarioId,
terminal: input.terminal,
trigger: input.trigger,
});
const context = {
diagnostic,
kind: input.definition.kind,
};
const raw: XtreamRawIterationResult = {
...input.definition,
cancellation: scenario.cancellation,
cancellationEvidence: scenario.cancellationEvidence,
catalogVerification: copyCatalogVerification(input.catalogVerification),
databaseWorker: createXtreamDatabaseWorkerMetrics(
input.mainCapture,
context
),
main: createXtreamMainMetrics(input.mainCapture, context),
phaseCapture,
phases,
playlistRefreshWorker: {
instantiated: false,
reason: XTREAM_NOT_APPLICABLE.PLAYLIST_REFRESH_WORKER,
},
processIdentity: createProcessIdentity(input),
renderer: createXtreamRendererMetrics(
input.mainCapture,
input.rendererCapture,
context,
scenario.backgroundMetrics
),
validity: {
actionContractValid: true,
catalogContractValid: true,
databaseWorkerCount: input.mainCapture.databaseWorkerCount,
dbPhaseContractValid: true,
diagnosticArtifactsValid:
input.definition.kind === XTREAM_ITERATION_KIND.DIAGNOSTIC
? true
: null,
lateDatabaseRequestCount:
input.mainCapture.lateDatabaseRequestCount,
playlistWorkerCount: input.mainCapture.playlistRefreshWorkerCount,
rendererTargetCount: 1,
},
};
assertXtreamIterationEvidenceBinding(raw);
assertXtreamIterationResult(raw);
return freezeDeep(raw);
}
function assertInputBoundary(input: XtreamIterationAssemblyInput): void {
const scenarioId = input.definition.scenarioId;
if (
!Object.values(XTREAM_SCENARIO_ID).includes(scenarioId) ||
input.mainCapture.requests.length !==
XTREAM_SCENARIO_DATABASE_REQUEST_COUNT[scenarioId] ||
!validXtreamRendererConsoleErrorEvidence(
input.rendererCapture.consoleErrorCount,
input.rendererCapture.consoleErrorBreakdown,
scenarioId
) ||
input.rendererCapture.pageErrorCount !== 0 ||
input.rendererCapture.storeToPaintMs !==
requireEpoch(input.rendererCapture.probe.uiPaintedEpochMs) -
requireEpoch(input.rendererCapture.probe.storeTerminalEpochMs)
) {
invalid();
}
const catalog = input.catalogVerification;
if (
catalog.databaseStateValid !== true ||
catalog.fixtureIdentityValid !== true ||
catalog.verifiedAfterCapture !== true ||
catalog.providerCategoryCount !== 100 ||
catalog.providerItemCount !== 100_000
) {
invalid();
}
}
function copyCatalogVerification(
catalog: XtreamCatalogVerification
): XtreamSummaryCatalogVerification {
return {
databaseStateValid: catalog.databaseStateValid,
fixtureIdentityValid: catalog.fixtureIdentityValid,
providerCategoryCount: catalog.providerCategoryCount as 100,
providerItemCount: catalog.providerItemCount as 100_000,
verifiedAfterCapture: catalog.verifiedAfterCapture,
};
}
function validateDiagnosticEvidence(
input: XtreamIterationAssemblyInput
): XtreamDiagnosticArtifactEvidence | null {
if (input.definition.kind !== XTREAM_ITERATION_KIND.DIAGNOSTIC) {
if (
input.diagnosticArtifacts !== null ||
input.mainCapture.capture.cpuProfilePath !== null ||
input.mainCapture.capture.heapSnapshotPath !== null ||
input.rendererCapture.cpuProfilePath !== null ||
input.rendererCapture.heapSnapshotPath !== null ||
input.rendererCapture.tracePath !== null ||
input.mainCapture.workers.some(
({ profilePath, snapshotPath }) =>
profilePath !== null || snapshotPath !== null
)
) {
invalid();
}
return null;
}
assertXtreamDiagnosticArtifactEvidence(input.diagnosticArtifacts);
if (
input.process.profileDirectorySha256 !==
input.diagnosticArtifacts.directorySha256
) {
invalid();
}
return input.diagnosticArtifacts;
}
function createProcessIdentity(
input: XtreamIterationAssemblyInput
): XtreamIterationProcessIdentity {
const process = input.process;
if (
process.freshProcessVerified !== true ||
!Number.isSafeInteger(process.electronPid) ||
process.electronPid <= 0 ||
!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(process.launchId) ||
!/^[a-f0-9]{64}$/.test(process.profileDirectorySha256)
) {
invalid();
}
const captureGeneration = input.mainCapture.captureGeneration;
if (!Number.isSafeInteger(captureGeneration) || captureGeneration <= 0) {
invalid();
}
const identity = {
captureGeneration,
electronPid: process.electronPid,
launchId: process.launchId,
profileDirectorySha256: process.profileDirectorySha256,
rendererTargetId: input.rendererCapture.targetId,
browserWindowId:
input.mainCapture.capture.rendererWindow.windowIdentity
.browserWindowId,
webContentsId:
input.mainCapture.capture.rendererWindow.windowIdentity
.webContentsId,
};
return {
captureGeneration,
electronPid: process.electronPid,
freshProcess: true,
generationIdentitySha256: createHash('sha256')
.update(JSON.stringify(identity))
.digest('hex'),
launchId: process.launchId,
profileDirectorySha256: process.profileDirectorySha256,
};
}
function requireEpoch(value: unknown): number {
if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0)
invalid();
return value;
}
function invalid(): never {
throw new Error('invalid Xtream iteration assembly input');
}
@@ -0,0 +1,332 @@
import type { WorkerRequestPerformanceMetrics } from './m3u-refresh-cancellation-contract';
import type {
XtreamMainCaptureResult,
XtreamMainCaptureOperationOutcome,
} from './m3u-refresh-main-capture';
import {
XTREAM_ITERATION_KIND,
type XtreamIterationKind,
} from './xtream-benchmark-contract';
import type { XtreamDiagnosticArtifactEvidence } from './xtream-diagnostic-evidence';
import type { XtreamRendererCaptureMetrics } from './xtream-renderer-capture';
import {
XTREAM_NOT_APPLICABLE,
XTREAM_MAIN_CPU_METRIC_SCOPE,
XTREAM_WORKER_CPU_METRIC_SCOPE,
XTREAM_WORKER_REQUEST_INVALID_REASON,
XTREAM_WORKER_REQUEST_METRIC_SCOPE,
XTREAM_WORKER_WHOLE_METRIC_SCOPE,
type XtreamDatabaseWorkerMetrics,
type XtreamMainMetrics,
type XtreamRendererMetrics,
type XtreamWorkerRequestAccounting,
} from './xtream-summary-contract';
import { deriveXtreamWorkerRequestWindowProxy } from './xtream-worker-request-proxy';
interface MetricContext {
readonly diagnostic: XtreamDiagnosticArtifactEvidence | null;
readonly kind: XtreamIterationKind;
}
export function createXtreamMainMetrics(
main: XtreamMainCaptureResult,
context: MetricContext
): XtreamMainMetrics {
const memory = main.capture.memory;
const window = main.capture.rendererWindow;
return {
...profile(context, 'main'),
browserWindowId: window.windowIdentity.browserWindowId,
cpuMetricScope: XTREAM_MAIN_CPU_METRIC_SCOPE.ELECTRON_MAIN_THREAD,
cpuSystemMicros: main.capture.cpuSystemMicros,
cpuUserMicros: main.capture.cpuUserMicros,
eventLoopDelayMaxMs: main.capture.eventLoopDelay.maxMs,
eventLoopDelayP95Ms: main.capture.eventLoopDelay.p95Ms,
eventLoopDelayP99Ms: main.capture.eventLoopDelay.p99Ms,
eventLoopUtilization: null,
eventLoopUtilizationUnavailableReason:
XTREAM_NOT_APPLICABLE.MAIN_EVENT_LOOP_UTILIZATION,
peakHeapUsedBytes: memory.peakHeapUsedBytes,
peakRssBytes: memory.peakRssBytes,
postGcHeapUsedBytes: requireNumber(memory.postGcHeapUsedBytes),
responsiveEvents: window.responsiveEvents,
unresponsiveEvents: window.unresponsiveEvents,
webContentsId: window.windowIdentity.webContentsId,
};
}
export function createXtreamRendererMetrics(
main: XtreamMainCaptureResult,
renderer: XtreamRendererCaptureMetrics,
context: MetricContext,
background: {
readonly actionLatencyMs: number;
readonly dashboardPaintVisibility: 'visible-without-overlay';
readonly navigationLatencyMs: number;
readonly searchLatencyMs: number;
} | null
): XtreamRendererMetrics {
const rss = main.capture.rendererWindow.rss;
if (
rss.unavailableReason !== null ||
rss.missingSampleCount !== 0 ||
rss.validSampleCount <= 0
) {
invalid();
}
return {
...profile(context, 'renderer'),
actionLatencyMs: background?.actionLatencyMs ?? null,
consoleErrors: [],
dashboardPaintVisibility: background?.dashboardPaintVisibility ?? null,
frameGapMaxMs: requireDistribution(renderer.frameGap, 'max', true),
frameGapP95Ms: requireDistribution(renderer.frameGap, 'p95', true),
heartbeatMaxMs: requireDistribution(
renderer.heartbeatDelay,
'max',
true
),
heartbeatP95Ms: requireDistribution(
renderer.heartbeatDelay,
'p95',
true
),
longTaskCount: renderer.longTask.count,
longTaskMaxMs:
renderer.longTask.count === 0
? 0
: requireDistribution(renderer.longTask, 'max', true),
navigationLatencyMs: background?.navigationLatencyMs ?? null,
peakHeapUsedBytes: renderer.peakHeapUsedBytes,
peakRssBytes: requireNumber(rss.peakRssBytes),
postGcHeapUsedBytes: renderer.postGcHeapUsedBytes,
searchLatencyMs: background?.searchLatencyMs ?? null,
storeToPaintMs: renderer.storeToPaintMs,
targetId: renderer.targetId,
};
}
export function createXtreamDatabaseWorkerMetrics(
main: XtreamMainCaptureResult,
context: MetricContext
): XtreamDatabaseWorkerMetrics {
const worker = main.workers[0];
if (
main.workers.length !== 1 ||
!worker ||
worker.kind !== 'database.worker' ||
worker.heapUsedSampleCount <= 0 ||
worker.externalMemorySampleCount <= 0 ||
worker.peakHeapUsedUnavailableReason !== null ||
worker.peakExternalUnavailableReason !== null ||
worker.postGcHeapUnavailableReason !== null
) {
invalid();
}
const requests = createRequestAccounting(worker.requests);
const threadCpu = sumXtreamRequestThreadCpu(requests.evidence);
if (
context.diagnostic &&
context.diagnostic.profiles.databaseWorker.ordinal !== worker.ordinal
) {
invalid();
}
return {
...profile(context, 'databaseWorker'),
cpuMetricScope: XTREAM_WORKER_CPU_METRIC_SCOPE.SUM_VALID_REQUEST_WORK,
cpuSystemMicros: threadCpu.system,
cpuUserMicros: threadCpu.user,
currentForCapture: true,
eventLoopDelayMaxMs: requests.eventLoopDelayMaxMs,
eventLoopDelayMetricScope:
XTREAM_WORKER_REQUEST_METRIC_SCOPE.VALID_REQUEST_WINDOW_PROXY,
eventLoopDelayP95Ms: requests.eventLoopDelayP95Ms,
eventLoopDelayP99Ms: requests.eventLoopDelayP99Ms,
eventLoopUtilization: requireNumber(worker.eventLoopUtilization),
kind: 'database.worker',
ordinal: worker.ordinal,
peakExternalBytes: requireNumber(worker.peakExternalBytes),
peakHeapUsedBytes: requireNumber(worker.peakHeapUsedBytes),
postGcHeapUsedBytes: requireNumber(worker.postGcHeapUsedBytes),
requests,
rssBytes: null,
rssUnavailableReason: XTREAM_NOT_APPLICABLE.DATABASE_WORKER_RSS,
wholeWorkerMetricScope:
XTREAM_WORKER_WHOLE_METRIC_SCOPE.OPERATION_WINDOW,
};
}
function sumXtreamRequestThreadCpu(
requests: readonly WorkerRequestPerformanceMetrics[]
): { readonly system: number; readonly user: number } {
let system = 0;
let user = 0;
for (const request of requests) {
if (
request.invalidReason ===
XTREAM_WORKER_REQUEST_INVALID_REASON.OVERLAPPING_DATABASE_REQUESTS
) {
continue;
}
if (
request.invalidReason !== null ||
request.threadCpuUnavailableReason !== null ||
request.threadCpuSystemMicros === null ||
request.threadCpuUserMicros === null
) {
invalid();
}
system += request.threadCpuSystemMicros;
user += request.threadCpuUserMicros;
}
if (
!Number.isSafeInteger(system) ||
system < 0 ||
!Number.isSafeInteger(user) ||
user < 0
) {
invalid();
}
return Object.freeze({ system, user });
}
export function assertXtreamMainEvidenceGates(
main: XtreamMainCaptureResult
): void {
if (
main.databaseWorkerCount !== 1 ||
main.playlistRefreshWorkerCount !== 0 ||
main.workers.length !== 1 ||
main.workers[0]?.kind !== 'database.worker' ||
main.lateDatabaseRequestCount !== 0 ||
main.lateEventCount !== 0 ||
main.quarantinedIpcMarkerCount !== 0 ||
main.rollover !== null ||
Object.values(main.invalidReasons).some(
(reasons) => reasons.length !== 0
) ||
main.capture.workers.length !== main.workers.length ||
main.capture.workers[0]?.ordinal !== main.workers[0]?.ordinal ||
main.requests.length !== main.workers[0]?.requests.length ||
!sameOutcomes(main.operationOutcomes, main.requests)
) {
invalid();
}
}
function createRequestAccounting(
evidence: readonly WorkerRequestPerformanceMetrics[]
): XtreamWorkerRequestAccounting {
const snapshot = evidence.map(cloneRequest);
const proxy = deriveXtreamWorkerRequestWindowProxy(snapshot);
if (!proxy) invalid();
const invalidSampleCount = snapshot.filter(
({ invalidReason }) =>
invalidReason ===
XTREAM_WORKER_REQUEST_INVALID_REASON.OVERLAPPING_DATABASE_REQUESTS
).length;
return {
evidence: Object.freeze(snapshot),
...proxy,
invalidReasons:
invalidSampleCount === 0
? []
: [
{
count: invalidSampleCount,
reason: XTREAM_WORKER_REQUEST_INVALID_REASON.OVERLAPPING_DATABASE_REQUESTS,
},
],
invalidSampleCount,
metricScope:
XTREAM_WORKER_REQUEST_METRIC_SCOPE.VALID_REQUEST_WINDOW_PROXY,
totalCount: snapshot.length,
validSampleCount: snapshot.length - invalidSampleCount,
};
}
function cloneRequest(
request: WorkerRequestPerformanceMetrics
): WorkerRequestPerformanceMetrics {
return {
...request,
eventLoopDelay:
request.eventLoopDelay === null
? null
: { ...request.eventLoopDelay },
phaseEvents: request.phaseEvents.map((event) => ({
...event,
...(event.metadata ? { metadata: { ...event.metadata } } : {}),
})),
};
}
function sameOutcomes(
actual: readonly XtreamMainCaptureOperationOutcome[],
requests: readonly WorkerRequestPerformanceMetrics[]
): boolean {
const expected = new Map<string, number>();
for (const request of requests) {
const key = `${request.operation}\0${
request.success ? 'success' : 'error'
}`;
expected.set(key, (expected.get(key) ?? 0) + 1);
}
const observed = new Map(
actual.map(({ count, operation, outcome }) => [
`${operation}\0${outcome}`,
count,
])
);
return (
actual.every(({ outcome }) => outcome !== 'pending') &&
expected.size === observed.size &&
[...expected].every(([key, count]) => observed.get(key) === count)
);
}
function profile(
context: MetricContext,
process: 'databaseWorker' | 'main' | 'renderer'
) {
if (context.kind !== XTREAM_ITERATION_KIND.DIAGNOSTIC) {
if (context.diagnostic !== null) invalid();
return {
cpuProfileDurationMicros: null,
cpuProfileUnavailableReason:
XTREAM_NOT_APPLICABLE.PROFILE_OUTSIDE_DIAGNOSTIC,
} as const;
}
if (!context.diagnostic) invalid();
const duration =
process === 'databaseWorker'
? context.diagnostic.profiles.databaseWorker.durationMicros
: context.diagnostic.profiles[process].durationMicros;
return {
cpuProfileDurationMicros: duration,
cpuProfileUnavailableReason: null,
} as const;
}
function requireDistribution(
value: {
readonly count: number;
readonly max: number | null;
readonly p95: number | null;
},
key: 'max' | 'p95',
requireSamples: boolean
): number {
if (requireSamples && value.count <= 0) invalid();
return requireNumber(value[key]);
}
function requireNumber(value: unknown): number {
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0)
invalid();
return value;
}
function invalid(): never {
throw new Error('invalid Xtream assembly metrics evidence');
}
@@ -0,0 +1,376 @@
import { pairRendererPerformancePhaseEvents } from './renderer-performance-phase-events';
import type { WorkerRequestPerformanceMetrics } from './m3u-refresh-cancellation-contract';
import type { XtreamMainCaptureResult } from './m3u-refresh-main-capture';
import type {
XtreamAttributionPhaseEvent,
XtreamIpcAttributionSpan,
XtreamPhaseAttributionInput,
} from './xtream-phase-attribution';
import {
XTREAM_ATTRIBUTION_PHASE as PHASE,
XTREAM_PHASE_SEMANTIC_TYPE as SEMANTIC,
type XtreamPhaseSemanticType,
} from './xtream-phase-inventory';
import {
semanticTypeFromXtreamPhaseSource,
xtreamDataSemanticSource,
type XtreamPhaseSemanticSource,
} from './xtream-phase-semantic-source';
import {
XTREAM_IPC_PRODUCER_NAMESPACE,
xtreamIpcProducerIdentityKey,
xtreamIpcProducerNamespaceForWorkerOperation,
} from './xtream-ipc-producer-identity';
import { xtreamWorkerOperationForIpcMethod } from './xtream-ipc-worker-identity-binding';
import type { XtreamIpcTimelineRecord } from './xtream-ipc-marker-events.model';
import type { XtreamRendererCaptureMetrics } from './xtream-renderer-capture';
const MAIN_PHASES = new Set<string>([
PHASE.CANCEL_SESSION,
PHASE.JSON_TRANSFORM,
PHASE.NETWORK_TOTAL,
PHASE.RESPONSE_READY,
]);
const LEGACY_METHODS = Object.freeze({
DB_GET_APP_PLAYLIST: 'dbGetAppPlaylist',
DB_UPSERT_APP_PLAYLIST: 'dbUpsertAppPlaylist',
});
export function deriveXtreamPhaseCapture(
scenarioId: XtreamPhaseAttributionInput['scenarioId'],
main: XtreamMainCaptureResult,
renderer: XtreamRendererCaptureMetrics
): XtreamPhaseAttributionInput {
const operationStartEpochMs = renderer.probe.operationStartEpochMs;
const rendererTerminalEpochMs = requireEpoch(
renderer.probe.terminalEpochMs
);
const uiPaintEpochMs = requireEpoch(renderer.probe.uiPaintedEpochMs);
const events = [
...mainPhaseEvents(main),
...workerPhaseEvents(main.requests, main),
...rendererPhaseEvents(renderer),
];
const ipc = ipcSpans(main);
const terminalEpochMs = Math.max(
rendererTerminalEpochMs,
...events.map(({ epochMs }) => epochMs),
...ipc.map(({ endEpochMs }) => endEpochMs)
);
return Object.freeze({
backgroundSearchMarkerObserved: events.some(
({ phase }) => phase === PHASE.STORE_SEARCH_RESULTS
),
events: Object.freeze(events),
ipcSpans: Object.freeze(ipc),
operationStartEpochMs,
scenarioId,
terminalEpochMs,
uiPaintEpochMs,
});
}
function mainPhaseEvents(
main: XtreamMainCaptureResult
): XtreamAttributionPhaseEvent[] {
return main.ipcTimeline
.filter(
({ phase, type }) =>
type === 'xtream-main-phase' &&
typeof phase === 'string' &&
MAIN_PHASES.has(phase)
)
.map((record) => {
const source = {
categoryType: record.categoryType ?? null,
contentType: record.contentType ?? null,
providerAction: record.action ?? null,
} as XtreamPhaseSemanticSource;
return phaseEvent({
boundary: record.boundary,
correlationId: requireText(record.requestId),
durationMs: record.durationMs ?? null,
epochMs: record.epochMs,
itemCount: null,
phase: requireText(record.phase),
source,
});
});
}
function workerPhaseEvents(
requests: readonly WorkerRequestPerformanceMetrics[],
main: XtreamMainCaptureResult
): XtreamAttributionPhaseEvent[] {
return requests.flatMap((request) => {
const correlationId = requireText(request.requestId);
const source = workerSemanticSource(request, main);
return request.phaseEvents.map((event) =>
phaseEvent({
boundary: event.boundary,
correlationId,
durationMs: event.durationMs,
epochMs: event.epochMs,
itemCount:
event.boundary === 'end'
? (event.metadata?.itemCount ?? null)
: null,
phase: event.phase,
source,
})
);
});
}
function workerSemanticSource(
request: WorkerRequestPerformanceMetrics,
main: XtreamMainCaptureResult
): XtreamPhaseSemanticSource {
const operation = requireText(request.operation);
const namespace = xtreamIpcProducerNamespaceForWorkerOperation(operation);
if (namespace !== XTREAM_IPC_PRODUCER_NAMESPACE.XTREAM_PRELOAD) {
return xtreamDataSemanticSource(null);
}
const marker = main.ipcTimeline.filter(
(record) =>
record.type === 'xtream-preload-marker' &&
record.boundary === 'start' &&
record.ipcCallId === request.ipcCallId &&
record.sourceEpochMs === request.sourceEpochMs &&
xtreamWorkerOperationForIpcMethod(record.method ?? '') === operation
);
if (marker.length !== 1 || !marker[0]) invalid();
return {
categoryType: marker[0].categoryType ?? null,
contentType: marker[0].contentType ?? null,
providerAction: null,
} as XtreamPhaseSemanticSource;
}
function rendererPhaseEvents(
renderer: XtreamRendererCaptureMetrics
): XtreamAttributionPhaseEvent[] {
return pairRendererPerformancePhaseEvents(
renderer.probe.performancePhaseEvents
).flatMap((span) => {
const source = rendererSemanticSource(span.phase);
const itemCount = span.metadata?.items ?? null;
return [
phaseEvent({
boundary: 'start',
correlationId: span.phaseId,
durationMs: null,
epochMs: span.startedEpochMs,
itemCount: null,
phase: span.phase,
source,
}),
phaseEvent({
boundary: 'end',
correlationId: span.phaseId,
durationMs: span.durationMs,
epochMs: span.endedEpochMs,
itemCount,
phase: span.phase,
source,
}),
];
});
}
function rendererSemanticSource(phase: string): XtreamPhaseSemanticSource {
const semantic: XtreamPhaseSemanticType | null =
phase === PHASE.STORE_PUBLISH_LIVE
? SEMANTIC.LIVE_CONTENT
: phase === PHASE.STORE_PUBLISH_VOD
? SEMANTIC.VOD_CONTENT
: phase === PHASE.STORE_PUBLISH_SERIES
? SEMANTIC.SERIES_CONTENT
: null;
return xtreamDataSemanticSource(semantic);
}
function ipcSpans(main: XtreamMainCaptureResult): XtreamIpcAttributionSpan[] {
const spans = xtreamIpcSpans(main);
for (const request of main.requests) {
const operation = request.operation ?? '';
const method = LEGACY_METHODS[operation as keyof typeof LEGACY_METHODS];
if (method) spans.push(...legacyIpcPair(main, request, method));
}
return spans;
}
function xtreamIpcSpans(
main: XtreamMainCaptureResult
): XtreamIpcAttributionSpan[] {
const groups = new Map<string, typeof main.ipcTimeline>();
for (const marker of main.ipcTimeline) {
if (
marker.type !== 'xtream-preload-marker' ||
!Number.isSafeInteger(marker.ipcCallId) ||
typeof marker.method !== 'string'
) {
continue;
}
const key = xtreamIpcProducerIdentityKey(
XTREAM_IPC_PRODUCER_NAMESPACE.XTREAM_PRELOAD,
Number(marker.ipcCallId)
);
groups.set(key, [...(groups.get(key) ?? []), marker]);
}
return [...groups.entries()].flatMap(([correlationId, markers]) => {
const start = markers.find(({ boundary }) => boundary === 'start');
const end = markers.find(({ boundary }) => boundary === 'end');
if (
markers.length !== 2 ||
!start ||
!end ||
start.method !== end.method ||
start.outcome !== null ||
!['error', 'success'].includes(String(end.outcome))
) {
invalid();
}
const sourceEpochMs = requireEpoch(start.sourceEpochMs);
return [
ipcSpan(
'request',
correlationId,
start,
sourceEpochMs,
sourceEpochMs,
end.outcome as 'error' | 'success'
),
ipcSpan(
'response',
correlationId,
end,
requireEpoch(end.sourceEpochMs),
sourceEpochMs,
end.outcome as 'error' | 'success'
),
];
});
}
function legacyIpcPair(
main: XtreamMainCaptureResult,
request: WorkerRequestPerformanceMetrics,
method: string
): XtreamIpcAttributionSpan[] {
const ipcCallId = requirePositiveInteger(request.ipcCallId);
const sourceEpochMs = requireEpoch(request.sourceEpochMs);
const requestTimeline = oneTimeline(main, request, 'db-request');
const success = oneTimeline(main, request, 'preload-performance-success');
const responseStartEpochMs = requireEpoch(request.responseEpochMs);
const correlationId = xtreamIpcProducerIdentityKey(
XTREAM_IPC_PRODUCER_NAMESPACE.LEGACY_PRELOAD,
ipcCallId
);
return [
{
boundary: 'request',
correlationId,
endEpochMs: requestTimeline.epochMs,
ipcCallId,
method,
outcome: 'success',
sourceEpochMs,
startEpochMs: sourceEpochMs,
},
{
boundary: 'response',
correlationId,
endEpochMs: requireEpoch(success.sourceEpochMs),
ipcCallId,
method,
outcome: 'success',
sourceEpochMs,
startEpochMs: responseStartEpochMs,
},
];
}
function oneTimeline(
main: XtreamMainCaptureResult,
request: WorkerRequestPerformanceMetrics,
type: 'db-request' | 'preload-performance-success'
) {
const matches = main.capture.timeline.filter(
(record) =>
record.type === type &&
record.ipcCallId === request.ipcCallId &&
record.operation === request.operation &&
record.playlistId === request.playlistId &&
(type !== 'db-request' ||
(record.requestId === request.requestId &&
record.sourceEpochMs === request.sourceEpochMs))
);
if (matches.length !== 1 || !matches[0]) invalid();
return matches[0];
}
function ipcSpan(
boundary: 'request' | 'response',
correlationId: string,
marker: XtreamIpcTimelineRecord,
startEpochMs: number,
sourceEpochMs: number,
outcome: 'error' | 'success'
): XtreamIpcAttributionSpan {
return {
boundary,
correlationId,
endEpochMs: marker.epochMs,
ipcCallId: requirePositiveInteger(marker.ipcCallId),
method: requireText(marker.method),
outcome,
sourceEpochMs,
startEpochMs,
};
}
function phaseEvent(input: {
boundary: 'end' | 'start';
correlationId: string;
durationMs: number | null;
epochMs: number;
itemCount: number | null;
phase: string;
source: XtreamPhaseSemanticSource;
}): XtreamAttributionPhaseEvent {
const semanticType = semanticTypeFromXtreamPhaseSource(input.source);
if (semanticType === undefined) invalid();
return {
boundary: input.boundary,
categoryType: input.source.categoryType,
contentType: input.source.contentType,
correlationId: input.correlationId,
durationMs: input.durationMs,
epochMs: input.epochMs,
itemCount: input.itemCount,
phase: input.phase,
providerAction: input.source.providerAction,
semanticType,
};
}
function requireEpoch(value: unknown): number {
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0)
invalid();
return value;
}
function requirePositiveInteger(value: unknown): number {
if (!Number.isSafeInteger(value) || Number(value) <= 0) invalid();
return Number(value);
}
function requireText(value: unknown): string {
if (typeof value !== 'string' || value.length === 0) invalid();
return value;
}
function invalid(): never {
throw new Error('invalid Xtream assembly phase evidence');
}
@@ -0,0 +1,363 @@
import { isDeepStrictEqual } from 'node:util';
import {
XTREAM_SCENARIO_ID,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import type { XtreamMainCaptureResult } from './m3u-refresh-main-capture';
import type {
XtreamIpcAttributionSpan,
XtreamPhaseAttributionInput,
} from './xtream-phase-attribution';
import type { XtreamRendererCaptureMetrics } from './xtream-renderer-capture';
import type {
XtreamScenarioTerminalEvidence,
XtreamScenarioTriggerEvidence,
} from './xtream-scenario-driver';
import {
XTREAM_CANCEL_NETWORK_ABORT_REASON,
type XtreamCancellationEvidence,
type XtreamCancellationMetrics,
} from './xtream-summary-contract';
import {
summarizeXtreamUiActionSamples,
XTREAM_UI_ACTION_ORDER,
type XtreamUiActionProbeResult,
type XtreamUiActionSample,
} from './xtream-ui-action-probe';
export interface XtreamScenarioAssembly {
readonly backgroundMetrics: {
readonly actionLatencyMs: number;
readonly dashboardPaintVisibility: 'visible-without-overlay';
readonly navigationLatencyMs: number;
readonly searchLatencyMs: number;
} | null;
readonly cancellation: XtreamCancellationMetrics;
readonly cancellationEvidence: XtreamCancellationEvidence | null;
}
export function assembleXtreamScenarioEvidence(input: {
readonly main: XtreamMainCaptureResult;
readonly phaseCapture: XtreamPhaseAttributionInput;
readonly renderer: XtreamRendererCaptureMetrics;
readonly scenarioId: XtreamScenarioId;
readonly terminal: XtreamScenarioTerminalEvidence;
readonly trigger: XtreamScenarioTriggerEvidence;
}): XtreamScenarioAssembly {
assertEnvelope(input);
return {
backgroundMetrics: backgroundMetrics(input),
...cancellationEvidence(input),
};
}
function assertEnvelope(input: {
readonly main: XtreamMainCaptureResult;
readonly phaseCapture: XtreamPhaseAttributionInput;
readonly renderer: XtreamRendererCaptureMetrics;
readonly scenarioId: XtreamScenarioId;
readonly terminal: XtreamScenarioTerminalEvidence;
readonly trigger: XtreamScenarioTriggerEvidence;
}): void {
const start = input.phaseCapture.operationStartEpochMs;
const terminal = input.phaseCapture.terminalEpochMs;
if (
input.trigger.scenarioId !== input.scenarioId ||
input.terminal.scenarioId !== input.scenarioId ||
input.renderer.probe.scenarioId !== input.scenarioId ||
input.trigger.triggerEpochMs < Math.floor(start) ||
input.trigger.triggerEpochMs > input.terminal.terminalEpochMs ||
input.main.captureStartedEpochMs >
input.main.measurementStartedEpochMs ||
input.main.measurementStartedEpochMs > start ||
input.renderer.measurementStartEpochMs < start ||
input.renderer.probe.terminalEpochMs === null ||
input.renderer.probe.terminalEpochMs >
input.renderer.captureCutoffEpochMs ||
input.renderer.captureCutoffEpochMs > input.main.captureCutoffEpochMs ||
terminal > input.main.captureCutoffEpochMs ||
input.main.captureCutoffEpochMs > input.main.captureStoppedEpochMs
) {
invalid();
}
}
function backgroundMetrics(
input: Parameters<typeof assembleXtreamScenarioEvidence>[0]
): XtreamScenarioAssembly['backgroundMetrics'] {
const background = input.terminal.backgroundProbe;
const operation = input.terminal.operation;
if (input.scenarioId !== XTREAM_SCENARIO_ID.BACKGROUND_UI) {
if (background !== null || operation !== null) invalid();
return null;
}
if (
!background ||
!operation ||
operation.active ||
operation.terminalStatus !== 'completed' ||
operation.terminalEpochMs === null ||
background.operation !== 'delete-xtream-content' ||
operation.operation !== background.operation ||
operation.operationId !== background.operationId ||
operation.playlistId !== background.playlistId ||
operation.startedEpochMs > background.startedEpochMs ||
operation.terminalEpochMs > input.terminal.terminalEpochMs ||
background.completedEpochMs > input.terminal.terminalEpochMs ||
background.completedEpochMs >= input.renderer.probe.uiPaintedEpochMs
) {
invalid();
}
const requests = input.main.requests.filter(
({ operation: candidate }) => candidate === 'DB_DELETE_XTREAM_CONTENT'
);
const request = requests[0];
if (
requests.length !== 1 ||
!request ||
request.operationId !== background.operationId ||
request.playlistId !== background.playlistId ||
request.workStartedEpochMs === null ||
request.workEndedEpochMs === null ||
background.startedEpochMs < request.workStartedEpochMs ||
background.startedEpochMs > request.workEndedEpochMs ||
request.workEndedEpochMs > input.terminal.terminalEpochMs
) {
invalid();
}
const result = readUiResult(background.result);
const firstSample = result.samples[0];
const lastSample = result.samples.at(-1);
const dashboardSample = result.samples.find(
({ kind }) => kind === 'dashboard'
);
const storeTerminalEpochMs = input.renderer.probe.storeTerminalEpochMs;
if (
!firstSample ||
!lastSample ||
!dashboardSample ||
storeTerminalEpochMs === null ||
firstSample.startEpochMs < background.startedEpochMs ||
lastSample.endEpochMs > background.completedEpochMs ||
lastSample.endEpochMs > storeTerminalEpochMs ||
operation.terminalEpochMs > storeTerminalEpochMs ||
request.workEndedEpochMs > storeTerminalEpochMs
) {
invalid();
}
return {
actionLatencyMs: requireNumber(result.action.max),
dashboardPaintVisibility: result.dashboardPaintVisibility,
navigationLatencyMs: requireNumber(result.navigation.max),
searchLatencyMs: requireNumber(result.search.max),
};
}
function readUiResult(value: unknown): XtreamUiActionProbeResult {
if (!isRecord(value)) invalid();
const samplesValue = value['samples'];
if (
value['dashboardPaintVisibility'] !== 'visible-without-overlay' ||
!Array.isArray(samplesValue) ||
samplesValue.length !== XTREAM_UI_ACTION_ORDER.length
) {
invalid();
}
const samples = samplesValue.map((entry, index) =>
readSample(entry, index)
);
if (
samples.some((sample, index) => {
const previous = samples[index - 1];
return (
previous !== undefined &&
previous.endEpochMs > sample.startEpochMs
);
})
) {
invalid();
}
const summary = summarizeXtreamUiActionSamples(samples);
if (
!isDeepStrictEqual(summary.action, value['action']) ||
!isDeepStrictEqual(summary.navigation, value['navigation']) ||
!isDeepStrictEqual(summary.search, value['search'])
) {
invalid();
}
return {
...summary,
dashboardPaintVisibility: 'visible-without-overlay',
samples,
};
}
function readSample(value: unknown, index: number): XtreamUiActionSample {
if (
!isRecord(value) ||
value['activeAfter'] !== true ||
value['activeBefore'] !== true ||
value['kind'] !== XTREAM_UI_ACTION_ORDER[index] ||
!['action', 'navigation', 'search'].includes(String(value['category']))
) {
invalid();
}
const startEpochMs = requireNumber(value['startEpochMs']);
const endEpochMs = requireNumber(value['endEpochMs']);
const latencyMs = requireNumber(value['latencyMs']);
if (
endEpochMs < startEpochMs ||
Math.abs(latencyMs - (endEpochMs - startEpochMs)) > 0.001
) {
invalid();
}
return {
activeAfter: true,
activeBefore: true,
category: value['category'] as XtreamUiActionSample['category'],
endEpochMs,
kind: value['kind'] as XtreamUiActionSample['kind'],
latencyMs,
startEpochMs,
};
}
function cancellationEvidence(
input: Parameters<typeof assembleXtreamScenarioEvidence>[0]
): Pick<XtreamScenarioAssembly, 'cancellation' | 'cancellationEvidence'> {
const driver = input.terminal.cancellation;
if (input.scenarioId !== XTREAM_SCENARIO_ID.CANCEL_IMPORT) {
if (driver !== null) invalid();
return {
cancellation: emptyCancellation(),
cancellationEvidence: null,
};
}
const failed = input.main.requests.filter(
({ operation, success }) => operation === 'DB_SAVE_CONTENT' && !success
);
const request = failed[0];
const timeline = input.main.cancelTimeline;
const renderer = input.renderer.probe;
if (
failed.length !== 1 ||
!request ||
!driver ||
typeof request.requestId !== 'string' ||
typeof request.operationId !== 'string' ||
driver.operationId !== request.operationId ||
driver.armedEpochMs > driver.progressEpochMs ||
driver.progressEpochMs > driver.clickEpochMs ||
driver.threshold !== Math.max(100, Math.floor(driver.total * 0.1)) ||
driver.current < driver.threshold ||
renderer.cancellationClickEpochMs === null ||
renderer.cancellationClickEpochMs < driver.clickEpochMs ||
renderer.dbCancellationTerminalEpochMs === null ||
timeline.length !== 3
) {
invalid();
}
const dispatch = timeline[0];
const receipt = timeline[1];
const workerTerminal = timeline[2];
const preload = ipcPair(input.phaseCapture.ipcSpans, 'dbCancelOperation');
const authoritative = request.responseEpochMs;
const painted = requireNumber(renderer.uiPaintedEpochMs);
if (
!dispatch ||
!receipt ||
!workerTerminal ||
dispatch.type !== 'db-cancel-dispatched' ||
receipt.type !== 'db-cancel-received' ||
workerTerminal.type !== 'db-cancel-terminal-received' ||
renderer.dbCancellationTerminalEpochMs < workerTerminal.epochMs ||
renderer.dbCancellationTerminalEpochMs > painted ||
authoritative > painted
) {
invalid();
}
const click = driver.clickEpochMs;
const cancellation: XtreamCancellationMetrics = {
acknowledgementLatencyMs: authoritative - click,
authoritativeDatabaseAcknowledgementObserved: true,
authoritativeTerminalEpochMs: authoritative,
clickEpochMs: click,
clickToDatabaseDispatchMs: dispatch.epochMs - click,
clickToPaintMs: painted - click,
clickToPreloadReturnMs: preload[1].endEpochMs - click,
databaseDispatchEpochMs: dispatch.epochMs,
failedDatabaseRequestId: request.requestId,
failedOperationId: request.operationId,
mainNetworkAbortObserved: false,
mainNetworkAbortReason:
XTREAM_CANCEL_NETWORK_ABORT_REASON.AFTER_NETWORK_COMPLETE,
paintedEpochMs: painted,
preloadReturnEpochMs: preload[1].endEpochMs,
preloadStartEpochMs: preload[0].startEpochMs,
workerReceiptEpochMs: receipt.epochMs,
workerReceiptIsAuthoritative: false,
workerReceiptLatencyMs: receipt.epochMs - click,
};
if (
Object.values(cancellation).some(
(entry) => typeof entry === 'number' && entry < 0
)
) {
invalid();
}
return {
cancellation,
cancellationEvidence: {
timeline: timeline.map((entry) => ({ ...entry })),
},
};
}
function ipcPair(
spans: readonly XtreamIpcAttributionSpan[],
method: string
): readonly [XtreamIpcAttributionSpan, XtreamIpcAttributionSpan] {
const selected = spans.filter((span) => span.method === method);
const request = selected.find(({ boundary }) => boundary === 'request');
const response = selected.find(({ boundary }) => boundary === 'response');
if (selected.length !== 2 || !request || !response) invalid();
return [request, response];
}
function emptyCancellation(): XtreamCancellationMetrics {
return {
acknowledgementLatencyMs: null,
authoritativeDatabaseAcknowledgementObserved: false,
authoritativeTerminalEpochMs: null,
clickEpochMs: null,
clickToDatabaseDispatchMs: null,
clickToPaintMs: null,
clickToPreloadReturnMs: null,
databaseDispatchEpochMs: null,
failedDatabaseRequestId: null,
failedOperationId: null,
mainNetworkAbortObserved: false,
mainNetworkAbortReason: null,
paintedEpochMs: null,
preloadReturnEpochMs: null,
preloadStartEpochMs: null,
workerReceiptEpochMs: null,
workerReceiptIsAuthoritative: false,
workerReceiptLatencyMs: null,
};
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
function requireNumber(value: unknown): number {
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0)
invalid();
return value;
}
function invalid(): never {
throw new Error('invalid Xtream scenario assembly evidence');
}
@@ -0,0 +1,389 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
XTREAM_ITERATION_KIND,
XTREAM_SCENARIO_ID,
type XtreamIterationDefinition,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
import { iteration } from './xtream-benchmark-report.fixtures';
import { assertXtreamIterationResult } from './xtream-iteration-validity';
import type { XtreamRawIterationResult } from './xtream-summary-contract';
describe('Xtream persisted iteration evidence binding', () => {
it('rejects an independently edited phase headline', () => {
const raw = createIteration();
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
phases: {
...raw.phases,
sqliteWriteMs: 99,
},
}),
/invalid Xtream iteration/
);
});
it('rejects worker phase evidence that no longer backs the phase headline', () => {
const raw = createIteration();
const requests = raw.databaseWorker.requests.evidence.map((request) => {
if (request.operation !== 'DB_SAVE_CONTENT') return request;
const phaseEvents = request.phaseEvents.map((event, index) =>
index === 1
? {
...event,
durationMs: 1.5,
epochMs: event.epochMs + 0.5,
}
: event
);
return { ...request, phaseEvents };
});
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
databaseWorker: {
...raw.databaseWorker,
requests: {
...raw.databaseWorker.requests,
evidence: requests,
},
},
}),
/invalid Xtream iteration/
);
});
it('rejects a self-consistent cancel headline outside the failed request', () => {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const cancellation = {
...raw.cancellation,
authoritativeTerminalEpochMs:
Number(raw.cancellation.authoritativeTerminalEpochMs) + 5_000,
clickEpochMs: Number(raw.cancellation.clickEpochMs) + 5_000,
databaseDispatchEpochMs:
Number(raw.cancellation.databaseDispatchEpochMs) + 5_000,
paintedEpochMs: Number(raw.cancellation.paintedEpochMs) + 5_000,
preloadReturnEpochMs:
Number(raw.cancellation.preloadReturnEpochMs) + 5_000,
preloadStartEpochMs:
Number(raw.cancellation.preloadStartEpochMs) + 5_000,
workerReceiptEpochMs:
Number(raw.cancellation.workerReceiptEpochMs) + 5_000,
};
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
cancellation,
}),
/invalid Xtream iteration/
);
});
it('binds the dedicated cancel receipt and failed-request identities exactly', () => {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const receiptDrift = {
...raw.cancellation,
workerReceiptEpochMs:
Number(raw.cancellation.workerReceiptEpochMs) + 0.5,
workerReceiptLatencyMs:
Number(raw.cancellation.workerReceiptLatencyMs) + 0.5,
};
const wrongRequest = {
...raw.cancellation,
failedDatabaseRequestId: 'another-request',
};
const wrongOperation = {
...raw.cancellation,
failedOperationId: 'another-operation',
};
for (const cancellation of [
receiptDrift,
wrongRequest,
wrongOperation,
]) {
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
cancellation,
}),
/invalid Xtream iteration/
);
}
});
it('accepts either ordering of worker receipt and preload return after dispatch', () => {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const dispatch = Number(raw.cancellation.databaseDispatchEpochMs);
const preloadReturn = Number(raw.cancellation.preloadReturnEpochMs);
const workerTerminal = Number(
raw.cancellationEvidence?.timeline.find(
({ type }) => type === 'db-cancel-terminal-received'
)?.epochMs
);
const beforeReturn = dispatch + (preloadReturn - dispatch) / 2;
const afterReturn =
preloadReturn + (workerTerminal - preloadReturn) / 2;
assert.notEqual(
raw.cancellation.workerReceiptEpochMs,
preloadReturn,
'fixture receipt must be independent from the preload response'
);
for (const receiptEpochMs of [beforeReturn, afterReturn]) {
assert.doesNotThrow(() =>
assertXtreamIterationResult(withReceipt(raw, receiptEpochMs))
);
}
});
it('rejects cancel-receipt identity drift and receipt after the authoritative terminal', () => {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const evidence = cancellationEvidence(raw);
const receiptIndex = evidence.timeline.findIndex(
({ type }) => type === 'db-cancel-received'
);
assert.notEqual(receiptIndex, -1);
for (const receipt of [
{ requestId: 'another-request' },
{ operationId: 'another-operation' },
{ ipcCallId: 999 },
{ sourceEpochMs: 999 },
{
epochMs:
Number(raw.cancellation.authoritativeTerminalEpochMs) + 1,
},
]) {
const timeline = evidence.timeline.map((record, index) =>
index === receiptIndex ? { ...record, ...receipt } : record
);
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
cancellationEvidence: { timeline },
}),
/invalid Xtream iteration/
);
}
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
cancellationEvidence: {
timeline: evidence.timeline.map((record) => ({
...record,
sourceEpochMs: record.sourceEpochMs + 1,
})),
},
}),
/invalid Xtream iteration/
);
});
it('rejects reuse of a worker request IPC identity for cancellation', () => {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const evidence = cancellationEvidence(raw);
const failedRequest = raw.databaseWorker.requests.evidence.find(
({ operation, success }) =>
operation === 'DB_SAVE_CONTENT' && !success
);
assert.ok(failedRequest?.ipcCallId);
for (const ipcCallId of [failedRequest.ipcCallId, 999]) {
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
cancellationEvidence: {
timeline: evidence.timeline.map((record) => ({
...record,
ipcCallId: ipcCallId as number,
})),
},
}),
/invalid Xtream iteration/
);
}
});
it('persists producer identity on the database cancel IPC pair', () => {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const databaseCancel = raw.phaseCapture.ipcSpans.filter(
({ method }) => method === 'dbCancelOperation'
) as readonly ((typeof raw.phaseCapture.ipcSpans)[number] & {
readonly ipcCallId?: number;
readonly sourceEpochMs?: number;
})[];
assert.equal(databaseCancel.length, 2);
assert.equal(typeof databaseCancel[0]?.ipcCallId, 'number');
assert.equal(
databaseCancel[0]?.ipcCallId,
databaseCancel[1]?.ipcCallId
);
assert.equal(typeof databaseCancel[0]?.sourceEpochMs, 'number');
assert.equal(
databaseCancel[0]?.sourceEpochMs,
databaseCancel[1]?.sourceEpochMs
);
});
it('rejects database preload identities swapped across worker operations', () => {
const raw = createIteration();
const contentRead = raw.phaseCapture.ipcSpans.find(
({ boundary, method }) =>
boundary === 'request' && method === 'dbGetContent'
);
const contentWrite = raw.phaseCapture.ipcSpans.find(
({ boundary, method }) =>
boundary === 'request' && method === 'dbSaveContent'
);
assert.ok(contentRead);
assert.ok(contentWrite);
const ipcSpans = raw.phaseCapture.ipcSpans.map((span) => {
if (span.correlationId === contentRead.correlationId) {
return {
...span,
ipcCallId: contentWrite.ipcCallId,
sourceEpochMs: contentWrite.sourceEpochMs,
};
}
return span.correlationId === contentWrite.correlationId
? {
...span,
ipcCallId: contentRead.ipcCallId,
sourceEpochMs: contentRead.sourceEpochMs,
}
: span;
});
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
phaseCapture: { ...raw.phaseCapture, ipcSpans },
}),
/invalid Xtream iteration/
);
});
it('rejects cancellation source chronology before an earlier worker call', () => {
const raw = createIteration(XTREAM_SCENARIO_ID.CANCEL_IMPORT);
const evidence = cancellationEvidence(raw);
const lastWorkerCall = raw.databaseWorker.requests.evidence
.filter(
(request) =>
request.ipcCallId !== null && request.sourceEpochMs !== null
)
.sort(
(left, right) =>
Number(right.ipcCallId) - Number(left.ipcCallId)
)[0];
assert.ok(lastWorkerCall?.sourceEpochMs);
const databaseSourceEpochMs =
Number(lastWorkerCall.sourceEpochMs) - 0.25;
const networkSourceEpochMs = databaseSourceEpochMs - 0.25;
const ipcSpans = raw.phaseCapture.ipcSpans.map((span) => {
if (span.method === 'xtreamCancelSession') {
return { ...span, sourceEpochMs: networkSourceEpochMs };
}
return span.method === 'dbCancelOperation'
? { ...span, sourceEpochMs: databaseSourceEpochMs }
: span;
});
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
cancellationEvidence: {
timeline: evidence.timeline.map((record) => ({
...record,
sourceEpochMs: databaseSourceEpochMs,
})),
},
phaseCapture: { ...raw.phaseCapture, ipcSpans },
}),
/invalid Xtream iteration/
);
});
it('ignores caller-owned phase array methods when checking evidence', () => {
const raw = createIteration();
const events = [
...raw.phaseCapture.events,
] as unknown as typeof raw.phaseCapture.events & {
filter: () => readonly never[];
map: () => readonly never[];
};
Object.defineProperties(events, {
filter: { value: () => [] },
map: { value: () => [] },
});
assert.throws(
() =>
assertXtreamIterationResult({
...raw,
phaseCapture: { ...raw.phaseCapture, events },
phases: { ...raw.phases, sqliteWriteMs: 99 },
}),
/invalid Xtream iteration/
);
});
});
function withReceipt(
raw: XtreamRawIterationResult,
receiptEpochMs: number
): XtreamRawIterationResult {
const click = Number(raw.cancellation.clickEpochMs);
const evidence = cancellationEvidence(raw);
return {
...raw,
cancellation: {
...raw.cancellation,
workerReceiptEpochMs: receiptEpochMs,
workerReceiptLatencyMs: receiptEpochMs - click,
},
cancellationEvidence: {
timeline: evidence.timeline.map((record) =>
record.type === 'db-cancel-received'
? { ...record, epochMs: receiptEpochMs }
: record
),
},
};
}
function cancellationEvidence(
raw: XtreamRawIterationResult
): NonNullable<XtreamRawIterationResult['cancellationEvidence']> {
const evidence = raw.cancellationEvidence;
assert.ok(evidence);
return evidence;
}
function createIteration(
scenarioId: XtreamScenarioId = XTREAM_SCENARIO_ID.INITIAL_IMPORT_LARGE
): XtreamRawIterationResult {
const definition: XtreamIterationDefinition = {
eligibleForComparison: true,
kind: XTREAM_ITERATION_KIND.MEASURED,
runId: 'run-01',
scenarioId,
};
return iteration(definition, 1);
}
Loaded 100 of 256 files, more files were not shown because too many files have changed in this diff. Show more