wiki: ingest 2 concepts — sched-fnf-r8-verification-stand + windows-docker-test-harness-gotchas
This commit is contained in:
75
.wiki/concepts/windows-docker-test-harness-gotchas.md
Normal file
75
.wiki/concepts/windows-docker-test-harness-gotchas.md
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
title: "Windows docker-тест-харнесс: грабли верификационных скриптов"
|
||||
type: concept
|
||||
tags: [windows, testing, node, docker, vitest, sqlite, gotchas]
|
||||
sources: []
|
||||
related: [concepts/sched-fnf-r8-verification-stand.md]
|
||||
updated: 2026-08-18
|
||||
---
|
||||
|
||||
# Windows docker-тест-харнесс: грабли
|
||||
|
||||
Собрано из верификационных прогонов против docker-контейнеров на Windows-хосте
|
||||
(стенд sched F&F r8, 2026-08-18). Переиспользуемо для любой проверки
|
||||
«локальные репро-скрипты против живых docker-БД».
|
||||
|
||||
## 1. `rmSync` удаляемого sqlite-файла — EBUSY на Windows
|
||||
|
||||
`new DatabaseSync('x.db')` создаёт файл, и `rmSync('x.db')` ПОСЛЕ открытия падает
|
||||
`EBUSY` (errno -4082): Windows не удаляет открытый файл (на POSIX unlink
|
||||
открытого — ок, на Windows — нет).
|
||||
|
||||
**Правило: `rmSync` ДО `DatabaseSync`.** Порядок в тесте:
|
||||
```js
|
||||
rmSync('x.db', { force: true });
|
||||
const db = new DatabaseSync('x.db');
|
||||
```
|
||||
Симптом-ловушка: тот же EBUSY бывает, если файл держит ВИСЯЩИЙ node-процесс
|
||||
прошлого прогона (см. п.4) — сначала убить процессы, потом чинить порядок.
|
||||
|
||||
## 2. vitest 10s-таймаут vs медленный docker-DDL
|
||||
|
||||
На этом хосте DDL в docker-mysql8 стоит ~200–1500ms на запрос (CREATE TABLE,
|
||||
ALTER), а `createMysqlStorage` (миграции v1→v5 на свежей БД) — ~11s. vitest-дефолт
|
||||
10s на тест → каждый mysql-тест падает в `beforeEach` по таймауту, БЕЗ
|
||||
assertion-ошибок. Выглядит как регрессия, а это окружение.
|
||||
|
||||
Варианты: `--testTimeout=60000`, либо (лучше для стенда) не гонять тяжёлый
|
||||
contract-сьют на mysql/pg/mariadb через vitest — покрывать те же пути
|
||||
отдельными node-скриптами (`adapters-spotcheck`, `adapter-migration-test`).
|
||||
|
||||
## 3. Фейк-часы в тестах движка — монотонность и изоляция
|
||||
|
||||
Инжектируемый `now()` даёт детерминизм, но:
|
||||
- **Часы должны идти МОНОТОННО.** Прыжок назад (например, после тика 10:03 гнать
|
||||
once-расписание на 10:01) ломает: расписание «уже» выстрелило catch-up'ом на
|
||||
более позднем тике, nextRunAt=null. Планируй все времена по возрастанию.
|
||||
- **Отдельный DB на сценарий.** Общий DB + прыгающие часы → соседняя задача
|
||||
становится due на «чужом» тике и стреляет (мешает счётчикам/онRunFinal).
|
||||
- **`rmSync` в начале каждого прогона** — иначе повторный запуск видит старые
|
||||
раны (флак «запусти ещё раз — упало»).
|
||||
- **Блокирующий раннер + `runOnce`** = дедлок, если release после `await`.
|
||||
Тик не await'ить, дать микро-паузу на claim, release, потом `await`.
|
||||
|
||||
## 4. Висельники node-процессов держат файлы/порты
|
||||
|
||||
После таймаутов и убитых прогонов node-процессы живут и держат sqlite-файлы
|
||||
(→ EBUSY) и соединения. `tasklist | grep node` врёт (UTF-16 binary); правильно:
|
||||
```powershell
|
||||
Get-CimInstance Win32_Process -Filter "Name='node.exe'" | Select ProcessId,CommandLine
|
||||
```
|
||||
Убивать точечно по CommandLine (репо-путь), НЕ всех — рядом крутятся dev-серверы
|
||||
юзера (nuxt, pi-агенты, wiki-graph). Таймаут bash убивает шелл, но не дерево
|
||||
node-детей — чистить руками.
|
||||
|
||||
## 5. Секвенции assert'ов: «ожидание» vs «поведение»
|
||||
|
||||
Половина «багов» в репро-скриптах — неверные ожидания в тесте, а не движок:
|
||||
- кумулятивные счётчики (retryCount = consumed-попытки, не «текущая»);
|
||||
- тай-брейки сортировок (priority-равные → id ASC);
|
||||
- событийные хуки на терминальных ранах (success тоже);
|
||||
- легаси-форматы данных (mongo: `config.data` не `data`, `paused`/`disabled`
|
||||
обязательны — иначе синтез даёт null и строка не в due).
|
||||
|
||||
Перед репортом о «находке» — перепроверить, что ожидание соответствует доке
|
||||
(это часто и есть ответ: поведение документировано, тест был неверен).
|
||||
Reference in New Issue
Block a user