Files
iptvnator/apps/electron-backend-e2e/src/performance/xtream-renderer-console-errors.ts
T
4gray a2fafcfc08 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
2026-07-28 08:08:07 +02:00

99 lines
2.8 KiB
TypeScript

import {
XTREAM_SCENARIO_ID,
type XtreamScenarioId,
} from './xtream-benchmark-contract';
export interface XtreamRendererConsoleErrorBreakdown {
databaseSaveCancellation: number;
fetchContentCancellation: number;
initializationCancellation: number;
unexpected: number;
}
type XtreamRendererConsoleErrorKind = keyof XtreamRendererConsoleErrorBreakdown;
const CANCELLATION_SIGNATURE = 'Operation "save-content" was cancelled';
export function createXtreamRendererConsoleErrorBreakdown(): XtreamRendererConsoleErrorBreakdown {
return {
databaseSaveCancellation: 0,
fetchContentCancellation: 0,
initializationCancellation: 0,
unexpected: 0,
};
}
export function recordXtreamRendererConsoleError(
breakdown: XtreamRendererConsoleErrorBreakdown,
scenarioId: XtreamScenarioId,
message: string
): void {
const kind = classifyXtreamRendererConsoleError(scenarioId, message);
breakdown[kind] += 1;
}
export function validXtreamRendererConsoleErrorEvidence(
total: number,
breakdown: XtreamRendererConsoleErrorBreakdown,
scenarioId: XtreamScenarioId
): boolean {
if (
!Number.isSafeInteger(total) ||
total < 0 ||
!validBreakdownCounts(breakdown) ||
total !== totalBreakdownCount(breakdown)
) {
return false;
}
if (scenarioId === XTREAM_SCENARIO_ID.CANCEL_IMPORT) {
return (
breakdown.databaseSaveCancellation === 1 &&
breakdown.fetchContentCancellation === 1 &&
breakdown.initializationCancellation === 1 &&
breakdown.unexpected === 0
);
}
return total === 0;
}
function classifyXtreamRendererConsoleError(
scenarioId: XtreamScenarioId,
message: string
): XtreamRendererConsoleErrorKind {
if (
scenarioId !== XTREAM_SCENARIO_ID.CANCEL_IMPORT ||
!message.includes(CANCELLATION_SIGNATURE)
) {
return 'unexpected';
}
if (message.startsWith('Error saving Xtream content:')) {
return 'databaseSaveCancellation';
}
if (message.startsWith('[withContent] Error fetching content')) {
return 'fetchContentCancellation';
}
if (message.startsWith('[withContent] Error initializing content')) {
return 'initializationCancellation';
}
return 'unexpected';
}
function totalBreakdownCount(
breakdown: XtreamRendererConsoleErrorBreakdown
): number {
return (
breakdown.databaseSaveCancellation +
breakdown.fetchContentCancellation +
breakdown.initializationCancellation +
breakdown.unexpected
);
}
function validBreakdownCounts(
breakdown: XtreamRendererConsoleErrorBreakdown
): boolean {
return Object.values(breakdown).every(
(value) => Number.isSafeInteger(value) && value >= 0
);
}