diff --git a/docs/uk/ci.md b/docs/uk/ci.md index de0189f08..943bee04d 100644 --- a/docs/uk/ci.md +++ b/docs/uk/ci.md @@ -1,34 +1,60 @@ --- read_when: - - Вам потрібно зрозуміти, чому завдання CI запустилося або не запустилося. - - Ви налагоджуєте збої перевірок GitHub Actions. -summary: Граф завдань CI, ворота охоплення та локальні еквіваленти команд + - Вам потрібно зрозуміти, чому завдання CI запустилося або не запустилося + - Ви налагоджуєте збої перевірок GitHub Actions +summary: Граф завдань CI, пороги охоплення та локальні еквіваленти команд title: Конвеєр CI x-i18n: - generated_at: "2026-04-26T22:14:39Z" + generated_at: "2026-04-26T22:39:59Z" model: gpt-5.4 provider: openai - source_hash: bad9dde51020fc3833d3848955a01af36e38e281a4c9de128b36b9553f66665e + source_hash: da03ca18ec9d3cc7057ce33d22fc692a2e0735e5bc88fedec7cfc1e144d49cd6 source_path: ci.md workflow: 15 --- -CI запускається після кожного пушу в `main` і для кожного pull request. Він використовує розумне визначення охоплення, щоб пропускати дорогі завдання, коли змінено лише не пов’язані області. +CI запускається для кожного push до `main` і для кожного pull request. Він використовує розумне визначення охоплення, щоб пропускати дорогі завдання, коли змінено лише не пов’язані ділянки. -QA Lab має окремі лінії CI поза основним робочим процесом із розумним визначенням охоплення. Робочий процес -`Parity gate` запускається для PR зі змінами, що відповідають умовам, і через ручний запуск; він -збирає приватне середовище виконання QA та порівнює агентні набори mock GPT-5.5 і Opus 4.6. -Робочий процес `QA-Lab - All Lanes` запускається щонічно в `main` і через -ручний запуск; він розгалужує mock parity gate, live-лінію Matrix і live-лінію -Telegram як паралельні завдання. Live-завдання використовують середовище -`qa-live-shared`, а лінія Telegram використовує оренди Convex. `OpenClaw Release -Checks` також запускає ті самі лінії QA Lab перед затвердженням релізу. +QA Lab має окремі доріжки CI поза основним робочим процесом із розумним визначенням охоплення. Робочий процес +`Parity gate` запускається для PR зі відповідними змінами та через ручний запуск; він +збирає приватне середовище виконання QA і порівнює агентні набори mock GPT-5.5 і Opus 4.6. +Робочий процес `QA-Lab - All Lanes` запускається щоночі на `main` і через +ручний запуск; він розгалужує mock parity gate, live-доріжку Matrix і live-доріжку +Telegram як паралельні завдання. Live-завдання використовують середовище `qa-live-shared`, +а доріжка Telegram використовує оренди Convex. `OpenClaw Release +Checks` також запускає ті самі доріжки QA Lab перед погодженням релізу. -Робочий процес `Duplicate PRs After Merge` — це ручний робочий процес для супровідників для очищення дублікатів після злиття. За замовчуванням він працює в режимі dry-run і закриває лише явно перелічені PR, коли `apply=true`. Перш ніж вносити зміни в GitHub, він перевіряє, що злитий PR справді об’єднано, і що кожен дублікат має або спільну згадану issue, або перекривні змінені фрагменти. +Робочий процес `Duplicate PRs After Merge` — це ручний робочий процес для мейнтейнерів для +очищення дублікатів після злиття. За замовчуванням він працює в режимі dry-run і закриває лише явно +вказані PR, коли `apply=true`. Перш ніж змінювати стан у GitHub, він перевіряє, +що злитий PR справді змерджено і що кожен дублікат має або спільну згадану issue, +або перетин змінених фрагментів. -Робочий процес `Docs Agent` — це подієва лінія обслуговування Codex для підтримки наявної документації у відповідності до нещодавно злитих змін. Він не має окремого запуску за розкладом: його може запустити успішний неботовий CI-прохід після пушу в `main`, а також його можна запустити вручну напряму. Виклики через workflow-run пропускаються, якщо `main` уже пішла вперед або якщо за останню годину вже було створено інший непропущений запуск Docs Agent. Коли він запускається, він переглядає діапазон комітів від вихідного SHA попереднього непропущеного Docs Agent до поточної `main`, тож один щогодинний запуск може охопити всі зміни в `main`, накопичені з часу останнього проходу документації. +Робочий процес `Docs Agent` — це керована подіями доріжка обслуговування Codex для підтримання +наявної документації у відповідності до нещодавно злитих змін. Він не має суто планового запуску: +його може запустити успішний неботовий запуск CI після push у `main`, а +ручний запуск може виконати його безпосередньо. Запуски через workflow-run пропускаються, +коли `main` уже просунувся вперед або коли за останню годину вже було створено +інший непропущений запуск Docs Agent. Коли він виконується, він +переглядає діапазон комітів від SHA джерела попереднього непропущеного Docs Agent до +поточного `main`, тож один щогодинний запуск може охопити всі зміни в main, накопичені +з моменту останнього проходу документації. -Робочий процес `Test Performance Agent` — це подієва лінія обслуговування Codex для повільних тестів. Він не має окремого запуску за розкладом: його може запустити успішний неботовий CI-прохід після пушу в `main`, але він пропускається, якщо того UTC-дня інший виклик через workflow-run уже відпрацював або ще виконується. Ручний запуск обходить цю денну перевірку активності. Лінія збирає згрупований звіт про продуктивність Vitest для повного набору, дозволяє Codex вносити лише невеликі виправлення продуктивності тестів без зниження покриття замість широких рефакторингів, потім повторно запускає звіт для повного набору й відхиляє зміни, які зменшують базову кількість тестів, що проходять. Якщо в базовому стані є тести, що не проходять, Codex може виправляти лише очевидні збої, а звіт повного набору після роботи агента має проходити повністю, перш ніж щось буде закомічено. Коли `main` просувається вперед до того, як бот встигає запушити результат, лінія перебазовує перевірений патч, повторно запускає `pnpm check:changed` і повторює пуш; конфліктні застарілі патчі пропускаються. Вона використовує GitHub-hosted Ubuntu, щоб дія Codex могла зберігати ту саму безпекову модель drop-sudo, що й агент документації. +Робочий процес `Test Performance Agent` — це керована подіями доріжка обслуговування Codex +для повільних тестів. Він не має суто планового запуску: його може запустити +успішний неботовий запуск CI після push у `main`, але він пропускається, якщо +інший запуск через workflow-run уже виконався або виконується в той UTC-день. +Ручний запуск обходить це денне обмеження активності. Доріжка збирає звіт про продуктивність +Vitest для повного набору тестів із групуванням, дозволяє Codex вносити лише невеликі +виправлення продуктивності тестів без зменшення покриття замість широких рефакторингів, потім +повторно запускає звіт для повного набору і відхиляє зміни, які зменшують +кількість тестів базової лінії, що проходять. Якщо в базовій лінії є тести, що падають, +Codex може виправляти лише очевидні збої, а звіт для повного набору після роботи агента +має пройти, перш ніж щось буде закомічено. Коли `main` просувається вперед до того, +як push бота буде злитий, доріжка перебазовує перевірений патч, повторно запускає +`pnpm check:changed` і повторює спробу push; застарілі конфліктні патчі пропускаються. +Вона використовує GitHub-hosted Ubuntu, щоб дія Codex могла +зберігати ту саму безпечну політику без `sudo`, що й docs agent. ```bash gh workflow run duplicate-after-merge.yml \ @@ -39,87 +65,87 @@ gh workflow run duplicate-after-merge.yml \ ## Огляд завдань -| Завдання | Призначення | Коли запускається | -| -------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------ | -| `preflight` | Виявлення змін лише в документації, змінених областей охоплення, змінених розширень і побудова маніфесту CI | Завжди для нечернеткових пушів і PR | -| `security-scm-fast` | Виявлення приватних ключів і аудит робочих процесів через `zizmor` | Завжди для нечернеткових пушів і PR | -| `security-dependency-audit` | Аудит production lockfile без залежностей щодо попереджень npm | Завжди для нечернеткових пушів і PR | -| `security-fast` | Обов’язковий агрегат для швидких завдань безпеки | Завжди для нечернеткових пушів і PR | -| `build-artifacts` | Збирання `dist/`, Control UI, перевірки зібраних артефактів і повторно використовувані артефакти для нижчих етапів | Зміни, релевантні для Node | -| `checks-fast-core` | Швидкі Linux-лінії коректності, як-от перевірки bundled/plugin-contract/protocol | Зміни, релевантні для Node | -| `checks-fast-contracts-channels` | Шардовані перевірки контрактів каналів зі стабільним агрегованим результатом перевірки | Зміни, релевантні для Node | -| `checks-node-extensions` | Повні шарди тестів bundled-плагінів для всього набору розширень | Зміни, релевантні для Node | -| `checks-node-core-test` | Шарди основних Node-тестів, без ліній каналів, bundled, контрактів і розширень | Зміни, релевантні для Node | -| `extension-fast` | Точкові тести лише для змінених bundled-плагінів | Pull request із змінами в розширеннях | -| `check` | Еквівалент основного локального gate, розбитий на шарди: production-типи, lint, guard, типи тестів і строгий smoke | Зміни, релевантні для Node | -| `check-additional` | Перевірки архітектури, меж, guard поверхні розширень, меж пакетів і шарди gateway-watch | Зміни, релевантні для Node | -| `build-smoke` | Smoke-тести зібраного CLI та smoke-тест пам’яті під час запуску | Зміни, релевантні для Node | -| `checks` | Верифікатор для тестів каналів зі зібраними артефактами плюс сумісність Node 22 лише для push | Зміни, релевантні для Node | -| `check-docs` | Форматування документації, lint і перевірки на зламані посилання | Документацію змінено | -| `skills-python` | Ruff + pytest для Skills на базі Python | Зміни, релевантні для Python Skills | -| `checks-windows` | Специфічні для Windows тестові лінії | Зміни, релевантні для Windows | -| `macos-node` | Лінія тестів TypeScript на macOS з використанням спільних зібраних артефактів | Зміни, релевантні для macOS | -| `macos-swift` | Swift lint, збирання та тести для застосунку macOS | Зміни, релевантні для macOS | -| `android` | Модульні тести Android для обох flavor плюс одне збирання debug APK | Зміни, релевантні для Android | -| `test-performance-agent` | Щоденна оптимізація повільних тестів Codex після довіреної активності | Успіх main CI або ручний запуск | +| Завдання | Призначення | Коли запускається | +| --------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------ | +| `preflight` | Визначає зміни лише в документації, змінені області охоплення, змінені extensions і формує маніфест CI | Завжди для недрафтових push і PR | +| `security-scm-fast` | Виявлення приватних ключів і аудит робочих процесів через `zizmor` | Завжди для недрафтових push і PR | +| `security-dependency-audit` | Аудит production lockfile без залежностей щодо advisory npm | Завжди для недрафтових push і PR | +| `security-fast` | Обов’язковий агрегат для швидких завдань безпеки | Завжди для недрафтових push і PR | +| `build-artifacts` | Збирає `dist/`, Control UI, перевірки зібраних артефактів і повторно використовувані downstream-артефакти | Зміни, релевантні для Node | +| `checks-fast-core` | Швидкі доріжки перевірки коректності на Linux, як-от bundled/plugin-contract/protocol checks | Зміни, релевантні для Node | +| `checks-fast-contracts-channels` | Шардовані перевірки контрактів каналів зі стабільним агрегованим результатом | Зміни, релевантні для Node | +| `checks-node-extensions` | Повні шарди тестів bundled plugins для всього набору extensions | Зміни, релевантні для Node | +| `checks-node-core-test` | Шарди core Node тестів, окрім доріжок channel, bundled, contract і extension | Зміни, релевантні для Node | +| `extension-fast` | Цільові тести лише для змінених bundled plugins | Pull request зі змінами в extension | +| `check` | Шардований еквівалент основного локального порогу: prod types, lint, guards, test types і strict smoke | Зміни, релевантні для Node | +| `check-additional` | Шарди для архітектури, меж, захисту поверхні extension, меж пакетів і gateway-watch | Зміни, релевантні для Node | +| `build-smoke` | Smoke-тести зібраного CLI і smoke-тест пам’яті під час запуску | Зміни, релевантні для Node | +| `checks` | Верифікатор для тестів каналів на зібраних артефактах плюс сумісність Node 22 лише для push | Зміни, релевантні для Node | +| `check-docs` | Форматування документації, lint і перевірки битих посилань | Документацію змінено | +| `skills-python` | Ruff + pytest для Skills на Python | Зміни, релевантні для Python Skills | +| `checks-windows` | Специфічні для Windows доріжки тестів | Зміни, релевантні для Windows | +| `macos-node` | Доріжка тестів TypeScript на macOS із використанням спільних зібраних артефактів | Зміни, релевантні для macOS | +| `macos-swift` | Swift lint, збірка і тести для застосунку macOS | Зміни, релевантні для macOS | +| `android` | Android unit-тести для обох flavor плюс одна debug APK-збірка | Зміни, релевантні для Android | +| `test-performance-agent` | Щоденна оптимізація повільних тестів Codex після довіреної активності | Успіх main CI або ручний запуск | ## Порядок fail-fast -Завдання впорядковано так, щоб дешеві перевірки падали раніше, ніж запускаються дорогі: +Завдання впорядковані так, щоб дешеві перевірки завершувалися з помилкою раніше, ніж запускатимуться дорогі: -1. `preflight` вирішує, які лінії взагалі існують. Логіка `docs-scope` і `changed-scope` — це кроки всередині цього завдання, а не окремі завдання. -2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs` і `skills-python` швидко падають, не чекаючи важчих матричних завдань для артефактів і платформ. -3. `build-artifacts` виконується паралельно зі швидкими Linux-лініями, щоб нижчі етапи могли початися, щойно буде готове спільне збирання. -4. Після цього розгалужуються важчі платформні та runtime-лінії: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `checks-node-core-test`, лише для PR `extension-fast`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`. +1. `preflight` вирішує, які доріжки взагалі існують. Логіка `docs-scope` і `changed-scope` — це кроки всередині цього завдання, а не окремі завдання. +2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs` і `skills-python` завершуються швидко з помилкою, не чекаючи важчих завдань для артефактів і платформних матриць. +3. `build-artifacts` виконується паралельно зі швидкими Linux-доріжками, щоб downstream-споживачі могли почати роботу, щойно спільна збірка буде готова. +4. Після цього розгалужуються важчі платформні та runtime-доріжки: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `checks-node-core-test`, PR-only `extension-fast`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`. -Логіка визначення охоплення міститься в `scripts/ci-changed-scope.mjs` і покривається модульними тестами в `src/scripts/ci-changed-scope.test.ts`. -Зміни робочих процесів CI перевіряють граф Node CI та lint робочих процесів, але самі по собі не примушують запускати нативні збирання Windows, Android або macOS; ці платформні лінії й далі обмежуються змінами у вихідному коді відповідних платформ. -Зміни лише в маршрутизації CI, окремі вибрані дешеві зміни у фікстурах core-тестів і вузькі зміни в допоміжниках/маршрутизації тестів контрактів плагінів використовують швидкий шлях маніфесту лише для Node: preflight, security і одну задачу `checks-fast-core`. Цей шлях уникає збирання артефактів, сумісності з Node 22, контрактів каналів, повних шардів core, шардів bundled-плагінів і додаткових матриць guard, коли змінені файли обмежені поверхнями маршрутизації або допоміжників, які швидка задача перевіряє безпосередньо. -Перевірки Windows Node обмежуються Windows-специфічними обгортками для процесів/шляхів, допоміжниками запуску npm/pnpm/UI, конфігурацією менеджера пакетів і поверхнями робочих процесів CI, які запускають цю лінію; не пов’язані зміни у вихідному коді, плагінах, install-smoke і зміни лише в тестах залишаються на Linux Node-лініях, щоб не резервувати Windows worker із 16 vCPU для покриття, яке вже перевіряється звичайними тестовими шардами. -Окремий робочий процес `install-smoke` повторно використовує той самий скрипт визначення охоплення через власне завдання `preflight`. Він ділить smoke-покриття на `run_fast_install_smoke` і `run_full_install_smoke`. Pull request запускають швидкий шлях для поверхонь Docker/package, змін пакетів/маніфестів bundled-плагінів і поверхонь core plugin/channel/gateway/Plugin SDK, які перевіряють Docker smoke-завдання. Зміни лише у вихідному коді bundled-плагінів, зміни лише в тестах і лише в документації не резервують Docker workers. Швидкий шлях один раз збирає образ root Dockerfile, перевіряє CLI, запускає smoke CLI `agents delete` зі спільним робочим простором, запускає container gateway-network e2e, перевіряє build arg для bundled extension і запускає обмежений Docker-профіль bundled-плагіна з сукупним таймаутом команди 240 секунд, при цьому для кожного сценарію `docker run` окремо також обмежується. Повний шлях зберігає покриття встановлення QR package і installer Docker/update для нічних запусків за розкладом, ручних запусків, workflow-call перевірок релізу та pull request, які справді зачіпають поверхні installer/package/Docker. Пуші в `main`, включно з merge-комітами, не примушують повний шлях; коли логіка changed-scope запитує повне покриття для пушу, робочий процес лишає швидкий Docker smoke, а повний install smoke відкладає до нічної або релізної валідації. Повільний smoke для image-provider із глобальним встановленням Bun керується окремо через `run_bun_global_install_smoke`; він запускається за нічним розкладом і з робочого процесу перевірок релізу, а ручні запуски `install-smoke` можуть явно його ввімкнути, але pull request і пуші в `main` його не запускають. Тести QR та installer Docker зберігають власні Dockerfile, орієнтовані на встановлення. Локальний `test:docker:all` попередньо збирає один спільний live-test образ, один раз пакує OpenClaw як npm tarball і збирає два спільні образи `scripts/e2e/Dockerfile`: базовий runner Node/Git для ліній installer/update/plugin-dependency і функціональний образ, який встановлює той самий tarball у `/app` для звичайних функціональних ліній. Планувальник вибирає образ для кожної лінії через `OPENCLAW_DOCKER_E2E_BARE_IMAGE` і `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`, а потім запускає лінії з `OPENCLAW_SKIP_DOCKER_BUILD=1`; кількість слотів основного пулу за замовчуванням 10 можна налаштувати через `OPENCLAW_DOCKER_ALL_PARALLELISM`, а кількість слотів хвостового пулу, чутливого до provider, також 10 — через `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM`. Обмеження для важких ліній за замовчуванням дорівнюють `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=6`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=8` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`, щоб лінії з npm install і кількома сервісами не перевантажували Docker, поки легші лінії все ще займають доступні слоти. Запуск ліній за замовчуванням зсувається на 2 секунди, щоб уникнути локальних сплесків створення контейнерів у Docker daemon; це можна змінити через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` або інше значення в мілісекундах. Локальний агрегований запуск попередньо перевіряє Docker, видаляє застарілі контейнери OpenClaw E2E, виводить статус активних ліній, зберігає таймінги ліній для впорядкування від найдовших до найкоротших і підтримує `OPENCLAW_DOCKER_ALL_DRY_RUN=1` для аналізу роботи планувальника. За замовчуванням він припиняє планувати нові лінії пулу після першої помилки, а кожна лінія має резервний таймаут 120 хвилин, який можна змінити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; окремі live/tail-лінії мають жорсткіші індивідуальні обмеження. `OPENCLAW_DOCKER_ALL_LANES=` запускає точні лінії планувальника, зокрема релізні лінії на кшталт `install-e2e` і розділені лінії оновлення bundled на кшталт `bundled-channel-update-acpx`, пропускаючи cleanup smoke, щоб агенти могли відтворити одну проблемну лінію. Повторно використовуваний робочий процес live/E2E збирає і публікує один bare GHCR Docker E2E image з тегом SHA і один functional GHCR Docker E2E image з тегом SHA, а потім запускає релізний набір Docker як максимум три chunked jobs з `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб кожен чанк завантажував потрібний тип образу і виконував кілька ліній через той самий зважений планувальник (`OPENCLAW_DOCKER_ALL_PROFILE=release-path`, `OPENCLAW_DOCKER_ALL_CHUNK=core|package-update|plugins-integrations`). Кожен чанк завантажує `.artifacts/docker-tests/` з журналами ліній, таймінгами, `summary.json`, таймінгами фаз і командами повторного запуску для кожної лінії. Вхід `docker_lanes` робочого процесу запускає вибрані лінії на підготовлених образах замість трьох chunked jobs, що обмежує налагодження проблемної лінії одним цільовим Docker-завданням; якщо вибрана лінія є live Docker-лінією, цільове завдання локально збирає live-test image для такого повторного запуску. Коли Open WebUI запитується разом із набором release-path, він запускається всередині чанка plugins/integrations замість резервування четвертого Docker worker; Open WebUI зберігає окреме standalone-завдання лише для запусків openwebui-only. Запланований робочий процес live/E2E щодня запускає повний набір release-path Docker. Матрицю bundled update поділено за цільовим оновленням, щоб повторні проходи npm update і doctor repair можна було шардувати разом з іншими bundled-перевірками. +Логіка визначення охоплення міститься в `scripts/ci-changed-scope.mjs` і покрита unit-тестами в `src/scripts/ci-changed-scope.test.ts`. +Редагування робочих процесів CI перевіряють граф Node CI та lint робочих процесів, але самі по собі не змушують запускати нативні збірки для Windows, Android або macOS; ці платформні доріжки, як і раніше, обмежуються змінами у вихідному коді відповідної платформи. +Редагування лише маршрутизації CI, окремі дешеві зміни фікстур core-тестів і вузькі зміни helper/test-routing для контрактів plugins використовують швидкий шлях маніфесту лише для Node: preflight, security і єдине завдання `checks-fast-core`. Цей шлях обходить build artifacts, сумісність Node 22, контракти каналів, повні шарди core, шарди bundled plugins і додаткові матриці guard, коли змінені файли обмежені поверхнями маршрутизації або helper, які швидке завдання перевіряє безпосередньо. +Перевірки Windows Node обмежуються специфічними для Windows обгортками process/path, helper для запуску npm/pnpm/UI, конфігурацією менеджера пакетів і поверхнями робочих процесів CI, які виконують цю доріжку; нерелевантні зміни у вихідному коді, plugins, install-smoke та зміни лише в тестах залишаються на Linux Node-доріжках, щоб не резервувати Windows worker із 16 vCPU для покриття, яке вже перевіряється звичайними шардами тестів. +Окремий робочий процес `install-smoke` повторно використовує той самий script для охоплення через власне завдання `preflight`. Він розділяє smoke-покриття на `run_fast_install_smoke` і `run_full_install_smoke`. Pull request запускають швидкий шлях для поверхонь Docker/package, змін package/manifest bundled plugins і core-поверхонь plugin/channel/gateway/Plugin SDK, які перевіряють Docker smoke-завдання. Зміни лише у вихідному коді bundled plugins, зміни лише в тестах і зміни лише в документації не резервують Docker workers. Швидкий шлях один раз збирає образ із root Dockerfile, перевіряє CLI, запускає CLI smoke для agents delete shared-workspace, запускає container gateway-network e2e, перевіряє аргумент збірки bundled extension і запускає обмежений Docker profile bundled-plugin з агрегованим timeout команди у 240 секунд, де для кожного сценарію окремо обмежено `docker run`. Повний шлях зберігає QR package install і покриття installer Docker/update для нічних запусків за розкладом, ручних запусків, release checks через workflow-call і pull request, які справді зачіпають поверхні installer/package/Docker. Push у `main`, включно з merge-комітами, не примушують повний шлях; коли логіка changed-scope запитує повне покриття для push, робочий процес залишає швидкий Docker smoke, а повний install smoke віддає нічній або релізній валідації. Повільний smoke для Bun global install image-provider окремо керується через `run_bun_global_install_smoke`; він запускається в нічному розкладі та з робочого процесу release checks, а ручні запуски `install-smoke` можуть явно його увімкнути, але pull request і push у `main` його не запускають. Тести QR і installer Docker зберігають власні Dockerfile, орієнтовані на встановлення. Локальний `test:docker:all` попередньо збирає один спільний образ live-test, один раз пакує OpenClaw як npm tarball і збирає два спільні образи `scripts/e2e/Dockerfile`: базовий runner Node/Git для доріжок installer/update/plugin-dependency і функціональний образ, який встановлює той самий tarball у `/app` для звичайних функціональних доріжок. Визначення Docker-доріжок містяться в `scripts/lib/docker-e2e-scenarios.mjs`, логіка планувальника — в `scripts/lib/docker-e2e-plan.mjs`, а runner виконує лише вибраний план. Планувальник вибирає образ для доріжки через `OPENCLAW_DOCKER_E2E_BARE_IMAGE` і `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`, а потім запускає доріжки з `OPENCLAW_SKIP_DOCKER_BUILD=1`; типову кількість слотів основного пулу 10 можна налаштувати через `OPENCLAW_DOCKER_ALL_PARALLELISM`, а кількість слотів tail-пулу 10, чутливого до provider, — через `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM`. Обмеження для важких доріжок за замовчуванням: `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`, щоб доріжки npm install і багатосервісні доріжки не перевантажували Docker, поки легші доріжки все ще заповнюють доступні слоти. Запуск доріжок за замовчуванням зсувається на 2 секунди, щоб уникнути локальних штормів створення в Docker daemon; це можна перевизначити через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` або інше значення в мілісекундах. Локальний агрегований запуск попередньо перевіряє Docker, видаляє застарілі контейнери OpenClaw E2E, виводить статус активних доріжок, зберігає час виконання доріжок для впорядкування за принципом longest-first і підтримує `OPENCLAW_DOCKER_ALL_DRY_RUN=1` для перевірки планувальника. За замовчуванням він припиняє планувати нові pooled-доріжки після першої помилки, і кожна доріжка має резервний timeout 120 хвилин, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; вибрані live/tail-доріжки використовують жорсткіші обмеження для кожної доріжки. `OPENCLAW_DOCKER_ALL_LANES=` запускає точні доріжки планувальника, включно з доріжками лише для релізу, як-от `install-e2e`, і розділеними доріжками оновлення bundled, як-от `bundled-channel-update-acpx`, водночас пропускаючи cleanup smoke, щоб агенти могли відтворити одну зламану доріжку. Повторно використовуваний робочий процес live/E2E запитує в `scripts/test-docker-all.mjs --plan-json`, яке package, тип образу, live-образ, доріжка та покриття credentials потрібні, після чого `scripts/docker-e2e.mjs` перетворює цей план на GitHub outputs і summary. Він пакує OpenClaw через `scripts/package-openclaw-for-docker.mjs`, збирає та пушить один bare GHCR Docker E2E image із тегом SHA, коли план потребує доріжок install/update/plugin-dependency, і збирає один functional GHCR Docker E2E image із тегом SHA, коли план потребує функціональних доріжок із встановленим package. Docker-набір для релізного шляху запускається максимум як три chunked jobs з `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб кожен chunk завантажував лише потрібний йому тип образу й виконував кілька доріжок через той самий зважений планувальник (`OPENCLAW_DOCKER_ALL_PROFILE=release-path`, `OPENCLAW_DOCKER_ALL_CHUNK=core|package-update|plugins-integrations`). Кожен chunk завантажує `.artifacts/docker-tests/` із логами доріжок, таймінгами, `summary.json`, таймінгами фаз, JSON-планом планувальника та командами повторного запуску для кожної доріжки. Вхід `docker_lanes` робочого процесу запускає вибрані доріжки на підготовлених образах замість трьох chunked jobs, що обмежує налагодження зламаної доріжки одним цільовим Docker job; якщо вибрана доріжка є live Docker-доріжкою, цільове завдання локально збирає live-test image для такого повторного запуску. Коли для release-path suite запитується Open WebUI, він виконується всередині chunk plugins/integrations замість резервування четвертого Docker worker; Open WebUI зберігає окреме завдання лише для dispatch, призначених тільки для openwebui. Запланований робочий процес live/E2E щодня запускає повний release-path Docker suite. Матриця bundled update розділена за ціллю оновлення, щоб повторні проходи npm update і doctor repair могли шардитися разом з іншими bundled-перевірками. -Локальна логіка changed-lanes міститься в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний gate суворіший щодо архітектурних меж, ніж широке платформне охоплення CI: production-зміни core запускають typecheck для core prod і core-тести, зміни лише в core-тестах запускають тільки typecheck/tests для core test, production-зміни розширень запускають typecheck для extension prod і тести розширень, а зміни лише в тестах розширень запускають лише typecheck/tests для extension test. Зміни у публічному Plugin SDK або plugin-contract розширюють валідацію на розширення, оскільки розширення залежать від цих контрактів core. Зміни лише в метаданих релізу з оновленням версій запускають цільові перевірки version/config/root-dependency. Невідомі зміни в корені/конфігурації безпечно ескалюються до всіх ліній. +Локальна логіка changed-lane міститься в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний поріг суворіший щодо архітектурних меж, ніж широке CI-охоплення платформ: зміни в core production запускають typecheck core prod плюс core-тести, зміни лише в core-тестах запускають лише typecheck/tests для core-тестів, зміни в extension production запускають typecheck extension prod плюс extension-тести, а зміни лише в extension-тестах запускають лише typecheck/tests для extension-тестів. Зміни в публічному Plugin SDK або plugin-contract розширюють валідацію на extensions, оскільки extensions залежать від цих core-контрактів. Підвищення версії лише в release metadata запускають цільові перевірки version/config/root-dependency. Невідомі зміни в root/config безпечно переводять виконання на всі доріжки. -Для пушів матриця `checks` додає лінію `compat-node22`, що запускається лише для push. Для pull request ця лінія пропускається, і матриця зосереджується на звичайних тестових/канальних лініях. +Для push матриця `checks` додає доріжку `compat-node22`, що запускається лише для push. Для pull request ця доріжка пропускається, і матриця залишається зосередженою на звичайних тестових доріжках і доріжках каналів. -Найповільніші сімейства Node-тестів поділені або збалансовані так, щоб кожне завдання залишалося невеликим без надмірного резервування runner-ів: контракти каналів запускаються як три зважені шарди, тести bundled-плагінів балансуються між шістьма worker-ами розширень, малі core unit-лінії попарно об’єднуються, auto-reply запускається на чотирьох збалансованих worker-ах із поділом reply subtree на шарди agent-runner, dispatch і commands/state-routing, а конфігурації agentic gateway/plugin розподіляються по наявних source-only agentic Node-завданнях замість очікування зібраних артефактів. Широкі browser-, QA-, media- і miscellaneous plugin-тести використовують свої окремі конфігурації Vitest замість спільного plugin catch-all. Завдання shard для розширень запускають до двох груп конфігурацій плагінів одночасно з одним worker-ом Vitest на групу і збільшеним heap Node, щоб батчі плагінів із важкими імпортами не створювали додаткових CI-завдань. Широка лінія agents використовує спільний file-parallel scheduler Vitest, оскільки в ній домінують імпорти/планування, а не один повільний тестовий файл. `runtime-config` запускається разом із shard `infra core-runtime`, щоб спільний runtime-shard не тягнув хвіст виконання. Шарди на основі include-pattern записують дані таймінгів із використанням імені CI-shard, тому `.artifacts/vitest-shard-timings.json` може відрізняти цілу конфігурацію від відфільтрованого shard. `check-additional` тримає разом package-boundary compile/canary-роботи й відокремлює runtime topology architecture від gateway watch coverage; shard boundary guard запускає свої малі незалежні guard-перевірки паралельно в межах одного завдання. Gateway watch, тести каналів і shard core support-boundary запускаються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` уже зібрані, зберігаючи свої старі назви перевірок як легкі верифікаційні завдання та водночас уникаючи двох додаткових Blacksmith workers і другої черги споживачів артефактів. -Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, а потім збирає Play debug APK. Flavor third-party не має окремого source set або маніфесту; його лінія модульних тестів усе одно компілює цей flavor із прапорцями BuildConfig для SMS/call-log, водночас уникаючи дубльованого завдання пакування debug APK для кожного push, релевантного для Android. -`extension-fast` працює лише для PR, оскільки push-запуски вже виконують повні шарди bundled-плагінів. Це дає швидкий зворотний зв’язок для перевірки змінених плагінів у review, не резервуючи додатковий Blacksmith worker у `main` для покриття, яке вже наявне в `checks-node-extensions`. +Найповільніші сімейства Node-тестів розділені або збалансовані так, щоб кожне завдання залишалося невеликим без надмірного резервування runner-ів: контракти каналів виконуються як три зважені шарди, тести bundled plugins балансуються між шістьма workers для extension, малі unit-доріжки core попарно поєднуються, auto-reply виконується на чотирьох збалансованих workers із розбиттям піддерева reply на шарди agent-runner, dispatch і commands/state-routing, а конфігурації agentic gateway/plugin розподіляються між наявними Node-завданнями agentic лише для source, замість очікування на build artifacts. Широкі browser-, QA-, media- і miscellaneous plugin-тести використовують свої окремі конфігурації Vitest замість спільного універсального набору для plugins. Завдання шардів extension одночасно запускають до двох груп конфігурацій plugins з одним worker Vitest на групу і більшим heap Node, щоб batch-набори plugins з важкими import не створювали додаткових завдань CI. Широка доріжка agents використовує спільний file-parallel scheduler Vitest, оскільки її визначають imports/планування, а не один повільний тестовий файл. `runtime-config` запускається разом із шардом infra core-runtime, щоб спільний runtime-shard не залишався хвостовим. Шарди за include-pattern записують таймінги з використанням назви CI-shard, тож `.artifacts/vitest-shard-timings.json` може відрізняти цілу конфігурацію від відфільтрованого shard. `check-additional` тримає разом compile/canary-роботи для package-boundary і відокремлює архітектуру runtime topology від покриття gateway watch; shard boundary guard виконує свої невеликі незалежні guard-перевірки паралельно в межах одного завдання. Gateway watch, тести каналів і shard core support-boundary виконуються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` уже зібрані, зберігаючи свої попередні назви перевірок як легкі завдання-верифікатори та уникаючи двох додаткових Blacksmith workers і другої черги споживачів артефактів. +Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, а потім збирає Play debug APK. Flavor third-party не має окремого source set або manifest; його доріжка unit-тестів усе одно компілює цей flavor з прапорцями SMS/call-log у BuildConfig, водночас уникаючи дубльованого пакування debug APK для кожного push, релевантного для Android. +`extension-fast` є лише для PR, оскільки push-запуски вже виконують повні шарди bundled plugins. Це зберігає швидкий зворотний зв’язок для перевірки змінених plugins без резервування додаткового Blacksmith worker у `main` для покриття, яке вже присутнє в `checks-node-extensions`. -GitHub може позначати витіснені завдання як `cancelled`, коли новіший push надходить у той самий PR або ref `main`. Вважайте це шумом CI, якщо тільки найновіший запуск для того самого ref теж не падає. Агреговані shard-перевірки використовують `!cancelled() && always()`, тож вони все одно повідомляють про звичайні збої shard-ів, але не стають у чергу після того, як увесь робочий процес уже було витіснено. -Ключ конкурентності CI має версію (`CI-v7-*`), щоб zombie на стороні GitHub у старій групі черги не міг безкінечно блокувати новіші запуски `main`. +GitHub може позначати витіснені завдання як `cancelled`, коли новіший push потрапляє в той самий ref PR або `main`. Вважайте це шумом CI, якщо тільки найновіший запуск для того самого ref також не падає. Агреговані shard-перевірки використовують `!cancelled() && always()`, тож вони все ще повідомляють про звичайні збої shard-ів, але не стають у чергу після того, як увесь робочий процес уже було витіснено. +Ключ concurrency для CI має версіювання (`CI-v7-*`), щоб zombie-процес на боці GitHub у старій групі черги не міг безкінечно блокувати новіші запуски main. ## Runner-и | Runner | Завдання | -| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `ubuntu-24.04` | `preflight`, швидкі завдання безпеки та агрегати (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі перевірки protocol/contract/bundled, шардовані перевірки контрактів каналів, шарди `check`, окрім lint, шарди та агрегати `check-additional`, агреговані верифікатори Node-тестів, перевірки документації, Python Skills, workflow-sanity, labeler, auto-response; preflight для install-smoke також використовує GitHub-hosted Ubuntu, щоб матриця Blacksmith могла ставати в чергу раніше | -| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`, build-smoke, шарди Linux Node-тестів, шарди тестів bundled-плагінів, `android` | -| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`, який залишається достатньо чутливим до CPU, тому 8 vCPU коштували дорожче, ніж давали вигоди; Docker-збирання install-smoke, де час очікування в черзі для 32-vCPU коштував дорожче, ніж давав вигоди | -| `blacksmith-16vcpu-windows-2025` | `checks-windows` | -| `blacksmith-6vcpu-macos-latest` | `macos-node` у `openclaw/openclaw`; для форків використовується резервний варіант `macos-latest` | -| `blacksmith-12vcpu-macos-latest` | `macos-swift` у `openclaw/openclaw`; для форків використовується резервний варіант `macos-latest` | +| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ubuntu-24.04` | `preflight`, швидкі завдання безпеки та агрегати (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі перевірки protocol/contract/bundled, шардовані перевірки контрактів каналів, шарди `check`, крім lint, шарди й агрегати `check-additional`, агреговані верифікатори Node-тестів, перевірки docs, Python Skills, workflow-sanity, labeler, auto-response; preflight для install-smoke також використовує GitHub-hosted Ubuntu, щоб матриця Blacksmith могла ставати в чергу раніше | +| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`, build-smoke, шарди Linux Node-тестів, шарди тестів bundled plugins, `android` | +| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`, який усе ще достатньо чутливий до CPU, тож 8 vCPU коштували дорожче, ніж давали вигоди; Docker-збірки install-smoke, де час очікування в черзі для 32 vCPU коштував дорожче, ніж давав вигоди | +| `blacksmith-16vcpu-windows-2025` | `checks-windows` | +| `blacksmith-6vcpu-macos-latest` | `macos-node` у `openclaw/openclaw`; для форків використовується резервний перехід на `macos-latest` | +| `blacksmith-12vcpu-macos-latest` | `macos-swift` у `openclaw/openclaw`; для форків використовується резервний перехід на `macos-latest` | ## Локальні еквіваленти ```bash -pnpm changed:lanes # переглянути локальний класифікатор changed-lane для origin/main...HEAD -pnpm check:changed # розумний локальний gate: changed typecheck/lint/tests за boundary lane -pnpm check # швидкий локальний gate: production tsgo + шардований lint + паралельні швидкі guard-перевірки +pnpm changed:lanes # перевірити локальний класифікатор changed-lane для origin/main...HEAD +pnpm check:changed # розумний локальний поріг: changed typecheck/lint/tests за boundary lane +pnpm check # швидкий локальний поріг: production tsgo + шардований lint + паралельні швидкі guard-перевірки pnpm check:test-types -pnpm check:timed # той самий gate з таймінгами по етапах +pnpm check:timed # той самий поріг із таймінгами для кожного етапу pnpm build:strict-smoke pnpm check:architecture pnpm test:gateway:watch-regression pnpm test # тести vitest pnpm test:channels pnpm test:contracts:channels -pnpm check:docs # форматування документації + lint + зламані посилання -pnpm build # зібрати dist, коли мають значення лінії CI artifact/build-smoke -pnpm ci:timings # підсумувати останній push-запуск CI для origin/main +pnpm check:docs # форматування docs + lint + биті посилання +pnpm build # збірка dist, коли важливі доріжки CI artifact/build-smoke +pnpm ci:timings # підсумок останнього запуску push CI для origin/main pnpm ci:timings:recent # порівняти нещодавні успішні запуски main CI -node scripts/ci-run-timings.mjs # підсумувати загальний час, час у черзі та найповільніші завдання -node scripts/ci-run-timings.mjs --latest-main # ігнорувати шум issue/comment і вибрати push CI для origin/main +node scripts/ci-run-timings.mjs # підсумок wall time, queue time і найповільніших завдань +node scripts/ci-run-timings.mjs --latest-main # ігнорувати шум від issue/comment і вибрати push CI для origin/main node scripts/ci-run-timings.mjs --recent 10 # порівняти нещодавні успішні запуски main CI pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json diff --git a/docs/uk/help/testing.md b/docs/uk/help/testing.md index 175ab76d7..ce0fac369 100644 --- a/docs/uk/help/testing.md +++ b/docs/uk/help/testing.md @@ -1,15 +1,15 @@ --- read_when: - Запуск тестів локально або в CI - - Додавання регресійних тестів для багів моделі/провайдера - - Налагодження поведінки Gateway + агента + - Додавання регресійних тестів для багів моделей/провайдерів + - Налагодження поведінки Gateway + агентів summary: 'Набір для тестування: набори unit/e2e/live, ранери Docker і що охоплює кожен тест' title: Тестування x-i18n: - generated_at: "2026-04-26T22:14:42Z" + generated_at: "2026-04-26T22:39:59Z" model: gpt-5.4 provider: openai - source_hash: 425a86fc79b306f1957308c4060874d8d10a5ac61fb29b6cb91b7df3f445db91 + source_hash: 4499f5092819a250971610ce3e31191b871cd2a1d2915bb7479f9439cea94dcd source_path: help/testing.md workflow: 15 --- @@ -18,7 +18,7 @@ OpenClaw має три набори Vitest (unit/integration, e2e, live) і не ранерів Docker. Цей документ — посібник «як ми тестуємо»: - Що охоплює кожен набір (і що він навмисно _не_ охоплює). -- Які команди запускати для типових сценаріїв (локально, перед push, налагодження). +- Які команди запускати для типових сценаріїв роботи (локально, перед push, налагодження). - Як live-тести знаходять облікові дані та вибирають моделі/провайдерів. - Як додавати регресійні тести для реальних проблем із моделями/провайдерами. @@ -26,222 +26,225 @@ OpenClaw має три набори Vitest (unit/integration, e2e, live) і не У більшості випадків: -- Повний набір перевірок (очікується перед push): `pnpm build && pnpm check && pnpm check:test-types && pnpm test` +- Повний gate (очікується перед push): `pnpm build && pnpm check && pnpm check:test-types && pnpm test` - Швидший локальний запуск повного набору на потужній машині: `pnpm test:max` - Прямий цикл спостереження Vitest: `pnpm test:watch` -- Пряме націлення на файл тепер також маршрутизує шляхи extension/channel: `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -- Під час ітерації над однією помилкою спочатку віддавайте перевагу цільовим запускам. +- Прямий таргетинг файлу тепер також маршрутизує шляхи extension/channel: `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- Під час ітерацій над однією помилкою спочатку віддавайте перевагу цільовим запускам. - QA-сайт на базі Docker: `pnpm qa:lab:up` -- QA-lane на базі Linux VM: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` +- QA-лайн на базі Linux VM: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` Коли ви змінюєте тести або хочете додаткової впевненості: -- Перевірка покриття: `pnpm test:coverage` +- Gate покриття: `pnpm test:coverage` - Набір E2E: `pnpm test:e2e` Під час налагодження реальних провайдерів/моделей (потрібні реальні облікові дані): - Live-набір (моделі + перевірки інструментів/зображень Gateway): `pnpm test:live` -- Точковий запуск одного live-файлу без зайвого виводу: `pnpm test:live -- src/agents/models.profiles.live.test.ts` -- Docker-прогін live-моделей: `pnpm test:docker:live-models` - - Кожна вибрана модель тепер виконує текстовий хід плюс невелику перевірку у стилі читання файлу. - Моделі, у метаданих яких заявлено вхід `image`, також виконують невеликий хід із зображенням. +- Таргетинг одного live-файлу без зайвого виводу: `pnpm test:live -- src/agents/models.profiles.live.test.ts` +- Docker-прохід live-моделей: `pnpm test:docker:live-models` + - Для кожної вибраної моделі тепер виконується текстовий хід плюс невелика перевірка у стилі читання файлу. + Моделі, у чиїх метаданих зазначено вхід `image`, також виконують маленький хід із зображенням. Вимкніть додаткові перевірки за допомогою `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` або `OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0`, коли ізолюєте збої провайдера. - - Покриття в CI: щоденний `OpenClaw Scheduled Live And E2E Checks` і ручний + - Покриття CI: щоденний `OpenClaw Scheduled Live And E2E Checks` і ручний `OpenClaw Release Checks` обидва викликають повторно використовуваний live/E2E workflow з - `include_live_suites: true`, що включає окремі матричні Docker-завдання live-моделей, - розшардовані за провайдером. - - Для точкових повторних запусків у CI запустіть `OpenClaw Live And E2E Checks (Reusable)` + `include_live_suites: true`, що включає окремі matrix jobs Docker live-моделей, + розбиті за провайдером. + - Для цільових повторних запусків у CI викличте `OpenClaw Live And E2E Checks (Reusable)` з `include_live_suites: true` і `live_models_only: true`. - - Додавайте нові високосигнальні секрети провайдерів до `scripts/ci-hydrate-live-auth.sh`, + - Додавайте нові high-signal секрети провайдерів до `scripts/ci-hydrate-live-auth.sh`, а також до `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` і його - викликів за розкладом/для релізу. -- Smoke-тест native Codex bound-chat: `pnpm test:docker:live-codex-bind` - - Запускає Docker live lane проти шляху app-server Codex, прив’язує синтетичний + scheduled/release викликів. +- Native Codex bound-chat smoke: `pnpm test:docker:live-codex-bind` + - Запускає Docker live-лайн проти шляху Codex app-server, прив’язує синтетичний Slack DM через `/codex bind`, виконує `/codex fast` і `/codex permissions`, а потім перевіряє, що звичайна відповідь і вкладення-зображення - проходять через native Plugin binding, а не через ACP. -- Smoke-тест harness app-server Codex: `pnpm test:docker:live-codex-harness` - - Пропускає ходи агента Gateway через Plugin-owned harness app-server Codex, + проходять через native-прив’язку Plugin, а не через ACP. +- Codex app-server harness smoke: `pnpm test:docker:live-codex-harness` + - Пропускає ходи агентів Gateway через harness app-server, що належить Plugin у Codex, перевіряє `/codex status` і `/codex models`, а також за замовчуванням виконує перевірки image, cron MCP, sub-agent і Guardian. Вимкніть перевірку sub-agent за допомогою `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0`, коли ізолюєте інші збої app-server Codex. - Для точкової перевірки sub-agent вимкніть інші перевірки: + Для цільової перевірки sub-agent вимкніть інші перевірки: `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness`. Це завершиться після перевірки sub-agent, якщо не встановлено `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`. -- Smoke-тест rescue command Crestodian: `pnpm test:live:crestodian-rescue-channel` - - Опціональна додаткова перевірка поверхні rescue command для каналу повідомлень. - Вона виконує `/crestodian status`, ставить у чергу стійку зміну моделі, +- Smoke перевірки rescue-команди Crestodian: `pnpm test:live:crestodian-rescue-channel` + - Opt-in перевірка типу belt-and-suspenders для поверхні rescue-команди каналу повідомлень. + Вона виконує `/crestodian status`, ставить у чергу постійну зміну моделі, відповідає `/crestodian yes` і перевіряє шлях запису audit/config. -- Docker smoke-тест planner Crestodian: `pnpm test:docker:crestodian-planner` - - Запускає Crestodian у контейнері без конфігурації з фальшивим Claude CLI в `PATH` - і перевіряє, що запасний fuzzy planner перетворюється на типізований запис - конфігурації з audit. -- Docker smoke-тест першого запуску Crestodian: `pnpm test:docker:crestodian-first-run` - - Стартує з порожнього каталогу стану OpenClaw, маршрутизує голий `openclaw` до +- Docker smoke планувальника Crestodian: `pnpm test:docker:crestodian-planner` + - Запускає Crestodian у контейнері без конфігурації з підробленим Claude CLI у `PATH` + і перевіряє, що fuzzy planner fallback перетворюється на audited typed + запис у config. +- Docker smoke першого запуску Crestodian: `pnpm test:docker:crestodian-first-run` + - Починає з порожнього каталогу стану OpenClaw, маршрутизує простий `openclaw` до Crestodian, застосовує записи setup/model/agent/Discord plugin + SecretRef, - перевіряє конфігурацію і записи audit. Той самий шлях налаштування Ring 0 - також покрито в QA Lab через + валідує config і перевіряє записи audit. Той самий шлях налаштування Ring 0 + також покривається в QA Lab через `pnpm openclaw qa suite --scenario crestodian-ring-zero-setup`. -- Smoke-тест вартості Moonshot/Kimi: якщо встановлено `MOONSHOT_API_KEY`, виконайте - `openclaw models list --provider moonshot --json`, а потім ізольований +- Smoke перевірка вартості Moonshot/Kimi: коли встановлено `MOONSHOT_API_KEY`, виконайте + `openclaw models list --provider moonshot --json`, а потім виконайте ізольований `openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json` - проти `moonshot/kimi-k2.6`. Перевірте, що JSON повідомляє Moonshot/K2.6 і що - транскрипт помічника зберігає нормалізований `usage.cost`. + проти `moonshot/kimi-k2.6`. Переконайтеся, що JSON повідомляє про Moonshot/K2.6 і що + transcript асистента зберігає нормалізований `usage.cost`. -Порада: коли вам потрібен лише один збійний випадок, віддавайте перевагу звуженню live-тестів за допомогою змінних середовища allowlist, описаних нижче. +Порада: коли вам потрібен лише один проблемний випадок, надавайте перевагу звуженню live-тестів через env-змінні allowlist, описані нижче. -## Ранери для QA +## QA-специфічні ранери -Ці команди працюють поруч з основними наборами тестів, коли вам потрібен реалізм QA-lab: +Ці команди розташовані поруч з основними наборами тестів, коли вам потрібен рівень реалістичності QA Lab: CI запускає QA Lab в окремих workflow. `Parity gate` запускається для відповідних PR і -через ручний dispatch із mock-провайдерами. `QA-Lab - All Lanes` запускається щоночі на -`main` і через ручний dispatch із mock parity gate, live Matrix lane і -live Telegram lane під керуванням Convex як паралельні завдання. `OpenClaw Release Checks` -запускає ті самі lane перед затвердженням релізу. +через manual dispatch з mock-провайдерами. `QA-Lab - All Lanes` запускається щоночі на +`main` і через manual dispatch з mock parity gate, live Matrix lane і +live Telegram lane під керуванням Convex як паралельними jobs. `OpenClaw Release Checks` +запускає ті самі лайни перед схваленням релізу. - `pnpm openclaw qa suite` - - Запускає QA-сценарії з репозиторію безпосередньо на хості. + - Запускає QA-сценарії на основі репозиторію безпосередньо на хості. - За замовчуванням запускає кілька вибраних сценаріїв паралельно з ізольованими - Gateway workers. `qa-channel` за замовчуванням має concurrency 4 (обмежується + працівниками Gateway. `qa-channel` за замовчуванням має concurrency 4 (обмежену кількістю вибраних сценаріїв). Використовуйте `--concurrency `, щоб налаштувати - кількість workers, або `--concurrency 1` для старішого послідовного lane. - - Повертає ненульовий код виходу, якщо будь-який сценарій завершується помилкою. - Використовуйте `--allow-failures`, якщо вам потрібні артефакти без помилкового коду виходу. + кількість працівників, або `--concurrency 1` для старішого послідовного лайну. + - Завершується з ненульовим кодом, якщо будь-який сценарій зазнав невдачі. Використовуйте `--allow-failures`, якщо + вам потрібні артефакти без коду завершення з помилкою. - Підтримує режими провайдерів `live-frontier`, `mock-openai` і `aimock`. `aimock` запускає локальний сервер провайдера на базі AIMock для експериментального - покриття fixture і protocol-mock без заміни lane `mock-openai`, який знає про сценарії. + покриття fixture і protocol-mock без заміни лайну `mock-openai`, + який враховує сценарії. - `pnpm openclaw qa suite --runner multipass` - Запускає той самий QA-набір усередині тимчасової Linux VM Multipass. - - Зберігає ту саму поведінку вибору сценаріїв, що й `qa suite` на хості. - - Повторно використовує ті самі прапорці вибору провайдера/моделі, що й `qa suite`. - - Live-запуски передають у guest підтримувані вхідні QA-дані автентифікації, які для нього практичні: - ключі провайдерів через env, шлях до конфігурації live-провайдера QA і `CODEX_HOME`, якщо він наявний. + - Зберігає таку саму поведінку вибору сценаріїв, як і `qa suite` на хості. + - Повторно використовує ті самі прапори вибору провайдера/моделі, що й `qa suite`. + - Live-запуски передають підтримувані QA auth-входи, які практично використовувати для guest: + ключі провайдерів на основі env, шлях до config QA live provider і `CODEX_HOME`, якщо він наявний. - Каталоги виводу мають залишатися в межах кореня репозиторію, щоб guest міг записувати назад через змонтований workspace. - - Записує звичайний QA-звіт і підсумок, а також логи Multipass у + - Записує звичайні QA report + summary, а також логи Multipass у `.artifacts/qa-e2e/...`. - `pnpm qa:lab:up` - - Запускає QA-сайт на базі Docker для QA-роботи в операторському стилі. + - Запускає QA-сайт на базі Docker для операторської QA-роботи. - `pnpm test:docker:npm-onboard-channel-agent` - Збирає npm tarball з поточного checkout, встановлює його глобально в - Docker, виконує неінтерактивний onboarding із ключем API OpenAI, налаштовує Telegram - за замовчуванням, перевіряє, що ввімкнення Plugin встановлює runtime-залежності на вимогу, + Docker, виконує неінтерактивний onboarding OpenAI API-key, за замовчуванням налаштовує Telegram, + перевіряє, що ввімкнення Plugin встановлює runtime-залежності за потреби, запускає doctor і виконує один локальний хід агента проти замоканого endpoint OpenAI. - - Використовуйте `OPENCLAW_NPM_ONBOARD_CHANNEL=discord`, щоб запустити той самий lane - packaged-install з Discord. + - Використовуйте `OPENCLAW_NPM_ONBOARD_CHANNEL=discord`, щоб запустити той самий лайн + встановлення упакованої версії з Discord. - `pnpm test:docker:session-runtime-context` - - Виконує детермінований Docker smoke-тест built-app для вбудованих транскриптів runtime context. + - Запускає детермінований Docker smoke зібраного застосунку для transcript із вбудованим runtime context. Він перевіряє, що прихований runtime context OpenClaw зберігається як - спеціальне повідомлення, яке не відображається, замість витоку у видимий хід користувача, - потім підкладає пошкоджений JSONL сеансу і перевіряє, що + недисплейне custom-повідомлення замість витоку у видимий хід користувача, + потім підставляє зламаний JSONL сесії й перевіряє, що `openclaw doctor --fix` переписує його в активну гілку з резервною копією. - `pnpm test:docker:npm-telegram-live` - - Встановлює опублікований пакет OpenClaw у Docker, виконує onboarding для встановленого пакета, + - Встановлює опублікований пакет OpenClaw у Docker, виконує onboarding встановленого пакета, налаштовує Telegram через встановлений CLI, а потім повторно використовує - live Telegram QA lane з цим встановленим пакетом як SUT Gateway. + live Telegram QA-лайн з цим встановленим пакетом як SUT Gateway. - За замовчуванням використовується `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`. - - Використовує ті самі облікові дані Telegram через env або джерело облікових даних Convex, що й - `pnpm openclaw qa telegram`. Для автоматизації в CI/релізах установіть - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex` плюс + - Використовує ті самі env-облікові дані Telegram або джерело облікових даних Convex, що й + `pnpm openclaw qa telegram`. Для автоматизації CI/release встановіть + `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`, а також `OPENCLAW_QA_CONVEX_SITE_URL` і role secret. Якщо `OPENCLAW_QA_CONVEX_SITE_URL` і Convex role secret наявні в CI, обгортка Docker автоматично вибирає Convex. - - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` перевизначає спільну - `OPENCLAW_QA_CREDENTIAL_ROLE` лише для цього lane. - - У GitHub Actions цей lane доступний як ручний workflow для мейнтейнерів + - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` перевизначає спільний + `OPENCLAW_QA_CREDENTIAL_ROLE` лише для цього лайну. + - GitHub Actions надає цей лайн як ручний workflow для супровідників `NPM Telegram Beta E2E`. Він не запускається під час merge. Workflow використовує - середовище `qa-live-shared` і оренду облікових даних Convex CI. + середовище `qa-live-shared` і оренди облікових даних Convex CI. - `pnpm test:docker:bundled-channel-deps` - - Пакує і встановлює поточну збірку OpenClaw у Docker, запускає Gateway - зі сконфігурованим OpenAI, а потім вмикає bundled channel/plugins через редагування конфігурації. - - Перевіряє, що виявлення setup залишає невстановленими runtime-залежності - не налаштованих Plugin, що перший налаштований запуск Gateway або doctor встановлює - runtime-залежності кожного bundled Plugin на вимогу, і що другий restart не перевстановлює - залежності, які вже були активовані. + - Пакує та встановлює поточну збірку OpenClaw у Docker, запускає Gateway + з налаштованим OpenAI, а потім вмикає вбудовані channel/plugins через редагування config. + - Перевіряє, що виявлення setup залишає відсутніми runtime-залежності + неналаштованих plugin, що перший налаштований запуск Gateway або doctor встановлює runtime-залежності + кожного вбудованого plugin за потреби, і що другий перезапуск не перевстановлює залежності, + які вже були активовані. - Також встановлює відому старішу npm-базову версію, вмикає Telegram перед запуском - `openclaw update --tag `, і перевіряє, що - post-update doctor у кандидаті відновлює runtime-залежності bundled channel без - postinstall-відновлення з боку harness. + `openclaw update --tag ` і перевіряє, що post-update doctor кандидата + відновлює runtime-залежності вбудованих channel без відновлення postinstall + з боку harness. - `pnpm test:parallels:npm-update` - - Запускає native smoke-тест оновлення packaged-install на guest-системах Parallels. Кожна - вибрана платформа спочатку встановлює вказаний базовий пакет, потім виконує команду - встановленого `openclaw update` у тій самій guest-системі і перевіряє встановлену + - Запускає native smoke оновлення встановленого пакета в Parallels guest. Кожна + вибрана платформа спочатку встановлює потрібний базовий пакет, потім виконує + встановлену команду `openclaw update` у тому самому guest і перевіряє встановлену версію, статус оновлення, готовність gateway і один локальний хід агента. - - Використовуйте `--platform macos`, `--platform windows` або `--platform linux`, коли - ітеруєте над однією guest-системою. Використовуйте `--json` для шляху до підсумкового артефакту і - статусу кожного lane. - - За замовчуванням lane OpenAI використовує `openai/gpt-5.5` для live-перевірки ходу агента. + - Використовуйте `--platform macos`, `--platform windows` або `--platform linux` під час + ітерацій над одним guest. Використовуйте `--json` для шляху до summary artifact і + статусу кожного лайну. + - Лайн OpenAI за замовчуванням використовує `openai/gpt-5.5` для перевірки live agent-turn. Передайте `--model ` або встановіть - `OPENCLAW_PARALLELS_OPENAI_MODEL`, якщо навмисно перевіряєте іншу - модель OpenAI. - - Обгортайте довгі локальні запуски в host timeout, щоб збої транспорту Parallels - не поглинули решту вікна тестування: + `OPENCLAW_PARALLELS_OPENAI_MODEL`, якщо навмисно перевіряєте іншу модель OpenAI. + - Обгортайте довгі локальні запуски в host timeout, щоб зависання транспорту Parallels не + поглинало решту вікна тестування: ```bash timeout --foreground 150m pnpm test:parallels:npm-update -- --json timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json ``` - - Скрипт записує вкладені логи lane у `/tmp/openclaw-parallels-npm-update.*`. - Перегляньте `windows-update.log`, `macos-update.log` або `linux-update.log`, + - Скрипт записує вкладені логи лайнів у `/tmp/openclaw-parallels-npm-update.*`. + Перевіряйте `windows-update.log`, `macos-update.log` або `linux-update.log`, перш ніж вважати, що зовнішня обгортка зависла. - - Оновлення Windows може займати від 10 до 15 хвилин на post-update doctor/runtime - repair залежностей на холодній guest-системі; це все ще є нормальним, якщо вкладений + - Оновлення Windows може витрачати 10–15 хвилин на відновлення doctor/runtime dependency + після оновлення на cold guest; це все ще вважається нормальним, якщо вкладений npm debug log продовжує оновлюватися. - - Не запускайте цю агреговану обгортку паралельно з окремими smoke-lane Parallels - для macOS, Windows або Linux. Вони спільно використовують стан VM і можуть конфліктувати під час - відновлення snapshot, видачі пакетів або стану guest gateway. - - Перевірка після оновлення виконує звичайну поверхню bundled Plugin, оскільки - capability facades, як-от мовлення, генерація зображень і - розуміння медіа, завантажуються через bundled runtime API, навіть якщо сам + - Не запускайте цю агреговану обгортку паралельно з окремими smoke-лайнами Parallels + macOS, Windows або Linux. Вони використовують спільний стан VM і можуть конфліктувати під час + відновлення snapshot, видачі пакета або стану guest gateway. + - Перевірка після оновлення запускає звичайну поверхню bundled plugin, оскільки + capability facades, як-от speech, image generation і media + understanding, завантажуються через bundled runtime API навіть тоді, коли сам хід агента перевіряє лише просту текстову відповідь. - `pnpm openclaw qa aimock` - Запускає лише локальний сервер провайдера AIMock для прямого smoke-тестування протоколу. - `pnpm openclaw qa matrix` - - Запускає live QA lane Matrix проти тимчасового homeserver Tuwunel на базі Docker. - - Цей QA-хост наразі призначений лише для репозиторію/розробки. Упаковані встановлення OpenClaw не постачають + - Запускає live QA-лайн Matrix проти тимчасового homeserver Tuwunel на базі Docker. + - Цей QA-хост наразі призначений лише для репозиторію/розробки. Упаковані встановлення OpenClaw не постачаються з `qa-lab`, тому не надають `openclaw qa`. - - Checkout репозиторію напряму завантажують bundled runner; окремий крок встановлення Plugin не потрібен. - - Створює трьох тимчасових користувачів Matrix (`driver`, `sut`, `observer`) плюс одну приватну кімнату, а потім запускає дочірній QA gateway з реальним Plugin Matrix як транспортом SUT. - - За замовчуванням використовує зафіксований стабільний образ Tuwunel `ghcr.io/matrix-construct/tuwunel:v1.5.1`. Перевизначте його через `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE`, якщо потрібно протестувати інший образ. - - Matrix не надає спільних прапорців джерела облікових даних, тому що lane локально створює тимчасових користувачів. - - Записує звіт Matrix QA, підсумок, артефакт observed-events і об’єднаний лог виводу stdout/stderr у `.artifacts/qa-e2e/...`. - - За замовчуванням виводить прогрес і застосовує жорсткий timeout запуску через `OPENCLAW_QA_MATRIX_TIMEOUT_MS` (типово 30 хвилин). Очищення обмежується `OPENCLAW_QA_MATRIX_CLEANUP_TIMEOUT_MS`, а повідомлення про збої містять команду відновлення `docker compose ... down --remove-orphans`. + - Checkout репозиторію завантажують вбудований раннер напряму; окремий крок + встановлення plugin не потрібен. + - Налаштовує трьох тимчасових користувачів Matrix (`driver`, `sut`, `observer`) плюс одну приватну кімнату, а потім запускає дочірній QA gateway з реальним plugin Matrix як транспортом SUT. + - За замовчуванням використовує зафіксований стабільний образ Tuwunel `ghcr.io/matrix-construct/tuwunel:v1.5.1`. Перевизначайте через `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE`, якщо потрібно протестувати інший образ. + - Matrix не надає спільні прапори джерела облікових даних, оскільки лайн локально створює тимчасових користувачів. + - Записує звіт Matrix QA, summary, observed-events artifact і комбінований лог виводу stdout/stderr у `.artifacts/qa-e2e/...`. + - За замовчуванням виводить прогрес і застосовує жорсткий timeout виконання через `OPENCLAW_QA_MATRIX_TIMEOUT_MS` (типово 30 хвилин). Очищення обмежується `OPENCLAW_QA_MATRIX_CLEANUP_TIMEOUT_MS`, а помилки містять команду відновлення `docker compose ... down --remove-orphans`. - `pnpm openclaw qa telegram` - - Запускає live QA lane Telegram проти реальної приватної групи, використовуючи токени ботів driver і SUT з env. - - Потребує `OPENCLAW_QA_TELEGRAM_GROUP_ID`, `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` і `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`. Ідентифікатор групи має бути числовим ідентифікатором чату Telegram. - - Підтримує `--credential-source convex` для спільних пулінгових облікових даних. Типово використовуйте режим env або встановіть `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`, щоб увімкнути пулінгові lease. - - Повертає ненульовий код виходу, якщо будь-який сценарій завершується помилкою. Використовуйте `--allow-failures`, якщо вам потрібні артефакти без коду виходу з помилкою. - - Потребує двох різних ботів у тій самій приватній групі, причому бот SUT має надавати ім’я користувача Telegram. - - Для стабільного спостереження bot-to-bot увімкніть Bot-to-Bot Communication Mode у `@BotFather` для обох ботів і переконайтеся, що бот driver може спостерігати трафік ботів у групі. - - Записує звіт Telegram QA, підсумок і артефакт observed-messages у `.artifacts/qa-e2e/...`. Сценарії з відповідями включають RTT від запиту на відправлення driver до спостережуваної відповіді SUT. + - Запускає live QA-лайн Telegram проти реальної приватної групи, використовуючи токени bot driver і SUT з env. + - Потребує `OPENCLAW_QA_TELEGRAM_GROUP_ID`, `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` і `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`. ID групи має бути числовим Telegram chat id. + - Підтримує `--credential-source convex` для спільних пулових облікових даних. За замовчуванням використовуйте режим env або встановіть `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`, щоб увімкнути пулові lease. + - Завершується з ненульовим кодом, якщо будь-який сценарій зазнав невдачі. Використовуйте `--allow-failures`, якщо + вам потрібні артефакти без коду завершення з помилкою. + - Потребує двох різних bot в одній приватній групі, причому bot SUT має мати Telegram username. + - Для стабільного спостереження bot-to-bot увімкніть Bot-to-Bot Communication Mode у `@BotFather` для обох bot і переконайтеся, що bot driver може спостерігати трафік bot у групі. + - Записує звіт Telegram QA, summary і observed-messages artifact у `.artifacts/qa-e2e/...`. Сценарії з відповідями включають RTT від запиту на надсилання driver до спостереженої відповіді SUT. -Live transport lane використовують один стандартний контракт, щоб нові транспорти не розходилися в поведінці: +Live transport-лайни мають спільний стандартний контракт, щоб нові транспорти не розходилися: -`qa-channel` залишається широким синтетичним набором QA і не входить до матриці покриття live transport. +`qa-channel` залишається широким синтетичним QA-набором і не входить до матриці покриття live +transport. -| Lane | Canary | Блокування згадувань | Блок allowlist | Відповідь верхнього рівня | Відновлення після перезапуску | Подальша відповідь у треді | Ізоляція тредів | Спостереження за реакціями | Команда довідки | -| -------- | ------ | -------------------- | -------------- | ------------------------- | ----------------------------- | -------------------------- | --------------- | -------------------------- | --------------- | -| Matrix | x | x | x | x | x | x | x | x | | -| Telegram | x | | | | | | | | x | +| Лайн | Canary | Гейтінг згадок | Блокування allowlist | Відповідь верхнього рівня | Відновлення після перезапуску | Подальше повідомлення в треді | Ізоляція тредів | Спостереження реакцій | Команда help | +| ------- | ------ | -------------- | -------------------- | ------------------------- | ----------------------------- | ----------------------------- | --------------- | --------------------- | ------------ | +| Matrix | x | x | x | x | x | x | x | x | | +| Telegram | x | | | | | | | | x | ### Спільні облікові дані Telegram через Convex (v1) Коли для `openclaw qa telegram` увімкнено `--credential-source convex` (або `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`), -QA lab отримує ексклюзивну lease із пулу на базі Convex, надсилає Heartbeat -для цієї lease, поки lane працює, і звільняє lease під час завершення роботи. +QA lab отримує ексклюзивний lease із пулу на базі Convex, надсилає Heartbeat +для цього lease, поки виконується лайн, і звільняє lease під час завершення роботи. Еталонний scaffold проєкту Convex: - `qa/convex-credential-broker/` -Обов’язкові змінні env: +Обов’язкові env-змінні: - `OPENCLAW_QA_CONVEX_SITE_URL` (наприклад, `https://your-deployment.convex.site`) - Один секрет для вибраної ролі: @@ -251,7 +254,7 @@ QA lab отримує ексклюзивну lease із пулу на базі C - CLI: `--credential-role maintainer|ci` - Типове значення env: `OPENCLAW_QA_CREDENTIAL_ROLE` (типово `ci` у CI, інакше `maintainer`) -Необов’язкові змінні env: +Необов’язкові env-змінні: - `OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS` (типово `1200000`) - `OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS` (типово `30000`) @@ -261,12 +264,12 @@ QA lab отримує ексклюзивну lease із пулу на базі C - `OPENCLAW_QA_CREDENTIAL_OWNER_ID` (необов’язковий trace id) - `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` дозволяє loopback `http://` URL Convex лише для локальної розробки. -У звичайній роботі `OPENCLAW_QA_CONVEX_SITE_URL` має використовувати `https://`. +У звичайному режимі `OPENCLAW_QA_CONVEX_SITE_URL` має використовувати `https://`. -Адміністративні команди maintainer (додавання/видалення/список пулу) потребують +Адміністраторські команди maintainer (додати/видалити/перелічити пул) потребують саме `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`. -CLI-хелпери для maintainer: +Допоміжні CLI-команди для maintainer: ```bash pnpm openclaw qa credentials doctor @@ -275,9 +278,10 @@ pnpm openclaw qa credentials list --kind telegram pnpm openclaw qa credentials remove --credential-id ``` -Перед live-запусками використовуйте `doctor`, щоб перевірити URL сайту Convex, секрети broker, -префікс endpoint, HTTP timeout і досяжність admin/list без виведення -значень секретів. Використовуйте `--json` для машинозчитуваного виводу в скриптах і CI-утилітах. +Перед live-запусками використовуйте `doctor`, щоб перевірити URL сайту Convex, секрети +broker, префікс endpoint, HTTP timeout і доступність admin/list без виведення +значень секретів. Використовуйте `--json` для машиночитаного виводу в скриптах і CI +утилітах. Типовий контракт endpoint (`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): @@ -297,7 +301,7 @@ pnpm openclaw qa credentials remove --credential-id - `POST /admin/remove` (лише секрет maintainer) - Запит: `{ credentialId, actorId }` - Успіх: `{ status: "ok", changed, credential }` - - Захист від активної lease: `{ status: "error", code: "LEASE_ACTIVE", ... }` + - Захист від активного lease: `{ status: "error", code: "LEASE_ACTIVE", ... }` - `POST /admin/list` (лише секрет maintainer) - Запит: `{ kind?, status?, includePayload?, limit? }` - Успіх: `{ status: "ok", credentials, count }` @@ -305,60 +309,60 @@ pnpm openclaw qa credentials remove --credential-id Форма payload для типу Telegram: - `{ groupId: string, driverToken: string, sutToken: string }` -- `groupId` має бути рядком із числовим ідентифікатором чату Telegram. -- `admin/add` перевіряє цю форму для `kind: "telegram"` і відхиляє некоректні payload. +- `groupId` має бути рядком із числовим Telegram chat id. +- `admin/add` валідує цю форму для `kind: "telegram"` і відхиляє некоректні payload. ### Додавання каналу до QA -Додавання каналу до системи markdown QA вимагає рівно двох речей: +Додавання каналу до markdown-системи QA потребує рівно двох речей: -1. Transport adapter для каналу. -2. Набір сценаріїв, який перевіряє контракт каналу. +1. Транспортного адаптера для каналу. +2. Пакета сценаріїв, який перевіряє контракт каналу. -Не додавайте новий кореневий QA-командний простір верхнього рівня, якщо спільний хост `qa-lab` -може керувати цим потоком. +Не додавайте новий кореневий QA-командний простір верхнього рівня, якщо спільний хост `qa-lab` може +керувати цим потоком. -`qa-lab` відповідає за спільну механіку хоста: +`qa-lab` керує спільною механікою хоста: -- кореневий простір команд `openclaw qa` -- запуск і завершення набору -- concurrency workers -- запис артефактів -- генерацію звітів -- виконання сценаріїв -- alias сумісності для старіших сценаріїв `qa-channel` +- коренем команди `openclaw qa` +- запуском і завершенням набору +- конкурентністю worker +- записом артефактів +- генерацією звітів +- виконанням сценаріїв +- compatibility aliases для старих сценаріїв `qa-channel` -Runner plugins відповідають за транспортний контракт: +Plugin раннера керують транспортним контрактом: - як `openclaw qa ` монтується під спільним коренем `qa` -- як gateway налаштовується для цього транспорту +- як налаштовується gateway для цього транспорту - як перевіряється готовність - як інжектуються вхідні події - як спостерігаються вихідні повідомлення -- як надаються транскрипти й нормалізований стан транспорту -- як виконуються дії, забезпечені транспортом -- як обробляються транспортно-специфічне скидання або очищення +- як надаються transcript і нормалізований стан транспорту +- як виконуються дії на базі транспорту +- як обробляється transport-specific reset або cleanup -Мінімальний поріг впровадження нового каналу: +Мінімальний поріг впровадження для нового каналу: -1. Залишайте `qa-lab` власником спільного кореня `qa`. -2. Реалізуйте transport runner на спільному seam хоста `qa-lab`. -3. Залишайте транспортно-специфічну механіку всередині runner plugin або harness каналу. -4. Монтуйте runner як `openclaw qa ` замість реєстрації конкуруючої кореневої команди. - Runner plugins мають оголошувати `qaRunners` у `openclaw.plugin.json` і експортувати відповідний масив `qaRunnerCliRegistrations` із `runtime-api.ts`. - Залишайте `runtime-api.ts` легким; ліниве виконання CLI і runner має залишатися за окремими entrypoint. +1. Залиште `qa-lab` власником спільного кореня `qa`. +2. Реалізуйте транспортний раннер на спільному seam хоста `qa-lab`. +3. Зберігайте transport-specific механіку всередині Plugin раннера або harness каналу. +4. Монтуйте раннер як `openclaw qa `, а не реєструйте конкуруючий кореневий command. + Plugin раннера мають оголошувати `qaRunners` у `openclaw.plugin.json` і експортувати відповідний масив `qaRunnerCliRegistrations` з `runtime-api.ts`. + Зберігайте `runtime-api.ts` легким; lazy CLI і виконання раннера мають залишатися за окремими entrypoint. 5. Створюйте або адаптуйте markdown-сценарії в тематичних каталогах `qa/scenarios/`. -6. Для нових сценаріїв використовуйте generic helpers. -7. Зберігайте чинні alias сумісності, якщо репозиторій не виконує навмисну міграцію. +6. Для нових сценаріїв використовуйте загальні scenario helper. +7. Зберігайте наявні compatibility aliases працездатними, якщо тільки репозиторій не виконує навмисну міграцію. -Правило прийняття рішень суворе: +Правило прийняття рішення суворе: - Якщо поведінку можна один раз виразити в `qa-lab`, розміщуйте її в `qa-lab`. -- Якщо поведінка залежить від одного транспорту каналу, залишайте її в runner plugin або harness цього Plugin. -- Якщо сценарію потрібна нова можливість, яку може використати більше ніж один канал, додавайте generic helper замість специфічної для каналу гілки в `suite.ts`. -- Якщо поведінка має сенс лише для одного транспорту, залишайте сценарій транспортно-специфічним і явно позначайте це в контракті сценарію. +- Якщо поведінка залежить від одного транспортного каналу, зберігайте її в Plugin цього раннера або в harness plugin. +- Якщо сценарію потрібна нова можливість, яку може використовувати більш ніж один канал, додайте загальний helper замість channel-specific гілки в `suite.ts`. +- Якщо поведінка має сенс лише для одного транспорту, зберігайте сценарій transport-specific і явно позначайте це в контракті сценарію. -Для нових сценаріїв бажані назви generic helper такі: +Бажані назви загальних helper для нових сценаріїв: - `waitForTransportReady` - `waitForChannelReady` @@ -373,7 +377,7 @@ Runner plugins відповідають за транспортний контр - `formatTransportTranscript` - `resetTransport` -Alias сумісності залишаються доступними для наявних сценаріїв, зокрема: +Compatibility aliases залишаються доступними для наявних сценаріїв, зокрема: - `waitForQaChannelReady` - `waitForOutboundMessage` @@ -381,159 +385,156 @@ Alias сумісності залишаються доступними для н - `formatConversationTranscript` - `resetBus` -Нова робота з каналами має використовувати назви generic helper. -Alias сумісності існують, щоб уникнути міграції типу flag day, а не як модель -для створення нових сценаріїв. +Нова робота з каналами має використовувати загальні назви helper. +Compatibility aliases існують, щоб уникнути міграції одним днем, а не як модель для +створення нових сценаріїв. ## Набори тестів (що де запускається) -Сприймайте набори як «зростання реалізму» (і зростання флакiв/вартості): +Сприймайте набори як «зростання реалістичності» (і зростання нестабільності/вартості): ### Unit / integration (типово) - Команда: `pnpm test` -- Конфігурація: нетаргетовані запуски використовують набір шардів `vitest.full-*.config.ts` і можуть розгортати багатопроєктні шарди в конфігурації для окремих проєктів для паралельного планування -- Файли: інвентарі core/unit у `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts` і whitelist node-тести `ui`, покриті `vitest.unit.config.ts` +- Config: нетаргетовані запуски використовують набір shard `vitest.full-*.config.ts` і можуть розгортати multi-project shard у конфігурації для кожного проєкту для паралельного планування +- Файли: core/unit inventory у `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts` і whitelist тести `ui` для node, які покриває `vitest.unit.config.ts` - Обсяг: - Чисті unit-тести - - In-process integration-тести (автентифікація gateway, маршрутизація, інструменти, парсинг, конфігурація) + - In-process integration-тести (auth gateway, маршрутизація, tooling, парсинг, config) - Детерміновані регресії для відомих багів - Очікування: - - Запускаються в CI + - Запускається в CI - Реальні ключі не потрібні - - Мають бути швидкими й стабільними + - Має бути швидким і стабільним - + - - Нетаргетований `pnpm test` запускає дванадцять менших конфігурацій шардів (`core-unit-fast`, `core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) замість одного гігантського native root-project процесу. Це зменшує піковий RSS на завантажених машинах і не дає роботі auto-reply/extension виснажувати нерелевантні набори. - - `pnpm test --watch` усе ще використовує native root-граф проєктів `vitest.config.ts`, тому що багатошардовий цикл watch непрактичний. - - `pnpm test`, `pnpm test:watch` і `pnpm test:perf:imports` спочатку маршрутизують явні цілі файлів/каталогів через scoped lane, тому `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` уникає повної вартості запуску root project. - - `pnpm test:changed` розгортає змінені git-шляхи в ті самі scoped lane, коли diff торкається лише source/test файлів, які можна маршрутизувати; редагування config/setup усе ще повертаються до широкого повторного запуску root project. - - `pnpm check:changed` — це звичайний розумний локальний gate для вузьких змін. Він класифікує diff на core, core tests, extensions, extension tests, apps, docs, release metadata, live Docker tooling і tooling, а потім запускає відповідні lane typecheck/lint/test. Зміни публічного Plugin SDK і plugin-contract включають один прохід валідації extension, тому що extensions залежать від цих контрактів core. Підвищення версії лише в release metadata запускають цільові перевірки version/config/root-dependency замість повного набору, із захистом, який відхиляє зміни package поза полем version верхнього рівня. - - Редагування harness live Docker ACP запускають сфокусований локальний gate: shell-синтаксис для live Docker auth-скриптів, dry-run планувальника live Docker, unit-тести bind ACP і тести extension ACPX. Зміни `package.json` включаються лише тоді, коли diff обмежений `scripts["test:docker:live-*"]`; редагування dependency, export, version та іншої package-поверхні все ще використовують ширші перевірки. - - Unit-тести з легкими імпортами з agents, commands, plugins, helper auto-reply, `plugin-sdk` та подібних чистих утилітних ділянок маршрутизуються через lane `unit-fast`, який пропускає `test/setup-openclaw-runtime.ts`; файли зі станом/важким runtime залишаються на наявних lane. - - Вибрані helper source-файли `plugin-sdk` і `commands` також зіставляють запуски в режимі changed з явними sibling-тестами в цих легких lane, тож редагування helper уникають повторного запуску повного важкого набору для цього каталогу. - - `auto-reply` має окремі кошики для helper верхнього рівня core, integration-тестів верхнього рівня `reply.*` і піддерева `src/auto-reply/reply/**`. У CI піддерево reply додатково ділиться на шарди agent-runner, dispatch і commands/state-routing, щоб один кошик із важкими імпортами не забирав увесь Node tail. + - Нетаргетований `pnpm test` запускає дванадцять менших shard-конфігурацій (`core-unit-fast`, `core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) замість одного гігантського процесу native root-project. Це зменшує піковий RSS на завантажених машинах і не дає роботі auto-reply/extension виснажувати не пов’язані набори. + - `pnpm test --watch` як і раніше використовує граф проєктів native root `vitest.config.ts`, оскільки цикл спостереження з кількома shard непрактичний. + - `pnpm test`, `pnpm test:watch` і `pnpm test:perf:imports` спочатку маршрутизують явні цілі файлів/каталогів через scoped-лайни, тому `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` не сплачує повну ціну запуску root project. + - `pnpm test:changed` розгортає змінені шляхи git у ті самі scoped-лайни, коли diff торкається лише routable вихідних/тестових файлів; редагування config/setup, як і раніше, повертаються до широкого повторного запуску root-project. + - `pnpm check:changed` — це звичайний розумний локальний gate для вузької роботи. Він класифікує diff на core, тести core, extensions, тести extension, apps, docs, метадані релізу, live Docker tooling і tooling, а потім запускає відповідні лайни typecheck/lint/test. Зміни публічного Plugin SDK і plugin-contract включають один validation-прохід extension, оскільки extensions залежать від цих контрактів core. Оновлення версій лише в metadata релізу запускають цільові перевірки version/config/root-dependency замість повного набору, із захистом, який відхиляє зміни package поза полем version верхнього рівня. + - Редагування harness live Docker ACP запускають фокусований локальний gate: shell syntax для скриптів auth live Docker, dry-run планувальника live Docker, unit-тести ACP bind і тести extension ACPX. Зміни `package.json` включаються лише тоді, коли diff обмежений `scripts["test:docker:live-*"]`; редагування dependency, export, version та інших поверхонь package, як і раніше, використовують ширші guard. + - Import-light unit-тести з agents, commands, plugins, helper auto-reply, `plugin-sdk` та подібних чистих utility-ділянок маршрутизуються через лайн `unit-fast`, який пропускає `test/setup-openclaw-runtime.ts`; stateful/runtime-heavy файли залишаються в наявних лайнах. + - Вибрані helper-вихідні файли `plugin-sdk` і `commands` також зіставляють запуски в режимі changed з явними sibling-тестами в цих light-лайнах, тож редагування helper уникають повторного запуску повного важкого набору для цього каталогу. + - `auto-reply` має окремі bucket для helper core верхнього рівня, integration-тестів `reply.*` верхнього рівня та піддерева `src/auto-reply/reply/**`. CI додатково розділяє піддерево reply на shard agent-runner, dispatch і commands/state-routing, щоб один import-heavy bucket не контролював увесь хвіст Node. - - Коли ви змінюєте входи виявлення message-tool або runtime context Compaction, - зберігайте обидва рівні покриття. - - Додавайте сфокусовані helper-регресії для чистих меж маршрутизації та нормалізації. - - Підтримуйте в здоровому стані integration-набори embedded runner: + - Коли ви змінюєте вхідні дані виявлення message-tool або runtime context Compaction, зберігайте обидва рівні покриття. + - Додавайте фокусовані helper-регресії для чистих меж маршрутизації та нормалізації. + - Підтримуйте справність integration-наборів embedded runner: `src/agents/pi-embedded-runner/compact.hooks.test.ts`, `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` і `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`. - - Ці набори перевіряють, що scoped id і поведінка Compaction усе ще проходять - через реальні шляхи `run.ts` / `compact.ts`; лише helper-тести - не є достатньою заміною для цих integration-шляхів. + - Ці набори перевіряють, що scoped id і поведінка Compaction, як і раніше, проходять + через реальні шляхи `run.ts` / `compact.ts`; самі лише helper-тести не є + достатньою заміною для цих integration-шляхів. - + - - Базова конфігурація Vitest типово використовує `threads`. - - Спільна конфігурація Vitest фіксує `isolate: false` і використовує - неізольований runner у root projects, e2e і live configs. - - Кореневий UI lane зберігає своє налаштування `jsdom` і optimizer, але також працює на - спільному неізольованому runner. - - Кожен шард `pnpm test` успадковує ті самі типові значення `threads` + `isolate: false` - зі спільної конфігурації Vitest. + - Базовий config Vitest типово використовує `threads`. + - Спільний config Vitest фіксує `isolate: false` і використовує + non-isolated runner для root project, e2e і live config. + - Кореневий лайн UI зберігає свій `jsdom` setup і optimizer, але також запускається на + спільному non-isolated runner. + - Кожен shard `pnpm test` успадковує ті самі типові значення `threads` + `isolate: false` + зі спільного config Vitest. - `scripts/run-vitest.mjs` типово додає `--no-maglev` для дочірніх Node-процесів Vitest, щоб зменшити churn компіляції V8 під час великих локальних запусків. - Установіть `OPENCLAW_VITEST_ENABLE_MAGLEV=1`, щоб порівняти зі стандартною + Встановіть `OPENCLAW_VITEST_ENABLE_MAGLEV=1`, щоб порівняти зі стандартною поведінкою V8. - - `pnpm changed:lanes` показує, які архітектурні lane запускає diff. - - Pre-commit hook виконує лише форматування. Він повторно індексує відформатовані файли і + - `pnpm changed:lanes` показує, які архітектурні лайни запускає diff. + - Pre-commit hook виконує лише форматування. Він повторно додає форматовані файли в stage і не запускає lint, typecheck або тести. - - Явно запускайте `pnpm check:changed` перед передаванням або push, коли + - Явно запускайте `pnpm check:changed` перед передачею або push, коли вам потрібен розумний локальний gate. Зміни публічного Plugin SDK і plugin-contract - включають один прохід валідації extension. - - `pnpm test:changed` маршрутизує через scoped lane, коли змінені шляхи - однозначно зіставляються з меншим набором. + включають один validation-прохід extension. + - `pnpm test:changed` маршрутизує через scoped-лайни, коли змінені шляхи + чітко відповідають меншому набору. - `pnpm test:max` і `pnpm test:changed:max` зберігають ту саму поведінку маршрутизації, - лише з вищим лімітом workers. - - Автоматичне масштабування локальних workers навмисно є консервативним і знижує навантаження, - коли середнє навантаження хоста вже високе, тож кілька одночасних - запусків Vitest типово завдають менше шкоди. - - Базова конфігурація Vitest позначає файли projects/config як - `forceRerunTriggers`, щоб повторні запуски в режимі changed залишалися коректними, - коли змінюється зв’язування тестів. - - Конфігурація зберігає `OPENCLAW_VITEST_FS_MODULE_CACHE` увімкненим на підтримуваних - хостах; установіть `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`, якщо вам потрібне + лише з вищою межею worker. + - Автомасштабування локальних worker навмисно консервативне і знижує навантаження, + коли середнє навантаження хоста вже високе, тому кілька одночасних + запусків Vitest за замовчуванням завдають менше шкоди. + - Базовий config Vitest позначає файли project/config як + `forceRerunTriggers`, щоб повторні запуски в режимі changed залишалися коректними + при зміні wiring тестів. + - Config зберігає `OPENCLAW_VITEST_FS_MODULE_CACHE` увімкненим на підтримуваних + хостах; встановіть `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`, якщо вам потрібне одне явне розташування кешу для прямого профілювання. - - `pnpm test:perf:imports` вмикає звітність Vitest про тривалість імпорту плюс - вивід import-breakdown. - - `pnpm test:perf:imports:changed` обмежує той самий режим профілювання + - `pnpm test:perf:imports` вмикає звітування Vitest про тривалість import, а також + вивід деталізації import. + - `pnpm test:perf:imports:changed` обмежує той самий вигляд профілювання файлами, зміненими відносно `origin/main`. - - Дані часу шардів записуються в `.artifacts/vitest-shard-timings.json`. - Запуски цілої конфігурації використовують шлях конфігурації як ключ; шарди CI - з include-pattern додають ім’я шарда, щоб відфільтровані шарди можна було + - Дані про час виконання shard записуються в `.artifacts/vitest-shard-timings.json`. + Запуски всього config використовують шлях config як ключ; shard CI з include-pattern + додають ім’я shard, щоб відфільтровані shard можна було відстежувати окремо. - - Коли один гарячий тест усе ще витрачає більшу частину часу на стартові імпорти, - тримайте важкі залежності за вузьким локальним seam `*.runtime.ts` і мокуйте - цей seam напряму замість глибокого імпорту runtime helper лише - для передачі їх через `vi.mock(...)`. + - Коли один гарячий тест усе ще витрачає більшість часу на startup import, + тримайте важкі dependency за вузьким локальним seam `*.runtime.ts` і напряму мокуйте + цей seam замість deep-import runtime helper лише для того, щоб передати їх через `vi.mock(...)`. - `pnpm test:perf:changed:bench -- --ref ` порівнює маршрутизований - `test:changed` з native шляхом root project для цього закоміченого - diff і виводить wall time плюс macOS max RSS. - - `pnpm test:perf:changed:bench -- --worktree` виконує бенчмарк поточного - брудного дерева, маршрутизуючи список змінених файлів через - `scripts/test-projects.mjs` і кореневу конфігурацію Vitest. - - `pnpm test:perf:profile:main` записує CPU-профіль main thread для - накладних витрат запуску та трансформації Vitest/Vite. - - `pnpm test:perf:profile:runner` записує профілі CPU+heap runner для - unit-набору з вимкненим паралелізмом файлів. + `test:changed` з native шляхом root-project для цього закоміченого diff і виводить wall time плюс macOS max RSS. + - `pnpm test:perf:changed:bench -- --worktree` бенчмаркує поточне брудне дерево, + маршрутизуючи список змінених файлів через + `scripts/test-projects.mjs` і root config Vitest. + - `pnpm test:perf:profile:main` записує CPU profile головного потоку для + startup і transform overhead у Vitest/Vite. + - `pnpm test:perf:profile:runner` записує CPU+heap profile раннера для + unit-набору з вимкненим file parallelism. -### Стабільність (gateway) +### Стабільність (Gateway) - Команда: `pnpm test:stability:gateway` -- Конфігурація: `vitest.gateway.config.ts`, примусово один worker +- Config: `vitest.gateway.config.ts`, примусово один worker - Обсяг: - Запускає реальний loopback Gateway з увімкненою діагностикою за замовчуванням - - Пропускає синтетичне навантаження повідомленнями gateway, пам’яттю та великими payload через шлях діагностичних подій - - Запитує `diagnostics.stability` через WS RPC Gateway - - Покриває helper персистентності diagnostic stability bundle - - Перевіряє, що recorder залишається обмеженим, синтетичні зразки RSS лишаються в межах бюджету тиску, а глибини черг на сесію повертаються до нуля + - Пропускає синтетичне навантаження повідомлень gateway, пам’яті та великих payload через шлях діагностичних подій + - Виконує запит до `diagnostics.stability` через Gateway WS RPC + - Покриває helper збереження diagnostic stability bundle + - Перевіряє, що recorder залишається обмеженим, синтетичні вибірки RSS не перевищують бюджет тиску, а глибина черги для кожної сесії знову спадає до нуля - Очікування: - Безпечно для CI і без ключів - - Вузький lane для подальшого опрацювання регресій стабільності, а не заміна повного набору Gateway + - Вузький лайн для подальшого опрацювання регресій стабільності, а не заміна повного набору Gateway ### E2E (gateway smoke) - Команда: `pnpm test:e2e` -- Конфігурація: `vitest.e2e.config.ts` -- Файли: `src/**/*.e2e.test.ts`, `test/**/*.e2e.test.ts` і bundled-plugin E2E-тести в `extensions/` +- Config: `vitest.e2e.config.ts` +- Файли: `src/**/*.e2e.test.ts`, `test/**/*.e2e.test.ts` і E2E-тести bundled-plugin у `extensions/` - Типові параметри runtime: - Використовує Vitest `threads` з `isolate: false`, як і решта репозиторію. - - Використовує адаптивну кількість workers (CI: до 2, локально: 1 за замовчуванням). - - За замовчуванням працює в тихому режимі, щоб зменшити накладні витрати на консольний I/O. + - Використовує adaptive worker (CI: до 2, локально: типово 1). + - За замовчуванням запускається в silent mode, щоб зменшити накладні витрати на console I/O. - Корисні перевизначення: - - `OPENCLAW_E2E_WORKERS=` щоб примусово задати кількість workers (обмежено 16). - - `OPENCLAW_E2E_VERBOSE=1` щоб знову ввімкнути докладний консольний вивід. + - `OPENCLAW_E2E_WORKERS=`, щоб примусово задати кількість worker (обмежено 16). + - `OPENCLAW_E2E_VERBOSE=1`, щоб знову ввімкнути докладний вивід у console. - Обсяг: - - Наскрізна поведінка gateway із кількома інстансами - - Поверхні WebSocket/HTTP, pairинг Node і важча мережева взаємодія + - End-to-end поведінка gateway з кількома екземплярами + - Поверхні WebSocket/HTTP, pairing Node і важче мережеве навантаження - Очікування: - - Запускається в CI (коли увімкнено в pipeline) + - Запускається в CI (коли ввімкнено в pipeline) - Реальні ключі не потрібні - - Має більше рухомих частин, ніж unit-тести (може бути повільнішим) + - Має більше рухомих частин, ніж unit-тести (може бути повільніше) ### E2E: smoke OpenShell backend @@ -541,53 +542,53 @@ Alias сумісності існують, щоб уникнути міграц - Файл: `extensions/openshell/src/backend.e2e.test.ts` - Обсяг: - Запускає ізольований Gateway OpenShell на хості через Docker - - Створює sandbox із тимчасового локального Dockerfile - - Перевіряє OpenShell backend OpenClaw через реальні `sandbox ssh-config` + SSH exec - - Перевіряє канонічну для remote поведінку файлової системи через fs bridge sandbox + - Створює sandbox з тимчасового локального Dockerfile + - Виконує backend OpenShell в OpenClaw через реальні `sandbox ssh-config` + SSH exec + - Перевіряє remote-canonical поведінку файлової системи через sandbox fs bridge - Очікування: - - Лише за бажанням; не входить до типового запуску `pnpm test:e2e` - - Потребує локального CLI `openshell` і справного демона Docker - - Використовує ізольовані `HOME` / `XDG_CONFIG_HOME`, а потім знищує test gateway і sandbox + - Лише opt-in; не є частиною типового запуску `pnpm test:e2e` + - Потребує локальний CLI `openshell` і працездатний Docker daemon + - Використовує ізольовані `HOME` / `XDG_CONFIG_HOME`, після чого знищує test gateway і sandbox - Корисні перевизначення: - - `OPENCLAW_E2E_OPENSHELL=1`, щоб увімкнути тест під час ручного запуску ширшого набору e2e - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`, щоб указати нестандартний CLI-бінарник або wrapper-скрипт + - `OPENCLAW_E2E_OPENSHELL=1`, щоб увімкнути тест під час ручного запуску ширшого e2e-набору + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`, щоб вказати нестандартний двійковий файл CLI або wrapper script ### Live (реальні провайдери + реальні моделі) - Команда: `pnpm test:live` -- Конфігурація: `vitest.live.config.ts` -- Файли: `src/**/*.live.test.ts`, `test/**/*.live.test.ts` і bundled-plugin live-тести в `extensions/` +- Config: `vitest.live.config.ts` +- Файли: `src/**/*.live.test.ts`, `test/**/*.live.test.ts` і live-тести bundled-plugin у `extensions/` - Типово: **увімкнено** через `pnpm test:live` (встановлює `OPENCLAW_LIVE_TEST=1`) - Обсяг: - - «Чи справді цей провайдер/модель _сьогодні_ працює з реальними обліковими даними?» - - Виявляє зміни формату провайдера, особливості виклику інструментів, проблеми автентифікації та поведінку rate limit + - «Чи цей провайдер/модель справді працює _сьогодні_ з реальними обліковими даними?» + - Виявлення змін формату провайдера, особливостей виклику інструментів, проблем auth і поведінки rate limit - Очікування: - - За задумом нестабільні для CI (реальні мережі, реальні політики провайдерів, квоти, відмови) - - Коштують грошей / використовують rate limit + - За задумом не є стабільним для CI (реальні мережі, реальні політики провайдерів, квоти, збої) + - Коштує грошей / використовує rate limit - Краще запускати звужені підмножини, а не «все» -- Live-запуски підключають `~/.profile`, щоб підхопити відсутні API-ключі. +- Live-запуски підвантажують `~/.profile`, щоб отримати відсутні API key. - За замовчуванням live-запуски все одно ізолюють `HOME` і копіюють матеріали config/auth у тимчасовий test home, щоб unit-fixture не могли змінити ваш реальний `~/.openclaw`. -- Установлюйте `OPENCLAW_LIVE_USE_REAL_HOME=1` лише тоді, коли вам навмисно потрібно, щоб live-тести використовували ваш реальний домашній каталог. -- `pnpm test:live` тепер за замовчуванням працює в тихішому режимі: він зберігає вивід прогресу `[live] ...`, але пригнічує додаткове повідомлення про `~/.profile` і вимикає логи bootstrap Gateway/шум Bonjour. Установіть `OPENCLAW_LIVE_TEST_QUIET=0`, якщо хочете повернути повні startup-логи. -- Ротація API-ключів (залежно від провайдера): установіть `*_API_KEYS` у форматі з комами/крапками з комою або `*_API_KEY_1`, `*_API_KEY_2` (наприклад, `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) або перевизначення для конкретного live-запуску через `OPENCLAW_LIVE_*_KEY`; тести повторюють спробу у відповідь на rate limit. +- Встановлюйте `OPENCLAW_LIVE_USE_REAL_HOME=1` лише тоді, коли навмисно потрібно, щоб live-тести використовували ваш реальний home-каталог. +- `pnpm test:live` тепер за замовчуванням працює в тихішому режимі: він зберігає вивід прогресу `[live] ...`, але приглушує додаткове повідомлення `~/.profile` і вимикає bootstrap-логи gateway/шум Bonjour. Встановіть `OPENCLAW_LIVE_TEST_QUIET=0`, якщо хочете повернути повні startup-логи. +- Ротація API key (залежно від провайдера): встановіть `*_API_KEYS` у форматі comma/semicolon або `*_API_KEY_1`, `*_API_KEY_2` (наприклад `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) чи використайте перевизначення для live через `OPENCLAW_LIVE_*_KEY`; тести повторюють спробу у відповідь на rate limit. - Вивід прогресу/Heartbeat: - - Live-набори тепер виводять рядки прогресу в stderr, щоб довгі виклики провайдера було видно як активні, навіть коли перехоплення консолі Vitest працює тихо. - - `vitest.live.config.ts` вимикає перехоплення консолі Vitest, тому рядки прогресу провайдера/gateway одразу транслюються під час live-запусків. - - Налаштовуйте Heartbeat direct-model через `OPENCLAW_LIVE_HEARTBEAT_MS`. + - Live-набори тепер виводять рядки прогресу в stderr, тож довгі виклики провайдера залишаються видимо активними, навіть коли перехоплення console у Vitest тихе. + - `vitest.live.config.ts` вимикає перехоплення console у Vitest, щоб рядки прогресу провайдера/gateway одразу передавалися під час live-запусків. + - Налаштовуйте Heartbeat для direct-model через `OPENCLAW_LIVE_HEARTBEAT_MS`. - Налаштовуйте Heartbeat gateway/probe через `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS`. -## Який набір запускати? +## Який набір мені запускати? -Використовуйте цю таблицю рішень: +Скористайтеся цією таблицею рішень: - Редагуєте логіку/тести: запускайте `pnpm test` (і `pnpm test:coverage`, якщо змінили багато) -- Торкаєтеся мережевої взаємодії gateway / протоколу WS / pairингy: додайте `pnpm test:e2e` -- Налагоджуєте «мій бот не працює» / збої, специфічні для провайдера / виклик інструментів: запускайте звужений `pnpm test:live` +- Торкаєтеся мережевої взаємодії gateway / WS protocol / pairing: додайте `pnpm test:e2e` +- Налагоджуєте «мій bot не працює» / збої, специфічні для провайдера / виклик інструментів: запускайте звужений `pnpm test:live` -## Live-тести (які торкаються мережі) +## Live (мережеві) тести -Для live-матриці моделей, smoke-тестів CLI backend, smoke-тестів ACP, harness Codex app-server -і всіх live-тестів медіапровайдерів (Deepgram, BytePlus, ComfyUI, image, +Для live matrix моделей, smoke CLI backend, smoke ACP, harness app-server Codex +і всіх live-тестів media-provider (Deepgram, BytePlus, ComfyUI, image, music, video, media harness) — а також обробки облікових даних для live-запусків — див. [Тестування — live-набори](/uk/help/testing-live). @@ -595,158 +596,159 @@ music, video, media harness) — а також обробки облікових Ці ранери Docker поділяються на дві категорії: -- Ранери live-моделей: `test:docker:live-models` і `test:docker:live-gateway` запускають лише відповідний live-файл із ключем профілю всередині Docker-образу репозиторію (`src/agents/models.profiles.live.test.ts` і `src/gateway/gateway-models.profiles.live.test.ts`), монтують ваш локальний каталог config і workspace (і підключають `~/.profile`, якщо він змонтований). Відповідні локальні entrypoint — `test:live:models-profiles` і `test:live:gateway-profiles`. -- Docker live-ранери типово мають меншу верхню межу smoke-перевірок, щоб повний Docker-прогін залишався практичним: +- Ранери live-моделей: `test:docker:live-models` і `test:docker:live-gateway` запускають лише відповідний live-файл для свого profile-key всередині Docker-образу репозиторію (`src/agents/models.profiles.live.test.ts` і `src/gateway/gateway-models.profiles.live.test.ts`), монтують ваш локальний каталог config і workspace (і підвантажують `~/.profile`, якщо його змонтовано). Відповідні локальні entrypoint — `test:live:models-profiles` і `test:live:gateway-profiles`. +- Ранери Docker live за замовчуванням мають меншу межу smoke, щоб повний Docker-прохід залишався практичним: `test:docker:live-models` типово використовує `OPENCLAW_LIVE_MAX_MODELS=12`, а `test:docker:live-gateway` типово використовує `OPENCLAW_LIVE_GATEWAY_SMOKE=1`, `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`, `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000` і - `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Перевизначайте ці змінні env, коли - вам явно потрібне більше вичерпне сканування. -- `test:docker:all` один раз збирає live Docker-образ через `test:docker:live-build`, один раз пакує OpenClaw як npm tarball, а потім збирає/повторно використовує два образи `scripts/e2e/Dockerfile`. Базовий образ — це лише раннер Node/Git для lane встановлення/оновлення/залежностей Plugin; ці lane монтують попередньо зібраний tarball. Функціональний образ встановлює той самий tarball у `/app` для lane функціональності built-app. Агрегований запуск використовує зважений локальний планувальник: `OPENCLAW_DOCKER_ALL_PARALLELISM` керує слотами процесів, а обмеження ресурсів не дають усім важким lane live, npm-install і multi-service стартувати одночасно. Типові значення — 10 слотів, `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=6`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=8` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`; налаштовуйте `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` або `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT` лише тоді, коли Docker-хост має більше запасу ресурсів. Ранер типово виконує Docker preflight, видаляє застарілі контейнери OpenClaw E2E, виводить статус кожні 30 секунд, зберігає час успішних lane у `.artifacts/docker-tests/lane-timings.json` і використовує ці часові дані, щоб у наступних запусках спочатку стартували довші lane. Використовуйте `OPENCLAW_DOCKER_ALL_DRY_RUN=1`, щоб вивести зважений маніфест lane без збирання або запуску Docker. -- Контейнерні smoke-ранери: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:npm-onboard-channel-agent`, `test:docker:update-channel-switch`, `test:docker:session-runtime-context`, `test:docker:agents-delete-shared-workspace`, `test:docker:gateway-network`, `test:docker:browser-cdp-snapshot`, `test:docker:mcp-channels`, `test:docker:pi-bundle-mcp-tools`, `test:docker:cron-mcp-cleanup`, `test:docker:plugins`, `test:docker:plugin-update` і `test:docker:config-reload` запускають один або більше реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня. + `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Перевизначайте ці env-змінні, коли + вам явно потрібен більший вичерпний прохід. +- `test:docker:all` один раз збирає live Docker-образ через `test:docker:live-build`, один раз пакує OpenClaw як npm tarball через `scripts/package-openclaw-for-docker.mjs`, а потім збирає/повторно використовує два образи `scripts/e2e/Dockerfile`. Базовий образ — це лише раннер Node/Git для лайнів install/update/plugin-dependency; ці лайни монтують попередньо зібраний tarball. Функціональний образ встановлює той самий tarball у `/app` для лайнів функціональності зібраного застосунку. Визначення Docker-лайнів містяться в `scripts/lib/docker-e2e-scenarios.mjs`; логіка planner міститься в `scripts/lib/docker-e2e-plan.mjs`; `scripts/test-docker-all.mjs` виконує вибраний план. Агрегатор використовує зважений локальний scheduler: `OPENCLAW_DOCKER_ALL_PARALLELISM` керує слотами процесів, а ліміти ресурсів не дають усім важким live-, npm-install- і multi-service-лайнам стартувати одночасно. Типові значення: 10 слотів, `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`; налаштовуйте `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` або `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT` лише тоді, коли Docker-хост має більший запас ресурсів. Раннер за замовчуванням виконує Docker preflight, видаляє застарілі контейнери OpenClaw E2E, виводить статус кожні 30 секунд, зберігає час виконання успішних лайнів у `.artifacts/docker-tests/lane-timings.json` і використовує ці дані, щоб у наступних запусках спочатку стартували довші лайни. Використовуйте `OPENCLAW_DOCKER_ALL_DRY_RUN=1`, щоб вивести зважений маніфест лайнів без збирання або запуску Docker, або `node scripts/test-docker-all.mjs --plan-json`, щоб вивести план CI для вибраних лайнів, потреб package/image і облікових даних. +- Контейнерні smoke-ранери: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:npm-onboard-channel-agent`, `test:docker:update-channel-switch`, `test:docker:session-runtime-context`, `test:docker:agents-delete-shared-workspace`, `test:docker:gateway-network`, `test:docker:browser-cdp-snapshot`, `test:docker:mcp-channels`, `test:docker:pi-bundle-mcp-tools`, `test:docker:cron-mcp-cleanup`, `test:docker:plugins`, `test:docker:plugin-update` і `test:docker:config-reload` запускають один або кілька реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня. -Docker-ранери live-моделей також bind-монтують лише потрібні CLI auth home (або всі підтримувані, якщо запуск не звужено), а потім копіюють їх у домашній каталог контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени без зміни auth-store на хості: +Docker-ранери live-моделей також bind-mount лише потрібні auth-home для CLI (або всі підтримувані, якщо запуск не звужений), а потім копіюють їх у home контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени без зміни auth-store хоста: - Прямі моделі: `pnpm test:docker:live-models` (скрипт: `scripts/test-live-models-docker.sh`) -- ACP bind smoke: `pnpm test:docker:live-acp-bind` (скрипт: `scripts/test-live-acp-bind-docker.sh`; типово покриває Claude, Codex і Gemini, із суворим покриттям Droid/OpenCode через `pnpm test:docker:live-acp-bind:droid` і `pnpm test:docker:live-acp-bind:opencode`) -- CLI backend smoke: `pnpm test:docker:live-cli-backend` (скрипт: `scripts/test-live-cli-backend-docker.sh`) -- Smoke harness Codex app-server: `pnpm test:docker:live-codex-harness` (скрипт: `scripts/test-live-codex-harness-docker.sh`) +- Smoke ACP bind: `pnpm test:docker:live-acp-bind` (скрипт: `scripts/test-live-acp-bind-docker.sh`; за замовчуванням покриває Claude, Codex і Gemini, із суворим покриттям Droid/OpenCode через `pnpm test:docker:live-acp-bind:droid` і `pnpm test:docker:live-acp-bind:opencode`) +- Smoke CLI backend: `pnpm test:docker:live-cli-backend` (скрипт: `scripts/test-live-cli-backend-docker.sh`) +- Smoke harness app-server Codex: `pnpm test:docker:live-codex-harness` (скрипт: `scripts/test-live-codex-harness-docker.sh`) - Gateway + dev agent: `pnpm test:docker:live-gateway` (скрипт: `scripts/test-live-gateway-models-docker.sh`) -- Open WebUI live smoke: `pnpm test:docker:openwebui` (скрипт: `scripts/e2e/openwebui-docker.sh`) -- Wizard onboarding (TTY, повний scaffolding): `pnpm test:docker:onboard` (скрипт: `scripts/e2e/onboard-docker.sh`) -- Smoke onboarding/channel/agent через npm tarball: `pnpm test:docker:npm-onboard-channel-agent` глобально встановлює запакований tarball OpenClaw у Docker, налаштовує OpenAI через onboarding env-ref плюс Telegram за замовчуванням, перевіряє, що doctor відновлює активовані runtime deps Plugin, і виконує один змоканий хід агента OpenAI. Повторно використовуйте попередньо зібраний tarball через `OPENCLAW_NPM_ONBOARD_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, пропустіть перебудову на хості через `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` або перемкніть канал через `OPENCLAW_NPM_ONBOARD_CHANNEL=discord`. -- Smoke перемикання каналу оновлення: `pnpm test:docker:update-channel-switch` глобально встановлює запакований tarball OpenClaw у Docker, перемикається з пакета `stable` на git `dev`, перевіряє, що збережений канал і Plugin працюють після оновлення, потім перемикається назад на пакет `stable` і перевіряє статус оновлення. -- Smoke runtime context сесії: `pnpm test:docker:session-runtime-context` перевіряє збереження транскрипту прихованого runtime context плюс відновлення doctor для уражених дубльованих гілок prompt-rewrite. -- Smoke глобального встановлення Bun: `bash scripts/e2e/bun-global-install-smoke.sh` пакує поточне дерево, встановлює його через `bun install -g` в ізольованому home і перевіряє, що `openclaw infer image providers --json` повертає bundled image providers замість зависання. Повторно використовуйте попередньо зібраний tarball через `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, пропустіть збірку на хості через `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` або скопіюйте `dist/` зі зібраного Docker-образу через `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local`. -- Docker smoke інсталятора: `bash scripts/test-install-sh-docker.sh` спільно використовує один npm cache у своїх контейнерах root, update і direct-npm. Smoke оновлення типово використовує npm `latest` як стабільну базову версію перед оновленням до tarball-кандидата. Перевірки інсталятора без root зберігають ізольований npm cache, щоб записи кешу, створені root, не маскували поведінку user-local install. Установіть `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache`, щоб повторно використовувати кеш root/update/direct-npm у локальних повторних запусках. +- Live smoke Open WebUI: `pnpm test:docker:openwebui` (скрипт: `scripts/e2e/openwebui-docker.sh`) +- Майстер onboarding (TTY, повне scaffolding): `pnpm test:docker:onboard` (скрипт: `scripts/e2e/onboard-docker.sh`) +- Smoke onboarding/channel/agent через npm tarball: `pnpm test:docker:npm-onboard-channel-agent` глобально встановлює упакований tarball OpenClaw у Docker, налаштовує OpenAI через onboarding env-ref плюс Telegram за замовчуванням, перевіряє, що doctor відновлює активовані runtime dependency plugin, і виконує один замоканий хід агента OpenAI. Повторно використовуйте попередньо зібраний tarball через `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, пропустіть перебудову хоста через `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` або змініть канал через `OPENCLAW_NPM_ONBOARD_CHANNEL=discord`. +- Smoke перемикання каналу оновлення: `pnpm test:docker:update-channel-switch` глобально встановлює упакований tarball OpenClaw у Docker, перемикається з package `stable` на git `dev`, перевіряє, що збережений канал і plugin після оновлення працюють, потім перемикається назад на package `stable` і перевіряє статус оновлення. +- Smoke runtime context сесії: `pnpm test:docker:session-runtime-context` перевіряє збереження transcript прихованого runtime context, а також відновлення doctor для уражених дубльованих гілок prompt-rewrite. +- Smoke глобального встановлення Bun: `bash scripts/e2e/bun-global-install-smoke.sh` пакує поточне дерево, встановлює його через `bun install -g` в ізольованому home і перевіряє, що `openclaw infer image providers --json` повертає bundled image provider замість зависання. Повторно використовуйте попередньо зібраний tarball через `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, пропустіть збирання хоста через `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` або скопіюйте `dist/` із зібраного Docker-образу через `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local`. +- Installer Docker smoke: `bash scripts/test-install-sh-docker.sh` використовує спільний npm cache для контейнерів root, update і direct-npm. Smoke оновлення за замовчуванням використовує npm `latest` як стабільну базу перед оновленням до candidate tarball. Перевірки installer без root зберігають ізольований npm cache, щоб записи cache, які належать root, не маскували поведінку локального встановлення користувача. Встановіть `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache`, щоб повторно використовувати cache root/update/direct-npm між локальними повторними запусками. - Install Smoke у CI пропускає дубльоване пряме глобальне оновлення npm через `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1`; запускайте скрипт локально без цього env, коли потрібне покриття прямого `npm install -g`. -- CLI smoke спільного workspace для видалення agents: `pnpm test:docker:agents-delete-shared-workspace` (скрипт: `scripts/e2e/agents-delete-shared-workspace-docker.sh`) типово збирає образ root Dockerfile, підготовлює два agents з одним workspace в ізольованому home контейнера, запускає `agents delete --json` і перевіряє коректний JSON та поведінку зі збереженням workspace. Повторно використовуйте образ install-smoke через `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1`. +- CLI smoke видалення спільного workspace агентів: `pnpm test:docker:agents-delete-shared-workspace` (скрипт: `scripts/e2e/agents-delete-shared-workspace-docker.sh`) за замовчуванням збирає образ root Dockerfile, створює два agent з одним workspace в ізольованому home контейнера, запускає `agents delete --json` і перевіряє коректний JSON та поведінку збереженого workspace. Повторно використовуйте образ install-smoke через `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1`. - Мережева взаємодія Gateway (два контейнери, WS auth + health): `pnpm test:docker:gateway-network` (скрипт: `scripts/e2e/gateway-network-docker.sh`) -- Smoke snapshot Browser CDP: `pnpm test:docker:browser-cdp-snapshot` (скрипт: `scripts/e2e/browser-cdp-snapshot-docker.sh`) збирає вихідний E2E-образ плюс шар Chromium, запускає Chromium із сирим CDP, виконує `browser doctor --deep` і перевіряє, що snapshot ролей CDP покривають URL посилань, елементи для кліку, підняті курсором, refs iframe і метадані frame. -- Регресія мінімального reasoning для OpenAI Responses `web_search`: `pnpm test:docker:openai-web-search-minimal` (скрипт: `scripts/e2e/openai-web-search-minimal-docker.sh`) запускає змоканий сервер OpenAI через Gateway, перевіряє, що `web_search` підвищує `reasoning.effort` з `minimal` до `low`, потім примусово викликає відхилення схеми провайдера і перевіряє, що сирі деталі з’являються в логах Gateway. -- MCP channel bridge (seeded Gateway + stdio bridge + raw smoke notification-frame Claude): `pnpm test:docker:mcp-channels` (скрипт: `scripts/e2e/mcp-channels-docker.sh`) -- Інструменти MCP пакета Pi (реальний stdio MCP server + smoke allow/deny вбудованого профілю Pi): `pnpm test:docker:pi-bundle-mcp-tools` (скрипт: `scripts/e2e/pi-bundle-mcp-tools-docker.sh`) -- Очищення MCP Cron/subagent (реальний Gateway + teardown дочірнього stdio MCP після ізольованих запусків cron і одноразового subagent): `pnpm test:docker:cron-mcp-cleanup` (скрипт: `scripts/e2e/cron-mcp-cleanup-docker.sh`) -- Plugins (smoke встановлення, встановлення/видалення ClawHub, оновлення marketplace і ввімкнення/перевірка пакета Claude): `pnpm test:docker:plugins` (скрипт: `scripts/e2e/plugins-docker.sh`) - Установіть `OPENCLAW_PLUGINS_E2E_CLAWHUB=0`, щоб пропустити live-блок ClawHub, або перевизначте типовий пакет через `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` і `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID`. +- Smoke CDP snapshot браузера: `pnpm test:docker:browser-cdp-snapshot` (скрипт: `scripts/e2e/browser-cdp-snapshot-docker.sh`) збирає вихідний E2E-образ плюс шар Chromium, запускає Chromium із сирим CDP, виконує `browser doctor --deep` і перевіряє, що snapshot ролей CDP покривають URL посилань, clickables, підняті курсором, iframe refs і метадані frame. +- Мінімальна reasoning-регресія OpenAI Responses web_search: `pnpm test:docker:openai-web-search-minimal` (скрипт: `scripts/e2e/openai-web-search-minimal-docker.sh`) запускає замоканий сервер OpenAI через Gateway, перевіряє, що `web_search` підвищує `reasoning.effort` з `minimal` до `low`, потім примусово викликає відхилення schema у провайдера і перевіряє, що сирі деталі з’являються в логах Gateway. +- MCP channel bridge (seeded Gateway + stdio bridge + smoke сирого notification-frame Claude): `pnpm test:docker:mcp-channels` (скрипт: `scripts/e2e/mcp-channels-docker.sh`) +- Інструменти MCP bundle Pi (реальний stdio MCP-сервер + smoke allow/deny для вбудованого профілю Pi): `pnpm test:docker:pi-bundle-mcp-tools` (скрипт: `scripts/e2e/pi-bundle-mcp-tools-docker.sh`) +- Очищення Cron/subagent MCP (реальний Gateway + завершення дочірнього stdio MCP після ізольованого cron і одноразових запусків subagent): `pnpm test:docker:cron-mcp-cleanup` (скрипт: `scripts/e2e/cron-mcp-cleanup-docker.sh`) +- Plugins (smoke встановлення, встановлення/видалення ClawHub, оновлення marketplace і ввімкнення/перевірка Claude-bundle): `pnpm test:docker:plugins` (скрипт: `scripts/e2e/plugins-docker.sh`) + Встановіть `OPENCLAW_PLUGINS_E2E_CLAWHUB=0`, щоб пропустити live-блок ClawHub, або перевизначте package за замовчуванням через `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` і `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID`. - Smoke незмінного оновлення Plugin: `pnpm test:docker:plugin-update` (скрипт: `scripts/e2e/plugin-update-unchanged-docker.sh`) - Smoke метаданих перезавантаження config: `pnpm test:docker:config-reload` (скрипт: `scripts/e2e/config-reload-source-docker.sh`) -- Runtime deps bundled Plugin: `pnpm test:docker:bundled-channel-deps` типово збирає невеликий Docker-образ раннера, один раз збирає і пакує OpenClaw на хості, а потім монтує цей tarball у кожний сценарій встановлення Linux. Повторно використовуйте образ через `OPENCLAW_SKIP_DOCKER_BUILD=1`, пропустіть перебудову на хості після свіжої локальної збірки через `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` або вкажіть на наявний tarball через `OPENCLAW_BUNDLED_CHANNEL_PACKAGE_TGZ=/path/to/openclaw-*.tgz`. Повний Docker-агрегат попередньо пакує цей tarball один раз, а потім шардує перевірки bundled channel на незалежні lane, включно з окремими lane оновлення для Telegram, Discord, Slack, Feishu, memory-lancedb і ACPX. Використовуйте `OPENCLAW_BUNDLED_CHANNELS=telegram,slack`, щоб звузити матрицю каналів під час прямого запуску bundled lane, або `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx`, щоб звузити сценарій оновлення. Lane також перевіряє, що `channels..enabled=false` і `plugins.entries..enabled=false` пригнічують відновлення runtime-dependency через doctor. -- Звужуйте runtime deps bundled Plugin під час ітерації, вимикаючи нерелевантні сценарії, наприклад: +- Runtime dependency bundled plugin: `pnpm test:docker:bundled-channel-deps` за замовчуванням збирає невеликий образ Docker runner, один раз збирає та пакує OpenClaw на хості, а потім монтує цей tarball у кожен сценарій Linux install. Повторно використовуйте образ через `OPENCLAW_SKIP_DOCKER_BUILD=1`, пропустіть перебудову хоста після свіжого локального збирання через `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` або вкажіть на наявний tarball через `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz`. Повний Docker-агрегатор попередньо пакує цей tarball один раз, а потім розбиває перевірки bundled channel на незалежні лайни, включно з окремими лайнами оновлення для Telegram, Discord, Slack, Feishu, memory-lancedb і ACPX. Використовуйте `OPENCLAW_BUNDLED_CHANNELS=telegram,slack`, щоб звузити matrix channel під час прямого запуску bundled-лайну, або `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx`, щоб звузити сценарій оновлення. Лайн також перевіряє, що `channels..enabled=false` і `plugins.entries..enabled=false` пригнічують відновлення doctor/runtime dependency. +- Звужуйте runtime dependency bundled plugin під час ітерацій, вимикаючи непов’язані сценарії, наприклад: `OPENCLAW_BUNDLED_CHANNEL_SCENARIOS=0 OPENCLAW_BUNDLED_CHANNEL_UPDATE_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_ROOT_OWNED_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_SETUP_ENTRY_SCENARIO=0 pnpm test:docker:bundled-channel-deps`. -Щоб вручну попередньо зібрати й повторно використати спільний функціональний образ: +Щоб вручну попередньо зібрати і повторно використовувати спільний функціональний образ: ```bash OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local pnpm test:docker:e2e-build OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels ``` -Перевизначення образів для конкретних наборів, як-от `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE`, усе ще мають пріоритет, якщо встановлені. Коли `OPENCLAW_SKIP_DOCKER_BUILD=1` вказує на віддалений спільний образ, скрипти завантажують його, якщо його ще немає локально. Тести Docker для QR та інсталятора зберігають власні Dockerfile, оскільки вони перевіряють поведінку пакета/встановлення, а не спільний runtime built-app. +Перевизначення образу для конкретного набору, як-от `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE`, усе ще мають пріоритет, якщо їх установлено. Коли `OPENCLAW_SKIP_DOCKER_BUILD=1` вказує на віддалений спільний образ, скрипти завантажують його, якщо він ще не локальний. QR- і installer-тести Docker зберігають власні Dockerfile, оскільки вони перевіряють поведінку package/install, а не спільний runtime зібраного застосунку. -Docker-ранери live-моделей також bind-монтують поточний checkout лише для читання і -розміщують його в тимчасовому workdir усередині контейнера. Це зберігає runtime- -образ компактним, але все одно запускає Vitest точно на вашому локальному source/config. -Крок staging пропускає великі локальні кеші та результати збірки застосунків, як-от -`.pnpm-store`, `.worktrees`, `__openclaw_vitest__`, а також локальні для застосунку каталоги `.build` або +Docker-ранери live-моделей також монтують поточний checkout лише для читання і +розгортають його в тимчасовий workdir усередині контейнера. Це дозволяє зберегти +runtime-образ компактним, водночас запускаючи Vitest точно на вашому локальному source/config. +Під час етапу розгортання пропускаються великі локальні кеші та артефакти збирання застосунків, як-от +`.pnpm-store`, `.worktrees`, `__openclaw_vitest__` і локальні для застосунків каталоги `.build` або виводу Gradle, щоб Docker live-запуски не витрачали хвилини на копіювання артефактів, специфічних для машини. -Вони також встановлюють `OPENCLAW_SKIP_CHANNELS=1`, щоб live-проби gateway не запускали -реальні workers каналів Telegram/Discord тощо всередині контейнера. -`test:docker:live-models` усе ще запускає `pnpm test:live`, тому також передавайте -`OPENCLAW_LIVE_GATEWAY_*`, коли вам потрібно звузити або виключити live-покриття gateway із цього Docker lane. -`test:docker:openwebui` — це smoke-перевірка сумісності вищого рівня: вона запускає -контейнер Gateway OpenClaw з увімкненими HTTP endpoint, сумісними з OpenAI, -запускає закріплений контейнер Open WebUI проти цього gateway, виконує вхід через +Вони також встановлюють `OPENCLAW_SKIP_CHANNELS=1`, щоб live-probe Gateway не запускали +реальні worker каналів Telegram/Discord тощо всередині контейнера. +`test:docker:live-models` усе ще запускає `pnpm test:live`, тож також передавайте +`OPENCLAW_LIVE_GATEWAY_*`, коли потрібно звузити або виключити покриття gateway +live із цього Docker-лайну. +`test:docker:openwebui` — це smoke перевірка сумісності вищого рівня: вона запускає +контейнер gateway OpenClaw з увімкненими HTTP-endpoint, сумісними з OpenAI, +запускає зафіксований контейнер Open WebUI проти цього gateway, входить через Open WebUI, перевіряє, що `/api/models` надає `openclaw/default`, а потім надсилає -реальний запит чату через проксі Open WebUI `/api/chat/completions`. -Перший запуск може бути помітно повільнішим, тому що Docker може знадобитися -завантажити образ Open WebUI, а Open WebUI може потребувати завершення власного cold-start налаштування. -Цей lane очікує придатний ключ live-моделі, а `OPENCLAW_PROFILE_FILE` -(типово `~/.profile`) — основний спосіб надати його в Dockerized-запусках. +реальний chat-запит через проксі `/api/chat/completions` Open WebUI. +Перший запуск може бути помітно повільнішим, оскільки Docker може потребувати завантаження +образу Open WebUI, а сам Open WebUI може ще завершувати власне налаштування cold-start. +Цей лайн очікує наявність придатного live-ключа моделі, а `OPENCLAW_PROFILE_FILE` +(типово `~/.profile`) є основним способом надати його в Dockerized-запусках. Успішні запуски виводять невеликий JSON payload на кшталт `{ "ok": true, "model": "openclaw/default", ... }`. -`test:docker:mcp-channels` навмисно є детермінованим і не потребує -реального облікового запису Telegram, Discord або iMessage. Він запускає seeded Gateway -контейнер, стартує другий контейнер, який запускає `openclaw mcp serve`, а потім -перевіряє виявлення маршрутизованих розмов, читання транскриптів, метадані вкладень, -поведінку черги live-подій, маршрутизацію вихідної відправки та сповіщення у стилі Claude про канал + +`test:docker:mcp-channels` навмисно детермінований і не потребує +реального облікового запису Telegram, Discord або iMessage. Він запускає +контейнер Gateway із початковим станом, запускає другий контейнер, який піднімає `openclaw mcp serve`, а потім +перевіряє виявлення маршрутизованих розмов, читання transcript, метадані вкладень, +поведінку черги live-подій, маршрутизацію вихідного надсилання та сповіщення у стилі Claude про канал + дозволи через реальний stdio MCP bridge. Перевірка сповіщень -безпосередньо досліджує сирі stdio MCP frame, тож smoke перевіряє те, що міст -справді виводить, а не лише те, що випадково показує конкретний client SDK. +безпосередньо аналізує сирі stdio MCP frame, тож smoke перевіряє саме те, що +bridge реально надсилає, а не лише те, що випадково показує конкретний SDK клієнта. `test:docker:pi-bundle-mcp-tools` є детермінованим і не потребує -ключа live-моделі. Він збирає Docker-образ репозиторію, запускає реальний stdio MCP probe server -усередині контейнера, матеріалізує цей сервер через вбудований runtime Pi bundle -MCP, виконує інструмент, а потім перевіряє, що `coding` і `messaging` зберігають +live-ключа моделі. Він збирає Docker-образ репозиторію, запускає реальний stdio MCP probe server +усередині контейнера, матеріалізує цей сервер через вбудований runtime bundle +MCP для Pi, виконує інструмент, а потім перевіряє, що `coding` і `messaging` зберігають інструменти `bundle-mcp`, тоді як `minimal` і `tools.deny: ["bundle-mcp"]` їх відфільтровують. -`test:docker:cron-mcp-cleanup` є детермінованим і не потребує ключа live-моделі. -Він запускає seeded Gateway із реальним stdio MCP probe server, виконує -ізольований Cron-хід і одноразовий дочірній хід `/subagents spawn`, а потім перевіряє, -що дочірній MCP-процес завершується після кожного запуску. +`test:docker:cron-mcp-cleanup` є детермінованим і не потребує live-ключа моделі. +Він запускає Gateway із початковим станом із реальним stdio MCP probe server, виконує +ізольований хід cron і одноразовий дочірній хід `/subagents spawn`, а потім перевіряє, +що дочірній процес MCP завершується після кожного запуску. -Ручний smoke plain-language thread для ACP (не CI): +Ручна smoke перевірка plain-language thread для ACP (не CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- Зберігайте цей скрипт для сценаріїв регресії/налагодження. Він може знову знадобитися для перевірки маршрутизації ACP thread, тому не видаляйте його. +- Зберігайте цей скрипт для workflow регресії/налагодження. Він може знову знадобитися для перевірки маршрутизації thread ACP, тож не видаляйте його. -Корисні змінні env: +Корисні env-змінні: - `OPENCLAW_CONFIG_DIR=...` (типово: `~/.openclaw`) монтується в `/home/node/.openclaw` - `OPENCLAW_WORKSPACE_DIR=...` (типово: `~/.openclaw/workspace`) монтується в `/home/node/.openclaw/workspace` -- `OPENCLAW_PROFILE_FILE=...` (типово: `~/.profile`) монтується в `/home/node/.profile` і підключається перед запуском тестів -- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1`, щоб перевіряти лише змінні env, підключені з `OPENCLAW_PROFILE_FILE`, використовуючи тимчасові каталоги config/workspace і без зовнішніх монтувань CLI auth -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (типово: `~/.cache/openclaw/docker-cli-tools`) монтується в `/home/node/.npm-global` для кешованих установлень CLI всередині Docker -- Зовнішні каталоги/файли CLI auth у `$HOME` монтуються лише для читання під `/host-auth...`, а потім копіюються в `/home/node/...` перед запуском тестів +- `OPENCLAW_PROFILE_FILE=...` (типово: `~/.profile`) монтується в `/home/node/.profile` і підвантажується перед запуском тестів +- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1`, щоб перевіряти лише env-змінні, підвантажені з `OPENCLAW_PROFILE_FILE`, використовуючи тимчасові каталоги config/workspace і без монтування auth зовнішнього CLI +- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (типово: `~/.cache/openclaw/docker-cli-tools`) монтується в `/home/node/.npm-global` для кешованих встановлень CLI усередині Docker +- Зовнішні auth-каталоги/файли CLI в `$HOME` монтуються лише для читання під `/host-auth...`, а потім копіюються в `/home/node/...` перед запуском тестів - Типові каталоги: `.minimax` - Типові файли: `~/.codex/auth.json`, `~/.codex/config.toml`, `.claude.json`, `~/.claude/.credentials.json`, `~/.claude/settings.json`, `~/.claude/settings.local.json` - Звужені запуски провайдерів монтують лише потрібні каталоги/файли, виведені з `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` - - Перевизначайте вручну через `OPENCLAW_DOCKER_AUTH_DIRS=all`, `OPENCLAW_DOCKER_AUTH_DIRS=none` або список через кому, як-от `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` + - Перевизначайте вручну через `OPENCLAW_DOCKER_AUTH_DIRS=all`, `OPENCLAW_DOCKER_AUTH_DIRS=none` або список через кому, наприклад `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` - `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...`, щоб звузити запуск -- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...`, щоб фільтрувати провайдерів усередині контейнера -- `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб повторно використовувати наявний образ `openclaw:local-live` для повторних запусків, які не потребують перебудови -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб переконатися, що облікові дані надходять зі сховища profile (а не з env) +- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...`, щоб відфільтрувати провайдерів усередині контейнера +- `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб повторно використати наявний образ `openclaw:local-live` для повторних запусків, яким не потрібне нове збирання +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб переконатися, що облікові дані беруться зі сховища profile (а не з env) - `OPENCLAW_OPENWEBUI_MODEL=...`, щоб вибрати модель, яку gateway надає для smoke Open WebUI -- `OPENCLAW_OPENWEBUI_PROMPT=...`, щоб перевизначити prompt перевірки nonce, який використовує smoke Open WebUI +- `OPENCLAW_OPENWEBUI_PROMPT=...`, щоб перевизначити nonce-check prompt, який використовує smoke Open WebUI - `OPENWEBUI_IMAGE=...`, щоб перевизначити зафіксований тег образу Open WebUI -## Перевірка документації +## Перевірка коректності документації -Після редагування документації запускайте перевірки docs: `pnpm check:docs`. -Запускайте повну перевірку anchor у Mintlify, коли вам також потрібні перевірки заголовків на сторінці: `pnpm docs:check-links:anchors`. +Запускайте перевірки docs після редагування документації: `pnpm check:docs`. +Запускайте повну перевірку anchor у Mintlify, коли також потрібні перевірки заголовків усередині сторінки: `pnpm docs:check-links:anchors`. -## Офлайн-регресія (безпечна для CI) +## Offline-регресії (безпечні для CI) Це регресії «реального pipeline» без реальних провайдерів: -- Виклик інструментів Gateway (mock OpenAI, реальний цикл gateway + agent): `src/gateway/gateway.test.ts` (випадок: "runs a mock OpenAI tool call end-to-end via gateway agent loop") -- Wizard Gateway (WS `wizard.start`/`wizard.next`, примусовий запис config + auth): `src/gateway/gateway.test.ts` (випадок: "runs wizard over ws and writes auth token config") +- Виклик інструментів Gateway (замоканий OpenAI, реальний gateway + цикл агента): `src/gateway/gateway.test.ts` (випадок: "runs a mock OpenAI tool call end-to-end via gateway agent loop") +- Майстер Gateway (WS `wizard.start`/`wizard.next`, записує config + застосовує auth): `src/gateway/gateway.test.ts` (випадок: "runs wizard over ws and writes auth token config") -## Оцінювання надійності агента (Skills) +## Оцінювання надійності агентів (Skills) -У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності агента»: +У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності агентів»: -- Mock-виклик інструментів через реальний цикл gateway + agent (`src/gateway/gateway.test.ts`). -- Наскрізні потоки wizard, які перевіряють зв’язування сесії та ефекти конфігурації (`src/gateway/gateway.test.ts`). +- Замоканий виклик інструментів через реальний gateway + цикл агента (`src/gateway/gateway.test.ts`). +- End-to-end потоки майстра, які перевіряють wiring сесії та вплив config (`src/gateway/gateway.test.ts`). -Чого все ще бракує для Skills (див. [Skills](/uk/tools/skills)): +Що все ще відсутнє для Skills (див. [Skills](/uk/tools/skills)): -- **Прийняття рішень:** коли Skills перелічені в prompt, чи вибирає агент правильний skill (або уникає нерелевантних)? -- **Відповідність вимогам:** чи читає агент `SKILL.md` перед використанням і виконує потрібні кроки/аргументи? +- **Прийняття рішень:** коли Skills перелічені в prompt, чи вибирає агент правильний Skill (або уникає нерелевантних)? +- **Відповідність:** чи читає агент `SKILL.md` перед використанням і чи виконує потрібні кроки/аргументи? - **Контракти workflow:** багатокрокові сценарії, які перевіряють порядок інструментів, перенесення історії сесії та межі sandbox. -Майбутні eval мають спершу залишатися детермінованими: +Майбутні оцінювання мають спочатку залишатися детермінованими: -- Runner сценаріїв із mock-провайдерами для перевірки викликів інструментів + порядку, читання skill-файлів і зв’язування сесії. -- Невеликий набір сценаріїв, сфокусованих на skills (використовувати чи уникати, gating, prompt injection). -- Необов’язкові live-eval (opt-in, із керуванням через env) лише після того, як буде готовий набір, безпечний для CI. +- Раннер сценаріїв із mock-провайдерами для перевірки викликів інструментів + їхнього порядку, читання skill-файлів і wiring сесії. +- Невеликий набір сценаріїв, сфокусованих на Skills (використовувати чи уникати, гейтінг, ін’єкція prompt). +- Необов’язкові live-оцінювання (opt-in, з керуванням через env) лише після того, як буде готовий безпечний для CI набір. -## Контрактні тести (форма Plugin і channel) +## Контрактні тести (форма plugin і channel) -Контрактні тести перевіряють, що кожен зареєстрований Plugin і channel відповідає своєму -інтерфейсному контракту. Вони проходять по всіх виявлених Plugin і запускають набір -перевірок форми та поведінки. Типовий unit-lane `pnpm test` навмисно -пропускає ці спільні seam- і smoke-файли; запускайте контрактні команди явно, +Контрактні тести перевіряють, що кожен зареєстрований plugin і channel відповідає своєму +контракту інтерфейсу. Вони перебирають усі виявлені plugin і запускають набір +перевірок форми та поведінки. Типовий unit-лайн `pnpm test` навмисно +пропускає ці файли спільних seam і smoke; запускайте контрактні команди явно, коли торкаєтеся спільних поверхонь channel або provider. ### Команди @@ -759,56 +761,56 @@ MCP, виконує інструмент, а потім перевіряє, що Розташовані в `src/channels/plugins/contracts/*.contract.test.ts`: -- **plugin** - Базова форма Plugin (`id`, `name`, `capabilities`) -- **setup** - Контракт wizard налаштування +- **plugin** - Базова форма plugin (id, name, capabilities) +- **setup** - Контракт майстра налаштування - **session-binding** - Поведінка прив’язки сесії - **outbound-payload** - Структура payload повідомлення - **inbound** - Обробка вхідних повідомлень - **actions** - Обробники дій channel - **threading** - Обробка ID thread -- **directory** - API каталогу/складу -- **group-policy** - Застосування групової політики +- **directory** - API directory/roster +- **group-policy** - Застосування group policy ### Контракти статусу provider Розташовані в `src/plugins/contracts/*.contract.test.ts`. - **status** - Перевірки статусу channel -- **registry** - Форма реєстру Plugin +- **registry** - Форма registry plugin ### Контракти provider Розташовані в `src/plugins/contracts/*.contract.test.ts`: - **auth** - Контракт потоку auth -- **auth-choice** - Вибір/встановлення auth +- **auth-choice** - Вибір/selection auth - **catalog** - API каталогу моделей -- **discovery** - Виявлення Plugin -- **loader** - Завантаження Plugin +- **discovery** - Виявлення plugin +- **loader** - Завантаження plugin - **runtime** - Runtime provider -- **shape** - Форма/інтерфейс Plugin -- **wizard** - Wizard налаштування +- **shape** - Форма/інтерфейс plugin +- **wizard** - Майстер налаштування ### Коли запускати - Після зміни export або subpath у plugin-sdk -- Після додавання або зміни Plugin channel або provider -- Після рефакторингу реєстрації або виявлення Plugin +- Після додавання або зміни plugin channel чи provider +- Після рефакторингу реєстрації plugin або виявлення -Контрактні тести запускаються в CI і не потребують реальних API-ключів. +Контрактні тести запускаються в CI і не потребують реальних API key. -## Додавання регресійних тестів (рекомендації) +## Додавання регресій (рекомендації) Коли ви виправляєте проблему provider/model, виявлену в live: - Додайте безпечну для CI регресію, якщо це можливо (mock/stub provider або фіксація точної трансформації форми запиту) -- Якщо проблема за своєю природою лише live (rate limit, політики auth), залишайте live-тест вузьким і opt-in через змінні env -- Віддавайте перевагу найменшому шару, який виявляє баг: - - баг перетворення/відтворення запиту provider → тест прямих моделей - - баг конвеєра сесії/історії/інструментів gateway → live smoke gateway або безпечний для CI mock-тест gateway -- Захисне обмеження обходу SecretRef: - - `src/secrets/exec-secret-ref-id-parity.test.ts` виводить одну вибіркову ціль для кожного класу SecretRef із метаданих реєстру (`listSecretTargetRegistryEntries()`), а потім перевіряє, що traversal-segment exec id відхиляються. - - Якщо ви додаєте нове сімейство цілей SecretRef з `includeInPlan` у `src/secrets/target-registry-data.ts`, оновіть `classifyTargetClass` у цьому тесті. Тест навмисно завершується помилкою для некласифікованих target id, щоб нові класи не можна було тихо пропустити. +- Якщо проблема за своєю природою стосується лише live (rate limit, політики auth), залишайте live-тест вузьким і opt-in через env-змінні +- Намагайтеся націлюватися на найменший шар, який виявляє баг: + - баг перетворення/відтворення запиту provider → тест direct models + - баг pipeline сесії/історії/інструментів gateway → smoke gateway live або безпечний для CI mock-тест gateway +- Guardrail обходу SecretRef: + - `src/secrets/exec-secret-ref-id-parity.test.ts` виводить одну вибіркову ціль для кожного класу SecretRef з metadata registry (`listSecretTargetRegistryEntries()`), а потім перевіряє, що exec id сегмента обходу відхиляються. + - Якщо ви додаєте нове сімейство цілей SecretRef `includeInPlan` у `src/secrets/target-registry-data.ts`, оновіть `classifyTargetClass` у цьому тесті. Тест навмисно завершується з помилкою для некласифікованих target id, щоб нові класи не можна було тихо пропустити. ## Пов’язане diff --git a/docs/uk/reference/test.md b/docs/uk/reference/test.md index ee8e2e3c3..534cd0c77 100644 --- a/docs/uk/reference/test.md +++ b/docs/uk/reference/test.md @@ -4,51 +4,51 @@ read_when: summary: Як запускати тести локально (`vitest`) і коли використовувати режими force/coverage title: Тести x-i18n: - generated_at: "2026-04-26T22:14:38Z" + generated_at: "2026-04-26T22:39:57Z" model: gpt-5.4 provider: openai - source_hash: 676abe8e753d49719f3bc333680e50e0a0ec9f82c5c85b5ef7c1ec55452f10ed + source_hash: 57a5eff6e46662960a9b06a1f6883bb22b3fd8598de6338b4e7da3fa1b90b492 source_path: reference/test.md workflow: 15 --- - Повний набір для тестування (набори тестів, live, Docker): [Тестування](/uk/help/testing) -- `pnpm test:force`: завершує будь-який завислий процес Gateway, що утримує типовий порт керування, а потім запускає повний набір Vitest з ізольованим портом Gateway, щоб серверні тести не конфліктували із запущеним екземпляром. Використовуйте це, коли попередній запуск Gateway залишив зайнятим порт 18789. -- `pnpm test:coverage`: запускає набір unit-тестів із покриттям V8 (через `vitest.unit.config.ts`). Це поріг unit-покриття для завантажених файлів, а не покриття всіх файлів у всьому репозиторії. Порогові значення: 70% для рядків/функцій/інструкцій і 55% для гілок. Оскільки `coverage.all` має значення false, перевірка вимірює файли, завантажені набором unit-тестів із покриттям, замість того щоб вважати кожен файл вихідного коду в розбитих lane непокритим. +- `pnpm test:force`: завершує будь-який завислий процес Gateway, який утримує типовий порт керування, а потім запускає повний набір Vitest з ізольованим портом Gateway, щоб серверні тести не конфліктували із запущеним екземпляром. Використовуйте це, коли попередній запуск Gateway залишив зайнятим порт 18789. +- `pnpm test:coverage`: запускає набір unit-тестів із покриттям V8 (через `vitest.unit.config.ts`). Це перевірка покриття unit-тестів для завантажених файлів, а не покриття всього репозиторію для всіх файлів. Порогові значення: 70% для рядків/функцій/інструкцій і 55% для гілок. Оскільки `coverage.all` має значення false, перевірка вимірює файли, завантажені набором unit-тестів із покриттям, замість того щоб вважати кожен файл вихідного коду з розділених lane без покриття. - `pnpm test:coverage:changed`: запускає unit-покриття лише для файлів, змінених відносно `origin/main`. -- `pnpm test:changed`: розгортає змінені шляхи git у scoped lane Vitest, коли diff зачіпає лише маршрутизовані файли коду/тестів. Зміни конфігурації/налаштування все одно повертаються до нативного запуску кореневих проєктів, щоб зміни в підключенні повторно широко запускали перевірки, коли це потрібно. -- `pnpm test:changed:focused`: запуск змінених тестів для внутрішнього циклу. Запускає лише точні цілі з прямих змін тестів, сусідніх файлів `*.test.ts`, явних зіставлень вихідного коду та локального графа імпортів. Широкі зміни/config/package пропускаються замість розгортання до повного fallback-запуску changed-test. -- `pnpm changed:lanes`: показує архітектурні lane, які запускаються diff-ом відносно `origin/main`. -- `pnpm check:changed`: запускає розумну перевірку changed gate для diff відносно `origin/main`. Вона запускає core-роботи з lane тестів core, роботу extensions з lane тестів extensions, зміни лише в тестах — тільки з typecheck/tests тестів, розгортає зміни в публічному Plugin SDK або plugin-contract до одного проходу валідації extension і залишає підвищення версій лише в release metadata на цільових перевірках version/config/root-dependency. -- `pnpm test`: маршрутизує явні цілі файлів/каталогів через scoped lane Vitest. Запуски без цілей використовують фіксовані групи shard і розгортаються до leaf config для локального паралельного виконання; група extensions завжди розгортається до shard config окремих extension/plugin замість одного великого процесу root-project. -- Запуски shard для повного набору, extensions і include-pattern оновлюють локальні дані часу виконання в `.artifacts/vitest-shard-timings.json`; подальші запуски всієї конфігурації використовують ці дані для балансування повільних і швидких shard. Shard CI з include-pattern додають назву shard до ключа часу, що зберігає видимість часів відфільтрованих shard без заміни даних часу повної конфігурації. Встановіть `OPENCLAW_TEST_PROJECTS_TIMINGS=0`, щоб ігнорувати локальний артефакт часу. -- Вибрані тестові файли `plugin-sdk` і `commands` тепер маршрутизуються через окремі легкі lane, які залишають лише `test/setup.ts`, а важкі випадки runtime залишаються у своїх наявних lane. -- Вихідні файли із сусідніми тестами зіставляються із цим сусіднім тестом перед fallback до ширших directory glob. Зміни helper у `test/helpers/channels` і `test/helpers/plugins` використовують локальний граф імпортів, щоб запускати тести, які імпортують ці файли, замість широкого запуску кожного shard, коли шлях залежності є точним. -- `auto-reply` тепер також розділяється на три окремі config (`core`, `top-level`, `reply`), щоб harness для reply не домінував над легшими top-level тестами status/token/helper. -- Базова конфігурація Vitest тепер типово використовує `pool: "threads"` і `isolate: false`, із увімкненим спільним неізольованим runner у всіх конфігураціях репозиторію. +- `pnpm test:changed`: розгортає змінені git-шляхи у відповідні lane Vitest, коли diff зачіпає лише маршрутизовані файли коду/тестів. Зміни конфігурації/налаштування все одно повертаються до нативного запуску кореневих проєктів, щоб зміни в обв’язці перезапускалися ширше, коли це потрібно. +- `pnpm test:changed:focused`: запуск змінених тестів для внутрішнього циклу розробки. Він запускає лише точні цілі з прямих змін у тестах, сусідніх файлів `*.test.ts`, явних відповідностей вихідного коду та локального графа імпортів. Широкі зміни, зміни конфігурації або пакетів пропускаються замість розгортання до повного резервного запуску changed-test. +- `pnpm changed:lanes`: показує архітектурні lane, які активуються diff відносно `origin/main`. +- `pnpm check:changed`: запускає розумну перевірку changed gate для diff відносно `origin/main`. Вона запускає core-роботи з core test lanes, роботу extensions з extension test lanes, зміни лише в тестах — лише з перевіркою типів тестів/тестами, розгортає зміни публічного Plugin SDK або plugin-contract до одного проходу перевірки extension і залишає підвищення версій лише в метаданих релізу на цільових перевірках версій/конфігурації/кореневих залежностей. +- `pnpm test`: спрямовує явні цілі файлів/каталогів через відповідні lane Vitest. Запуски без цілей використовують фіксовані shard-групи та розгортаються до leaf-конфігурацій для локального паралельного виконання; група extensions завжди розгортається до конфігурацій shard для кожного extension окремо, а не в один гігантський процес root-project. +- Повні запуски, запуски shards extensions і include-pattern оновлюють локальні дані часу виконання в `.artifacts/vitest-shard-timings.json`; пізніші запуски всієї конфігурації використовують ці дані, щоб збалансувати повільні й швидкі shards. CI-shards з include-pattern додають ім’я shard до ключа часу, що дозволяє зберігати видимість часу відфільтрованих shards без заміни даних часу для всієї конфігурації. Установіть `OPENCLAW_TEST_PROJECTS_TIMINGS=0`, щоб ігнорувати локальний артефакт часу. +- Вибрані тестові файли `plugin-sdk` і `commands` тепер спрямовуються через окремі легкі lane, які зберігають лише `test/setup.ts`, залишаючи ресурсоємні runtime-випадки у їхніх наявних lane. +- Вихідні файли із сусідніми тестами зіставляються з цим сусіднім тестом перед переходом до ширших glob шаблонів каталогу. Зміни helper-файлів у `test/helpers/channels` і `test/helpers/plugins` використовують локальний граф імпортів, щоб запускати тести, які їх імпортують, замість широкого запуску кожного shard, коли шлях залежності точний. +- `auto-reply` тепер також поділяється на три окремі конфігурації (`core`, `top-level`, `reply`), щоб harness для reply не домінував над легшими top-level тестами status/token/helper. +- Базова конфігурація Vitest тепер за замовчуванням використовує `pool: "threads"` і `isolate: false`, а спільний неізольований runner увімкнений у конфігураціях репозиторію. - `pnpm test:channels` запускає `vitest.channels.config.ts`. -- `pnpm test:extensions` і `pnpm test extensions` запускають усі shard extensions/plugin. Важкі channel plugin, browser plugin та OpenAI запускаються як окремі shard; інші групи plugin залишаються згрупованими. Використовуйте `pnpm test extensions/` для одного bundled lane plugin. -- `pnpm test:perf:imports`: вмикає звіти Vitest про тривалість імпорту та import-breakdown, при цьому все ще використовуючи маршрутизацію scoped lane для явних цілей файлів/каталогів. -- `pnpm test:perf:imports:changed`: те саме профілювання імпорту, але лише для файлів, змінених відносно `origin/main`. -- `pnpm test:perf:changed:bench -- --ref `: порівнює шлях routed changed-mode з нативним запуском root-project для того самого закоміченого git diff. -- `pnpm test:perf:changed:bench -- --worktree`: порівнює поточний набір змін у worktree без попереднього коміту. +- `pnpm test:extensions` і `pnpm test extensions` запускають усі shards extension/plugin. Важкі channel plugins, browser plugin та OpenAI запускаються як окремі shards; інші групи plugins залишаються пакетними. Використовуйте `pnpm test extensions/` для одного lane конкретного bundled plugin. +- `pnpm test:perf:imports`: вмикає звітування Vitest про тривалість імпорту та деталізацію імпорту, водночас і далі використовуючи маршрутизацію lane для явних цілей файлів/каталогів. +- `pnpm test:perf:imports:changed`: той самий профайлінг імпортів, але лише для файлів, змінених відносно `origin/main`. +- `pnpm test:perf:changed:bench -- --ref ` виконує бенчмарк маршрутизованого шляху в режимі changed проти нативного запуску root-project для того самого зафіксованого git diff. +- `pnpm test:perf:changed:bench -- --worktree` виконує бенчмарк поточного набору змін у worktree без попереднього коміту. - `pnpm test:perf:profile:main`: записує CPU-профіль для головного потоку Vitest (`.artifacts/vitest-main-profile`). - `pnpm test:perf:profile:runner`: записує профілі CPU + heap для unit runner (`.artifacts/vitest-runner-profile`). -- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`: послідовно запускає кожну leaf config Vitest повного набору і записує згруповані дані тривалості разом з JSON/log-артефактами для кожної config. Агент Test Performance використовує це як базову лінію перед спробами виправлення повільних тестів. -- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`: порівнює згруповані звіти після зміни, зосередженої на продуктивності. +- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`: послідовно запускає кожну leaf-конфігурацію Vitest повного набору тестів і записує згруповані дані тривалості разом з JSON/log-артефактами для кожної конфігурації. Агент продуктивності тестів використовує це як базову лінію перед спробами виправити повільні тести. +- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`: порівнює згруповані звіти після змін, спрямованих на продуктивність. - Інтеграція Gateway: вмикається через `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` або `pnpm test:gateway`. -- `pnpm test:e2e`: запускає наскрізні smoke-тести Gateway (multi-instance WS/HTTP/node pairing). Типово використовує `threads` + `isolate: false` з адаптивною кількістю workers у `vitest.e2e.config.ts`; налаштовується через `OPENCLAW_E2E_WORKERS=`, а для докладних логів встановіть `OPENCLAW_E2E_VERBOSE=1`. -- `pnpm test:live`: запускає live-тести провайдерів (minimax/zai). Потребує API-ключі та `LIVE=1` (або специфічний для провайдера `*_LIVE_TEST=1`) для зняття пропуску. -- `pnpm test:docker:all`: збирає спільний образ live-тестів, один раз пакує OpenClaw як npm tarball, збирає/повторно використовує базовий образ runner на Node/Git та функціональний образ, який встановлює цей tarball у `/app`, а потім запускає Docker smoke lane з `OPENCLAW_SKIP_DOCKER_BUILD=1` через зважений планувальник. Базовий образ (`OPENCLAW_DOCKER_E2E_BARE_IMAGE`) використовується для lane installer/update/plugin-dependency; ці lane монтують попередньо зібраний tarball замість використання скопійованих вихідних файлів репозиторію. Функціональний образ (`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`) використовується для звичайних lane функціональності зібраного застосунку. `OPENCLAW_DOCKER_ALL_PARALLELISM=` керує кількістю слотів процесів і типово дорівнює 10; `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=` керує пулом tail, чутливим до провайдерів, і типово дорівнює 10. Обмеження важких lane типово дорівнюють `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`; обмеження провайдерів типово задають один важкий lane на провайдера через `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`, `OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` і `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4`. Для потужніших хостів використовуйте `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` або `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`. Запуски lane типово розтягуються на 2 секунди, щоб уникнути шторму створення в локальному Docker daemon; перевизначте через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=`. Runner типово виконує попередню перевірку Docker, очищає застарілі контейнери OpenClaw E2E, виводить стан активних lane кожні 30 секунд, ділиться кешами CLI-інструментів провайдерів між сумісними lane, один раз повторює тимчасові збої live-провайдерів за замовчуванням (`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=`) і зберігає часи lane в `.artifacts/docker-tests/lane-timings.json` для впорядкування за принципом longest-first у наступних запусках. Використовуйте `OPENCLAW_DOCKER_ALL_DRY_RUN=1`, щоб вивести маніфест lane без запуску Docker, `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=` для налаштування виведення стану або `OPENCLAW_DOCKER_ALL_TIMINGS=0` для вимкнення повторного використання часових даних. Використовуйте `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip` лише для детермінованих/локальних lane або `OPENCLAW_DOCKER_ALL_LIVE_MODE=only` лише для lane live-провайдерів; псевдоніми пакетів — `pnpm test:docker:local:all` і `pnpm test:docker:live:all`. Режим лише live об’єднує main і tail live lane в один пул longest-first, щоб кошики провайдерів могли спільно пакувати роботу Claude, Codex і Gemini. Runner припиняє планування нових pooled lane після першої помилки, якщо не встановлено `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`, і кожен lane має резервний timeout 120 хвилин, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; вибрані live/tail lane використовують жорсткіші обмеження на рівні lane. Команди налаштування Docker для бекенду CLI мають власний timeout через `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` (типово 180). Логи кожного lane та фазові часи `summary.json` записуються в `.artifacts/docker-tests//`. -- `pnpm test:docker:browser-cdp-snapshot`: збирає контейнер source E2E на основі Chromium, запускає raw CDP та ізольований Gateway, виконує `browser doctor --deep` і перевіряє, що snapshot ролей CDP містять URL посилань, clickables, підвищені курсором, iframe refs і метадані frame. -- Live Docker probes бекенду CLI можна запускати як цільові lane, наприклад `pnpm test:docker:live-cli-backend:codex`, `pnpm test:docker:live-cli-backend:codex:resume` або `pnpm test:docker:live-cli-backend:codex:mcp`. Для Claude і Gemini є відповідні псевдоніми `:resume` і `:mcp`. -- `pnpm test:docker:openwebui`: запускає Dockerized OpenClaw + Open WebUI, входить через Open WebUI, перевіряє `/api/models`, а потім виконує реальний проксійований чат через `/api/chat/completions`. Потребує придатний ключ live-моделі (наприклад, OpenAI у `~/.profile`), завантажує зовнішній образ Open WebUI і не очікується як стабільний для CI, на відміну від звичайних наборів unit/e2e. -- `pnpm test:docker:mcp-channels`: запускає контейнер Gateway із підготовленими даними та другий клієнтський контейнер, який запускає `openclaw mcp serve`, а потім перевіряє виявлення маршрутованих розмов, читання транскриптів, метадані вкладень, поведінку черги live-подій, маршрутизацію вихідних відправлень і сповіщення про channel + дозволи в стилі Claude через реальний міст stdio. Перевірка сповіщень Claude читає сирі stdio MCP-кадри безпосередньо, щоб smoke-тест відображав те, що міст фактично надсилає. +- `pnpm test:e2e`: запускає наскрізні smoke-тести Gateway (парування WS/HTTP/node з кількома екземплярами). За замовчуванням використовує `threads` + `isolate: false` з адаптивною кількістю workers у `vitest.e2e.config.ts`; налаштовується через `OPENCLAW_E2E_WORKERS=`, а для докладних логів установіть `OPENCLAW_E2E_VERBOSE=1`. +- `pnpm test:live`: запускає live-тести провайдерів (minimax/zai). Потребує API-ключів і `LIVE=1` (або специфічного для провайдера `*_LIVE_TEST=1`), щоб зняти пропуск. +- `pnpm test:docker:all`: збирає спільний образ live-тестів, один раз пакує OpenClaw як npm tarball, збирає/повторно використовує базовий образ runner з Node/Git і функціональний образ, який встановлює цей tarball у `/app`, а потім запускає Docker smoke lanes з `OPENCLAW_SKIP_DOCKER_BUILD=1` через зважений планувальник. Базовий образ (`OPENCLAW_DOCKER_E2E_BARE_IMAGE`) використовується для lane встановлення/оновлення/залежностей plugin; ці lane монтують попередньо зібраний tarball замість використання скопійованих вихідних кодів репозиторію. Функціональний образ (`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`) використовується для звичайних lane функціональності зібраного застосунку. `scripts/package-openclaw-for-docker.mjs` — єдиний локальний/CI пакувальник пакета. Визначення Docker lane містяться в `scripts/lib/docker-e2e-scenarios.mjs`; логіка планувальника — у `scripts/lib/docker-e2e-plan.mjs`; `scripts/test-docker-all.mjs` виконує вибраний план. `node scripts/test-docker-all.mjs --plan-json` виводить CI-план, яким керує планувальник, для вибраних lane, типів образів, потреб пакета/live-image та перевірок облікових даних без збирання або запуску Docker. `OPENCLAW_DOCKER_ALL_PARALLELISM=` керує кількістю слотів процесів і за замовчуванням дорівнює 10; `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=` керує tail pool, чутливим до провайдерів, і за замовчуванням теж дорівнює 10. Обмеження важких lane за замовчуванням: `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`; обмеження провайдерів за замовчуванням — один важкий lane на провайдера через `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`, `OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` і `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4`. Використовуйте `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` або `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT` для більших хостів. Запуски lane за замовчуванням розподіляються з інтервалом 2 секунди, щоб уникнути штормів створення на локальному Docker daemon; змініть через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=`. Runner за замовчуванням виконує попередню перевірку Docker, очищає застарілі контейнери OpenClaw E2E, виводить статус активних lane кожні 30 секунд, спільно використовує кеші CLI-інструментів провайдерів між сумісними lane, за замовчуванням один раз повторює тимчасові збої live-провайдерів (`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=`) і зберігає час lane в `.artifacts/docker-tests/lane-timings.json` для впорядкування за принципом “найдовші спочатку” в наступних запусках. Використовуйте `OPENCLAW_DOCKER_ALL_DRY_RUN=1`, щоб вивести маніфест lane без запуску Docker, `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=` для налаштування частоти статусів, або `OPENCLAW_DOCKER_ALL_TIMINGS=0`, щоб вимкнути повторне використання даних часу. Використовуйте `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip` лише для детермінованих/локальних lane або `OPENCLAW_DOCKER_ALL_LIVE_MODE=only` лише для lane live-провайдерів; пакетні псевдоніми — `pnpm test:docker:local:all` і `pnpm test:docker:live:all`. Режим лише live об’єднує основні та tail live-lanes в один pool з порядком “найдовші спочатку”, щоб кошики провайдерів могли разом пакувати роботу Claude, Codex і Gemini. Runner припиняє планувати нові pooled lanes після першої помилки, якщо не встановлено `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`, а кожен lane має резервний тайм-аут 120 хвилин, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; окремі live/tail lanes використовують жорсткіші обмеження часу на lane. Команди налаштування Docker для бекенда CLI мають власний тайм-аут через `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` (за замовчуванням 180). Логи для кожного lane та `summary.json` з часом етапів записуються в `.artifacts/docker-tests//`. +- `pnpm test:docker:browser-cdp-snapshot`: збирає контейнер source E2E на базі Chromium, запускає сирий CDP і ізольований Gateway, виконує `browser doctor --deep` і перевіряє, що знімки ролей CDP містять URL посилань, clickables, підвищені курсором, iframe refs і метадані frame. +- Live Docker probes для бекенда CLI можна запускати як сфокусовані lane, наприклад `pnpm test:docker:live-cli-backend:codex`, `pnpm test:docker:live-cli-backend:codex:resume` або `pnpm test:docker:live-cli-backend:codex:mcp`. Для Claude і Gemini є відповідні псевдоніми `:resume` і `:mcp`. +- `pnpm test:docker:openwebui`: запускає Dockerized OpenClaw + Open WebUI, виконує вхід через Open WebUI, перевіряє `/api/models`, а потім запускає реальний проксійований чат через `/api/chat/completions`. Потребує придатного ключа live-моделі (наприклад, OpenAI у `~/.profile`), завантажує зовнішній образ Open WebUI і не вважається стабільним для CI так, як звичайні набори unit/e2e. +- `pnpm test:docker:mcp-channels`: запускає контейнер Gateway із підготовленими даними та другий клієнтський контейнер, який запускає `openclaw mcp serve`, а потім перевіряє виявлення маршрутизованих розмов, читання транскриптів, метадані вкладень, поведінку черги live-подій, маршрутизацію вихідного надсилання, а також сповіщення про channel і permissions у стилі Claude через реальний stdio bridge. Перевірка сповіщень Claude читає сирі stdio MCP-кадри безпосередньо, щоб smoke-тест відображав те, що bridge реально надсилає. -## Локальний PR gate +## Локальна перевірка PR -Для локальних перевірок land/gate PR запускайте: +Для локальних перевірок перед злиттям/проходженням gate PR виконайте: - `pnpm check:changed` - `pnpm check` @@ -57,7 +57,7 @@ x-i18n: - `pnpm test` - `pnpm check:docs` -Якщо `pnpm test` дає нестабільний результат на завантаженому хості, перезапустіть один раз перед тим, як вважати це регресією, а потім ізолюйте через `pnpm test `. Для хостів з обмеженою пам’яттю використовуйте: +Якщо `pnpm test` нестабільно працює на навантаженому хості, перезапустіть його один раз, перш ніж вважати це регресією, а потім ізолюйте за допомогою `pnpm test `. Для хостів з обмеженою пам’яттю використовуйте: - `OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test` - `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-cache pnpm test:changed` @@ -70,12 +70,12 @@ x-i18n: - `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10` - Необов’язкові змінні середовища: `MINIMAX_API_KEY`, `MINIMAX_BASE_URL`, `MINIMAX_MODEL`, `ANTHROPIC_API_KEY` -- Типовий prompt: “Reply with a single word: ok. No punctuation or extra text.” +- Типовий запит: “Відповідай одним словом: ok. Без розділових знаків або додаткового тексту.” Останній запуск (2025-12-31, 20 запусків): -- minimax медіана 1279ms (мін. 1114, макс. 2431) -- opus медіана 2454ms (мін. 1224, макс. 3170) +- minimax: медіана 1279 мс (мін. 1114, макс. 2431) +- opus: медіана 2454 мс (мін. 1224, макс. 3170) ## Бенчмарк запуску CLI @@ -98,31 +98,31 @@ x-i18n: - `pnpm tsx scripts/bench-cli-startup.ts --preset real --cpu-prof-dir .artifacts/cli-cpu` - `pnpm tsx scripts/bench-cli-startup.ts --json` -Presets: +Набори preset: - `startup`: `--version`, `--help`, `health`, `health --json`, `status --json`, `status` - `real`: `health`, `status`, `status --json`, `sessions`, `sessions --json`, `agents list --json`, `gateway status`, `gateway status --json`, `gateway health --json`, `config get gateway.port` -- `all`: обидва presets +- `all`: обидва набори preset -Вивід містить `sampleCount`, avg, p50, p95, min/max, розподіл exit-code/signal і підсумки max RSS для кожної команди. Необов’язкові `--cpu-prof-dir` / `--heap-prof-dir` записують профілі V8 для кожного запуску, щоб вимірювання часу та збір профілів використовували той самий harness. +Вивід містить `sampleCount`, avg, p50, p95, min/max, розподіл кодів виходу/сигналів і зведення максимального RSS для кожної команди. Необов’язкові `--cpu-prof-dir` / `--heap-prof-dir` записують профілі V8 для кожного запуску, тож вимірювання часу та захоплення профілю використовують одну й ту саму harness. -Угоди щодо збереженого виводу: +Умовні позначення для збереженого виводу: - `pnpm test:startup:bench:smoke` записує цільовий smoke-артефакт у `.artifacts/cli-startup-bench-smoke.json` -- `pnpm test:startup:bench:save` записує артефакт повного набору в `.artifacts/cli-startup-bench-all.json` з використанням `runs=5` і `warmup=1` -- `pnpm test:startup:bench:update` оновлює закомічений baseline fixture у `test/fixtures/cli-startup-bench.json` з використанням `runs=5` і `warmup=1` +- `pnpm test:startup:bench:save` записує артефакт повного набору тестів у `.artifacts/cli-startup-bench-all.json` з використанням `runs=5` і `warmup=1` +- `pnpm test:startup:bench:update` оновлює baseline fixture, що зберігається в репозиторії, у `test/fixtures/cli-startup-bench.json` з використанням `runs=5` і `warmup=1` -Закомічений fixture: +Fixture, що зберігається в репозиторії: - `test/fixtures/cli-startup-bench.json` -- Оновити через `pnpm test:startup:bench:update` -- Порівняти поточні результати з fixture через `pnpm test:startup:bench:check` +- Оновити за допомогою `pnpm test:startup:bench:update` +- Порівняти поточні результати з fixture за допомогою `pnpm test:startup:bench:check` ## Onboarding E2E (Docker) -Docker необов’язковий; це потрібно лише для containerized smoke-тестів onboarding. +Docker не є обов’язковим; це потрібно лише для контейнеризованих smoke-тестів onboarding. -Повний cold-start потік у чистому контейнері Linux: +Повний потік холодного старту в чистому Linux-контейнері: ```bash scripts/e2e/onboard-docker.sh @@ -132,7 +132,7 @@ scripts/e2e/onboard-docker.sh ## QR import smoke (Docker) -Гарантує, що підтримуваний допоміжний runtime-компонент QR завантажується в підтримуваних Docker runtime Node (типово Node 24, сумісний Node 22): +Гарантує, що підтримуваний helper runtime для QR завантажується в підтримуваних Docker runtime Node (Node 24 за замовчуванням, Node 22 сумісний): ```bash pnpm test:docker:qr @@ -141,4 +141,4 @@ pnpm test:docker:qr ## Пов’язане - [Тестування](/uk/help/testing) -- [Live-тестування](/uk/help/testing-live) +- [Тестування live](/uk/help/testing-live)