perf: сценарий памяти свода 2 (GO «все» → RF «все» → GO)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5dc6662767
commit
3363291801
@ -74,3 +74,8 @@ export class ByteCounter {
|
||||
export function filterResultMs(startAt: number, stableAt: number, respAt: number | null): number {
|
||||
return Math.max(stableAt, respAt ?? 0) - startAt;
|
||||
}
|
||||
|
||||
/** Точки замера памяти свода 2: GO «все» -> RF «все» -> (опц. прокрутка RF) -> снова GO. */
|
||||
export function memoryPoints(env: Record<string, string | undefined>): string[] {
|
||||
return env.PERF_SVOD2_MEM_SCROLL === '1' ? ['go', 'rf', 'rf_scrolled', 'final'] : ['go', 'rf', 'final'];
|
||||
}
|
||||
|
||||
92
perf/e2e/scenarios/svod2-memory.spec.ts
Normal file
92
perf/e2e/scenarios/svod2-memory.spec.ts
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Сценарий памяти свода 2 (Task 16): роль dfip, свежий контекст на каждый повтор, одна SPA-сессия внутри повтора.
|
||||
* Точки (lib/svod2.ts memoryPoints): go (вкладка GO, «Все ССП/РФ», «Загрузить») -> rf (вкладка RF, то же)
|
||||
* [-> rf_scrolled при PERF_SVOD2_MEM_SCROLL=1] -> final (возврат на GO, «Загрузить»).
|
||||
* В каждой точке gc -> heapUsed, domCounters. Запись: scenario "svod2-memory", target "svod2/<point>".
|
||||
* Env: PERF_SCALE, PERF_RUN_ID, PERF_REPEATS (3), PERF_SVOD2_MEM_SCROLL, PERF_LOAD_TIMEOUT_MS, PERF_MAX_STEPS,
|
||||
* PERF_TEST_TIMEOUT_MS.
|
||||
*/
|
||||
import { test, type Page } from '@playwright/test';
|
||||
import { loadManifest, scale } from '../lib/manifest';
|
||||
import { loginAs, WEB } from '../lib/auth';
|
||||
import { throttle, heapUsed, domCounters } from '../lib/cdp';
|
||||
import { append } from '../lib/results';
|
||||
import { scrollThrough } from '../lib/scroll';
|
||||
import { SVOD2_DATA_ROW_SELECTOR, memoryPoints } from '../lib/svod2';
|
||||
|
||||
const CONTAINER = '.MuiTableContainer-root';
|
||||
const MIN_ROWS = 20;
|
||||
const REPEATS = Number(process.env.PERF_REPEATS ?? 3);
|
||||
const LOAD_TIMEOUT = Number(process.env.PERF_LOAD_TIMEOUT_MS ?? 900_000);
|
||||
const MAX_STEPS = Number(process.env.PERF_MAX_STEPS ?? 5000);
|
||||
|
||||
async function waitRows(page: Page, what: string): Promise<number> {
|
||||
const t0 = Date.now();
|
||||
for (;;) {
|
||||
const n = await page.evaluate(([sel, rs]) => document.querySelectorAll(`${sel} ${rs}`).length, [CONTAINER, SVOD2_DATA_ROW_SELECTOR]);
|
||||
if (n >= MIN_ROWS) return n;
|
||||
if (Date.now() - t0 > LOAD_TIMEOUT) throw new Error(`${what}: rows<${MIN_ROWS} за ${LOAD_TIMEOUT} мс (rows=${n})`);
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
}
|
||||
|
||||
/** «Все ССП/РФ» + «Загрузить» (Svod2Page.jsx), как в scroll.spec.ts. */
|
||||
async function loadAll(page: Page): Promise<void> {
|
||||
await page.getByLabel('ССП/РФ').click();
|
||||
await page.getByRole('option', { name: 'Все ССП/РФ' }).click();
|
||||
await page.keyboard.press('Escape');
|
||||
await page.getByRole('button', { name: 'Загрузить' }).click();
|
||||
}
|
||||
|
||||
for (let repeat = 0; repeat < REPEATS; repeat++) {
|
||||
test(`svod2-memory: dfip #${repeat}`, async ({ browser }) => {
|
||||
test.setTimeout(Number(process.env.PERF_TEST_TIMEOUT_MS ?? 3600_000));
|
||||
const user = loadManifest().users['dfip'];
|
||||
if (!user) throw new Error('в манифесте нет пользователя dfip');
|
||||
const points = memoryPoints(process.env);
|
||||
const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 } });
|
||||
try {
|
||||
await loginAs(ctx, user);
|
||||
const page = await ctx.newPage();
|
||||
page.on('pageerror', (e) => console.log('pageerror:', e.message));
|
||||
await page.goto(WEB + '/svod/2');
|
||||
await throttle(page, 1);
|
||||
|
||||
const sample = async (point: string, rows: number) => {
|
||||
const heap = await heapUsed(page); // gc внутри
|
||||
const dom = await domCounters(page);
|
||||
append({
|
||||
scenario: 'svod2-memory', target: `svod2/${point}`, role: 'dfip', scale: scale(), cpu_rate: 1, repeat,
|
||||
metrics: { heap_used_mb: heap / 1048576, nodes: dom.nodes, documents: dom.documents, js_event_listeners: dom.jsEventListeners, rows_visible: rows },
|
||||
artifacts: [],
|
||||
});
|
||||
console.log(`${point} #${repeat}: heap ${(heap / 1048576).toFixed(1)} MB, nodes ${dom.nodes}, listeners ${dom.jsEventListeners}`);
|
||||
};
|
||||
|
||||
for (const point of points) {
|
||||
let rows: number;
|
||||
if (point === 'go') {
|
||||
await page.getByRole('tab').nth(0).click();
|
||||
await loadAll(page);
|
||||
rows = await waitRows(page, point);
|
||||
} else if (point === 'rf') {
|
||||
await page.getByRole('tab').nth(1).click();
|
||||
await loadAll(page);
|
||||
rows = await waitRows(page, point);
|
||||
} else if (point === 'rf_scrolled') {
|
||||
const r = await scrollThrough(page, CONTAINER, 'y', 200, MAX_STEPS);
|
||||
if (!r.complete) throw new Error(`rf_scrolled: скролл не дошёл до конца (${r.reason ?? 'incomplete'})`);
|
||||
rows = await waitRows(page, point);
|
||||
} else {
|
||||
await page.getByRole('tab').nth(0).click();
|
||||
await loadAll(page);
|
||||
rows = await waitRows(page, point);
|
||||
}
|
||||
await page.waitForTimeout(500);
|
||||
await sample(point, rows);
|
||||
}
|
||||
} finally {
|
||||
await ctx.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -7,6 +7,7 @@ import {
|
||||
svod2RespRe,
|
||||
countPagesRequested,
|
||||
filterResultMs,
|
||||
memoryPoints,
|
||||
SVOD2_DATA_ROW_SELECTOR,
|
||||
SVOD2_PLACEHOLDER_SELECTOR,
|
||||
} from '../lib/svod2.ts';
|
||||
@ -69,3 +70,12 @@ test('filterResultMs: нет запроса поиска - только стаб
|
||||
assert.equal(filterResultMs(1000, 1700, 1200), 700);
|
||||
assert.equal(filterResultMs(1000, 1700, 1900), 900);
|
||||
});
|
||||
|
||||
test('memoryPoints: по умолчанию go, rf, final', () => {
|
||||
assert.deepEqual(memoryPoints({}), ['go', 'rf', 'final']);
|
||||
assert.deepEqual(memoryPoints({ PERF_SVOD2_MEM_SCROLL: '0' }), ['go', 'rf', 'final']);
|
||||
});
|
||||
|
||||
test('memoryPoints: PERF_SVOD2_MEM_SCROLL=1 добавляет rf_scrolled', () => {
|
||||
assert.deepEqual(memoryPoints({ PERF_SVOD2_MEM_SCROLL: '1' }), ['go', 'rf', 'rf_scrolled', 'final']);
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user