From 77836f7adaf417417baf297a3e33994a60287656 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 20 Sep 2026 20:07:37 +0300 Subject: [PATCH] =?UTF-8?q?perf(tests):=20verify-snapshots=20=D0=BE=D1=82?= =?UTF-8?q?=D1=81=D0=B5=D0=B8=D0=B2=D0=B0=D0=B5=D1=82=20external-=D0=BA?= =?UTF-8?q?=D0=B5=D0=B9=D1=81=D1=8B=20=D0=B4=D0=BE=20=D0=BA=D0=BE=D0=BF?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B2=D1=8B?= =?UTF-8?q?=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Кейс на `setup: external:` платформой не проверяется никогда — решение об этом стояло в Step 7, а Step 0 до него успевал скопировать всю выгрузку типовой конфигурации в рабочий каталог. Результат копирования тут же выбрасывался: ни один шаг между Step 0 и Step 7 на вердикт для таких кейсов не влияет. Цена была видна на глаз: 10 кейсов real-* у meta-info занимали 166-235 секунд каждый, то есть около 32 минут чистого копирования ERP и БП. Прогон по навыку стал 2 мин 53 с против ~35 минут при том же результате: 36 прошли, 0 упало, те же 10 external пропущены с той же причиной. В репозитории таких кейсов 38. Решение перенесено к остальным ранним пропускам, до Step 0. Обе ветки сохранены: недоступная выгрузка (её нет на маке) по-прежнему даёт СКИП, а не падение, доступная — passed с noPlatformReason. Ставшие недостижимыми блоки в Step 0 и Step 7 удалены, caseProvidedConfig сузился до fixture:. Фикстурные кейсы не затронуты — прогон meta-validate до и после совпадает (17 прошли, 0 упало, 13 пропущено). Co-Authored-By: Claude Opus 5 (1M context) --- tests/skills/verify-snapshots.mjs | 55 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/tests/skills/verify-snapshots.mjs b/tests/skills/verify-snapshots.mjs index aae483bfb..768e0ad6e 100644 --- a/tests/skills/verify-snapshots.mjs +++ b/tests/skills/verify-snapshots.mjs @@ -8,8 +8,9 @@ // cfe-init, cfe-borrow, cfe-patch-method // Работает и с кейсами навыков, которые сами ничего не пишут (info/validate), если у кейса // есть preRun: проверяется, что платформа принимает собранную им фикстуру. -// Для кейсов на `setup: external:` проверка вырождается — 1С грузит собственную выгрузку -// типовой конфигурации (~3 мин на кейс, ноль информации). Такие гонять через --case. +// Кейсы на `setup: external:` платформой не проверяются: 1С грузила бы собственную выгрузку +// типовой конфигурации — минуты на кейс и ноль информации о навыке. Отсеиваются сразу, ДО +// копирования выгрузки, поэтому стоят доли секунды и полный прогон по навыку не тормозят. import { execFileSync } from 'child_process'; import { existsSync, mkdirSync, mkdtempSync, unlinkSync, readFileSync, writeFileSync, @@ -868,6 +869,27 @@ async function verifyCase(skillName, caseName, skillConfig, caseData, opts) { } } + // Кейс на `setup: external:` платформой не проверяется НИКОГДА: грузилась бы собственная + // выгрузка типовой — минуты на кейс и ноль информации о навыке. Решение принимаем ЗДЕСЬ, до + // Step 0. Раньше оно стояло в Step 7, а Step 0 успевал скопировать выгрузку целиком: 10 кейсов + // meta-info на real-* стоили ~32 минуты копирования ради результата, который тут же + // выбрасывался. Ни один шаг между Step 0 и Step 7 на вердикт для таких кейсов не влияет. + if (typeof caseData.setup === 'string' && caseData.setup.startsWith('external:')) { + const extPath = resolve(REPO_ROOT, caseData.setup.slice('external:'.length)); + // Недоступная выгрузка — СКИП, как в runner.mjs (`ensureSetup`, ветка external): путь к + // дампу ERP/БП машинозависим, на маке его нет, и падение здесь красило бы исправный навык. + if (!existsSync(extPath)) { + result.skipped = true; + result.skipReason = `внешняя выгрузка недоступна на этой машине: ${extPath}`; + return result; + } + result.noPlatformReason = 'external: грузилась бы собственная выгрузка типовой (~3 мин, ноль информации о навыке)'; + result.passed = true; + result.steps.push({ step: 'platform-load', ok: true, detail: 'skipped (external setup)' }); + if (opts.verbose) console.log(' ✓ platform-load: skipped (external setup)'); + return result; + } + // caseFiles — файловый вход кейса (напр. XSD для xdto-compile), как в runner.mjs for (const rel of caseData.caseFiles || []) { const src = join(CASES, skillName, rel); @@ -918,26 +940,12 @@ async function verifyCase(skillName, caseName, skillConfig, caseData, opts) { // configDir приходил только из скилл-уровневого setup (empty-config), поэтому у навыков // с setup: none фикстура до платформы не доезжала, а кейс всё равно получал PASS. if (existsSync(join(workDir, 'Configuration.xml'))) configDir = workDir; - } else if (typeof caseData.setup === 'string' && caseData.setup.startsWith('external:')) { - const extPath = resolve(REPO_ROOT, caseData.setup.slice('external:'.length)); - // Недоступная внешняя выгрузка — СКИП, как в runner.mjs (`ensureSetup`, ветка - // external). Путь к дампу ERP/БП машинозависим: на маке его нет, и падение - // здесь красило набор при полностью исправном навыке — расхождение двух - // раннеров по одному и тому же ключу DSL. - if (!existsSync(extPath)) { - result.skipped = true; - result.skipReason = `внешняя выгрузка недоступна на этой машине: ${extPath}`; - return result; - } - copyTreeSync(extPath, workDir); - log(`external: ${extPath}`, true); - configDir = workDir; } // ── Step 1: Setup (cf-init for empty-config, nothing for 'none') ── // Skip cf-init if external/fixture setup already provided a complete config - const caseProvidedConfig = typeof caseData.setup === 'string' && - (caseData.setup.startsWith('external:') || caseData.setup.startsWith('fixture:')); + // Только fixture: external сюда не доходит (отсеян до Step 0). + const caseProvidedConfig = typeof caseData.setup === 'string' && caseData.setup.startsWith('fixture:'); // Skip setup for cf-init skill — the test itself creates the config if (configDir && setupType.startsWith('empty-config') && !CONFIG_INIT_SKILLS.has(skillName) && !caseProvidedConfig) { try { @@ -1484,16 +1492,7 @@ async function verifyCase(skillName, caseName, skillConfig, caseData, opts) { } // ── Step 7: Platform load ── - // Skip platform load for external dumps (e.g. real ERP/БП configs): - // they're huge, version-sensitive, and the point of these test cases is - // to exercise the skill script against real-world XML, not to validate - // that an entire vendor config loads into a fresh DB. - if (caseProvidedConfig && caseData.setup.startsWith('external:')) { - result.noPlatformReason = 'external: грузилась бы собственная выгрузка типовой (~3 мин, ноль информации о навыке)'; - result.passed = true; - log('platform-load', true, 'skipped (external setup)'); - return result; - } + // Кейсы на external: сюда не доходят — они отсеяны до Step 0. const dbDir = join(workDir, 'testdb');