diff --git a/docs/uk/ci.md b/docs/uk/ci.md index acb36bea2..de0189f08 100644 --- a/docs/uk/ci.md +++ b/docs/uk/ci.md @@ -1,27 +1,34 @@ --- read_when: - - Вам потрібно зрозуміти, чому завдання CI було або не було запущено - - Ви налагоджуєте збої перевірок GitHub Actions -summary: Граф завдань CI, шлюзи охоплення та локальні еквіваленти команд + - Вам потрібно зрозуміти, чому завдання CI запустилося або не запустилося. + - Ви налагоджуєте збої перевірок GitHub Actions. +summary: Граф завдань CI, ворота охоплення та локальні еквіваленти команд title: Конвеєр CI x-i18n: - generated_at: "2026-04-26T21:58:21Z" + generated_at: "2026-04-26T22:14:39Z" model: gpt-5.4 provider: openai - source_hash: 3332c240435650af6f2cfe898d47bd7da8bdc58edb8dc8544699a741625d9b27 + source_hash: bad9dde51020fc3833d3848955a01af36e38e281a4c9de128b36b9553f66665e source_path: ci.md workflow: 15 --- -CI запускається при кожному пуші в `main` і при кожному pull request. Він використовує розумне визначення охоплення, щоб пропускати дорогі завдання, коли змінилися лише непов’язані частини. +CI запускається після кожного пушу в `main` і для кожного pull request. Він використовує розумне визначення охоплення, щоб пропускати дорогі завдання, коли змінено лише не пов’язані області. -QA Lab має окремі лінії CI поза основним workflow з розумним визначенням охоплення. Workflow `Parity gate` запускається для відповідних змін у PR і через ручний запуск; він збирає приватне середовище виконання QA та порівнює імітаційні agentic-паки GPT-5.5 і Opus 4.6. Workflow `QA-Lab - All Lanes` запускається щоночі в `main` і через ручний запуск; він розпаралелює імітаційний 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 перед затвердженням релізу. -Workflow `Duplicate PRs After Merge` — це ручний workflow для супровідників для очищення дублікатів після приземлення змін. За замовчуванням він працює в режимі dry-run і закриває лише явно перелічені PR, коли `apply=true`. Перш ніж змінювати стан у GitHub, він перевіряє, що приземлений PR змерджено і що кожен дублікат має або спільну згадану issue, або перетин змінених фрагментів. +Робочий процес `Duplicate PRs After Merge` — це ручний робочий процес для супровідників для очищення дублікатів після злиття. За замовчуванням він працює в режимі dry-run і закриває лише явно перелічені PR, коли `apply=true`. Перш ніж вносити зміни в GitHub, він перевіряє, що злитий PR справді об’єднано, і що кожен дублікат має або спільну згадану issue, або перекривні змінені фрагменти. -Workflow `Docs Agent` — це керована подіями лінія супроводу Codex для підтримання наявної документації у відповідності до нещодавно приземлених змін. Він не має окремого розкладу: його може запустити успішний запуск CI для пушу в `main`, зроблений не ботом, а також його можна запустити вручну. Виклики через workflow run пропускаються, якщо `main` уже змінився або якщо інший непропущений запуск Docs Agent був створений протягом останньої години. Коли він запускається, він переглядає діапазон комітів від SHA джерела попереднього непропущеного Docs Agent до поточного `main`, тому один щогодинний запуск може охопити всі зміни в main, накопичені з часу останнього проходу документації. +Робочий процес `Docs Agent` — це подієва лінія обслуговування Codex для підтримки наявної документації у відповідності до нещодавно злитих змін. Він не має окремого запуску за розкладом: його може запустити успішний неботовий CI-прохід після пушу в `main`, а також його можна запустити вручну напряму. Виклики через workflow-run пропускаються, якщо `main` уже пішла вперед або якщо за останню годину вже було створено інший непропущений запуск Docs Agent. Коли він запускається, він переглядає діапазон комітів від вихідного SHA попереднього непропущеного Docs Agent до поточної `main`, тож один щогодинний запуск може охопити всі зміни в `main`, накопичені з часу останнього проходу документації. -Workflow `Test Performance Agent` — це керована подіями лінія супроводу Codex для повільних тестів. Він не має окремого розкладу: його може запустити успішний запуск CI для пушу в `main`, зроблений не ботом, але він пропускається, якщо інший виклик через workflow run уже виконувався або виконується того ж дня за UTC. Ручний запуск обходить це денне обмеження активності. Лінія створює згрупований звіт про продуктивність Vitest для повного набору тестів, дозволяє Codex робити лише невеликі виправлення продуктивності тестів без зниження покриття замість широких рефакторингів, потім повторно запускає звіт для повного набору тестів і відхиляє зміни, які зменшують кількість тестів, що проходять, у базовому стані. Якщо в базовому стані є тести, що не проходять, Codex може виправляти лише очевидні збої, а звіт після роботи агента для повного набору тестів має пройти, перш ніж щось буде закомічено. Коли `main` змінюється до того, як пуш бота буде приземлено, лінія перебазовує перевірений патч, повторно запускає `pnpm check:changed` і повторює спробу пушу; конфліктні застарілі патчі пропускаються. Вона використовує GitHub-hosted Ubuntu, щоб дія Codex могла зберігати ту саму безпечну політику drop-sudo, що й агент документації. +Робочий процес `Test Performance Agent` — це подієва лінія обслуговування Codex для повільних тестів. Він не має окремого запуску за розкладом: його може запустити успішний неботовий CI-прохід після пушу в `main`, але він пропускається, якщо того UTC-дня інший виклик через workflow-run уже відпрацював або ще виконується. Ручний запуск обходить цю денну перевірку активності. Лінія збирає згрупований звіт про продуктивність Vitest для повного набору, дозволяє Codex вносити лише невеликі виправлення продуктивності тестів без зниження покриття замість широких рефакторингів, потім повторно запускає звіт для повного набору й відхиляє зміни, які зменшують базову кількість тестів, що проходять. Якщо в базовому стані є тести, що не проходять, Codex може виправляти лише очевидні збої, а звіт повного набору після роботи агента має проходити повністю, перш ніж щось буде закомічено. Коли `main` просувається вперед до того, як бот встигає запушити результат, лінія перебазовує перевірений патч, повторно запускає `pnpm check:changed` і повторює пуш; конфліктні застарілі патчі пропускаються. Вона використовує GitHub-hosted Ubuntu, щоб дія Codex могла зберігати ту саму безпекову модель drop-sudo, що й агент документації. ```bash gh workflow run duplicate-after-merge.yml \ @@ -33,87 +40,87 @@ gh workflow run duplicate-after-merge.yml \ ## Огляд завдань | Завдання | Призначення | Коли запускається | -| -------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------ | -| `preflight` | Визначає зміни лише в документації, змінені області охоплення, змінені розширення та будує маніфест CI | Завжди для push і PR, що не є draft | -| `security-scm-fast` | Виявлення приватних ключів і аудит workflow через `zizmor` | Завжди для push і PR, що не є draft | -| `security-dependency-audit` | Аудит production lockfile без залежностей щодо advisory npm | Завжди для push і PR, що не є draft | -| `security-fast` | Обов’язковий агрегат для швидких завдань безпеки | Завжди для push і PR, що не є draft | -| `build-artifacts` | Збирає `dist/`, Control UI, перевірки зібраних артефактів і повторно використовувані артефакти для нижчих етапів | Зміни, релевантні Node | -| `checks-fast-core` | Швидкі лінії перевірки коректності в Linux, як-от перевірки bundled/plugin-contract/protocol | Зміни, релевантні Node | -| `checks-fast-contracts-channels` | Шардовані перевірки контрактів каналів зі стабільним агрегованим результатом перевірки | Зміни, релевантні Node | -| `checks-node-extensions` | Повні шарди тестів bundled-plugin для всього набору розширень | Зміни, релевантні Node | -| `checks-node-core-test` | Шарди основних Node-тестів, без ліній каналів, bundled, контрактів і розширень | Зміни, релевантні Node | -| `extension-fast` | Цільові тести лише для змінених bundled plugins | Pull request зі змінами в розширеннях | -| `check` | Шардований еквівалент головного локального шлюзу: production types, lint, guard, test types і strict 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 | Зміни, релевантні Skills на Python | -| `checks-windows` | Специфічні для Windows лінії тестування | Зміни, релевантні Windows | -| `macos-node` | Лінія тестів TypeScript для macOS з використанням спільних зібраних артефактів | Зміни, релевантні macOS | -| `macos-swift` | Lint, збірка і тести Swift для застосунку macOS | Зміни, релевантні macOS | -| `android` | Модульні тести Android для обох варіантів плюс одна збірка debug APK | Зміни, релевантні Android | -| `test-performance-agent` | Щоденна оптимізація повільних тестів Codex після довіреної активності | Успішний main CI або ручний запуск | +| -------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------ | +| `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 або ручний запуск | ## Порядок 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`, `extension-fast` лише для PR, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`. +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`. -Логіка охоплення міститься в `scripts/ci-changed-scope.mjs` і покривається модульними тестами в `src/scripts/ci-changed-scope.test.ts`. -Зміни workflow CI перевіряють граф Node CI разом із lint для workflow, але самі по собі не примушують запускати нативні збірки Windows, Android або macOS; ці платформні лінії й надалі прив’язані до змін у вихідному коді відповідних платформ. -Зміни лише в маршрутизації CI, окремі дешеві правки фікстур core-тестів і вузькі правки helper/test-routing для контрактів плагінів використовують швидкий шлях маніфесту лише для Node: preflight, security і єдине завдання `checks-fast-core`. Цей шлях уникає build artifacts, сумісності з Node 22, контрактів каналів, повних shard-ів core, shard-ів bundled-plugin і додаткових матриць guard, коли змінені файли обмежуються поверхнями маршрутизації або helper, які швидке завдання перевіряє безпосередньо. -Перевірки Windows Node прив’язані до специфічних для Windows обгорток process/path, helper для npm/pnpm/UI runner, конфігурації package manager і поверхонь workflow CI, що запускають цю лінію; не пов’язані зміни у вихідному коді, плагінах, install-smoke і лише в тестах залишаються на Linux Node лініях, щоб не резервувати Windows worker на 16 vCPU для покриття, яке вже перевіряється звичайними test shard-ами. -Окремий workflow `install-smoke` повторно використовує той самий скрипт визначення охоплення через власне завдання `preflight`. Він розділяє smoke-покриття на `run_fast_install_smoke` і `run_full_install_smoke`. Для pull request запускається швидкий шлях для поверхонь Docker/package, змін пакетів/маніфестів bundled plugin і поверхонь core plugin/channel/gateway/Plugin SDK, які перевіряють Docker smoke jobs. Зміни лише у вихідному коді bundled plugin, лише в тестах і лише в документації не резервують Docker workers. Швидкий шлях один раз збирає образ root Dockerfile, перевіряє CLI, запускає smoke CLI `agents delete shared-workspace`, запускає container gateway-network e2e, перевіряє аргумент збірки bundled extension і запускає обмежений Docker profile bundled-plugin із сукупним таймаутом команди 240 секунд, де кожен сценарій `docker run` має власне окреме обмеження. Повний шлях зберігає покриття встановлення QR package і installer Docker/update для нічних запланованих запусків, ручних запусків, workflow-call перевірок релізу і pull request, які справді зачіпають поверхні installer/package/Docker. Пуші в `main`, включно з merge commit, не примушують повний шлях; коли логіка changed-scope на пуші вимагала б повне покриття, workflow залишає швидкий Docker smoke, а повний install smoke переносить на нічну або релізну перевірку. Повільний smoke для Bun global install image-provider окремо керується через `run_bun_global_install_smoke`; він запускається за нічним розкладом і з workflow перевірок релізу, а ручні запуски `install-smoke` можуть явно ввімкнути його, але pull request і пуші в `main` його не запускають. Тести QR і installer Docker зберігають власні Dockerfile, орієнтовані на встановлення. Локальний `test:docker:all` попередньо збирає один спільний live-test образ і два спільні built-app образи `scripts/e2e/Dockerfile`: bare image для ліній installer/update/plugin-dependency і functional image, який попередньо готує runtime dependency для bundled plugin для звичайних функціональних ліній. Планувальник вибирає образ для лінії через `OPENCLAW_DOCKER_E2E_BARE_IMAGE` і `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`, а потім запускає лінії з `OPENCLAW_SKIP_DOCKER_BUILD=1`; налаштуйте типову кількість слотів основного пулу 10 через `OPENCLAW_DOCKER_ALL_PARALLELISM`, а кількість слотів tail-пулу, чутливого до провайдера, 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 і multi-service не перевантажували Docker, поки легші лінії все ще заповнюють доступні слоти. Запуски ліній за замовчуванням зсуваються на 2 секунди, щоб уникати локальних сплесків створення контейнерів Docker daemon; перевизначайте через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` або інше значення в мілісекундах. Локальний агрегат попередньо перевіряє Docker, видаляє застарілі контейнери OpenClaw E2E, виводить статус активних ліній, зберігає таймінги ліній для впорядкування від найдовших до найкоротших і підтримує `OPENCLAW_DOCKER_ALL_DRY_RUN=1` для інспекції планувальника. За замовчуванням він припиняє планувати нові pooled lanes після першої помилки, і кожна лінія має резервний таймаут 120 хвилин, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; окремі live/tail лінії використовують жорсткіші індивідуальні обмеження. `OPENCLAW_DOCKER_ALL_LANES=` запускає точні лінії планувальника, включно з лініями лише для релізу, такими як `install-e2e`, і розділеними лініями оновлення bundled, такими як `bundled-channel-update-acpx`, пропускаючи cleanup smoke, щоб агенти могли відтворити одну збійну лінію. Повторно використовуваний live/E2E workflow збирає і пушить один bare GHCR Docker E2E image з тегом SHA і один functional GHCR Docker E2E image з тегом SHA, а потім запускає релізний Docker suite не більш ніж у трьох 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`, таймінгами фаз і командами повторного запуску для кожної лінії. Вхід `docker_lanes` workflow запускає вибрані лінії проти підготовлених образів замість трьох chunk jobs, що обмежує налагодження збійної лінії одним цільовим Docker job; якщо вибрана лінія є live Docker lane, цільове завдання локально збирає live-test image для такого повторного запуску. Коли Open WebUI запитується разом із релізним suite, він виконується всередині chunk plugins/integrations замість резервування четвертого Docker worker; Open WebUI зберігає окреме standalone job лише для запусків openwebui-only. Запланований live/E2E workflow щодня запускає повний релізний Docker suite. Матриця bundled update розділена за ціллю оновлення, щоб повторні проходи npm update і doctor repair могли shard-итися разом з іншими bundled-перевірками. +Логіка визначення охоплення міститься в `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-перевірками. -Локальна логіка changed-lane міститься в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний шлюз суворіший щодо меж архітектури, ніж широке платформне охоплення CI: зміни у production core запускають typecheck production core плюс core-тести, зміни лише в core-тестах запускають лише typecheck/tests для core-тестів, зміни у production розширень запускають typecheck production розширень плюс тести розширень, а зміни лише в тестах розширень запускають лише typecheck/tests для тестів розширень. Зміни в публічному Plugin SDK або plugin-contract розширюють перевірку на розширення, оскільки розширення залежать від цих core-контрактів. Зміни лише в метаданих релізу з підвищенням версії запускають цільові перевірки version/config/root-dependency. Невідомі зміни в root/config для безпеки переводять перевірку на всі лінії. +Локальна логіка 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. Невідомі зміни в корені/конфігурації безпечно ескалюються до всіх ліній. -На пушах матриця `checks` додає лінію `compat-node22`, яка запускається лише для push. Для pull request цю лінію пропускають, і матриця залишається зосередженою на звичайних test/channel лініях. +Для пушів матриця `checks` додає лінію `compat-node22`, що запускається лише для push. Для pull request ця лінія пропускається, і матриця зосереджується на звичайних тестових/канальних лініях. -Найповільніші сімейства Node-тестів розділені або збалансовані так, щоб кожне завдання залишалося невеликим без надмірного резервування runner-ів: контракти каналів працюють як три зважені shard-и, тести bundled plugin балансуються між шістьма worker-ами розширень, малі core unit lanes поєднуються в пари, auto-reply запускається на чотирьох збалансованих worker-ах із розділенням reply subtree на shard-и agent-runner, dispatch і commands/state-routing, а конфігурації agentic gateway/plugin розподіляються між наявними source-only agentic Node jobs замість очікування built artifacts. Широкі browser, QA, media та miscellaneous plugin-тести використовують свої окремі конфігурації Vitest замість спільного plugin catch-all. Завдання shard-ів розширень запускають до двох груп конфігурацій плагінів одночасно з одним worker-ом Vitest на групу та більшим heap Node, щоб пакетні набори плагінів із великим імпортом не створювали зайвих CI jobs. Широка лінія agents використовує спільний file-parallel scheduler Vitest, оскільки в ній домінують імпорт і планування, а не один повільний тестовий файл. `runtime-config` виконується разом із shard-ом infra core-runtime, щоб спільний runtime shard не ставав найдовшим. Shard-и за include pattern записують таймінги з використанням імені CI shard, тому `.artifacts/vitest-shard-timings.json` може розрізняти цілу конфігурацію й відфільтрований shard. `check-additional` тримає разом роботу package-boundary compile/canary і відокремлює runtime topology architecture від покриття gateway watch; shard boundary guard запускає свої невеликі незалежні guard паралельно всередині одного job. Gateway watch, channel-тести та shard core support-boundary виконуються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` уже зібрані, зберігаючи свої старі назви перевірок як полегшені verifier jobs, водночас уникаючи двох додаткових Blacksmith worker-ів і другої черги споживачів артефактів. -Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, а потім збирає Play debug APK. Варіант third-party не має окремого source set або manifest; його лінія unit-тестів усе одно компілює цей варіант із прапорцями SMS/call-log у BuildConfig, водночас уникаючи дублювання packaging job для debug APK на кожному Android-релевантному push. -`extension-fast` запускається лише для PR, тому що push-запуски вже виконують повні shard-и bundled plugin. Це дає швидкий зворотний зв’язок щодо змінених плагінів під час review без резервування додаткового Blacksmith worker-а в `main` для покриття, яке вже присутнє в `checks-node-extensions`. +Найповільніші сімейства 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`. -GitHub може позначати замінені завдання як `cancelled`, коли новіший push потрапляє в той самий PR або ref `main`. Вважайте це шумом CI, якщо лише найновіший запуск для того самого ref також не завершується збоєм. Агреговані shard-перевірки використовують `!cancelled() && always()`, щоб вони все одно повідомляли про звичайні збої shard-ів, але не ставали в чергу після того, як увесь workflow уже був замінений. -Ключ конкурентності CI версіонований (`CI-v7-*`), щоб zombie-процес на боці GitHub у старій групі черги не міг безкінечно блокувати новіші запуски main. +GitHub може позначати витіснені завдання як `cancelled`, коли новіший push надходить у той самий PR або ref `main`. Вважайте це шумом CI, якщо тільки найновіший запуск для того самого ref теж не падає. Агреговані shard-перевірки використовують `!cancelled() && always()`, тож вони все одно повідомляють про звичайні збої shard-ів, але не стають у чергу після того, як увесь робочий процес уже було витіснено. +Ключ конкурентності CI має версію (`CI-v7-*`), щоб zombie на стороні GitHub у старій групі черги не міг безкінечно блокувати новіші запуски `main`. ## Runner-и -| Runner | Завдання | -| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ubuntu-24.04` | `preflight`, швидкі завдання безпеки та агрегати (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі перевірки protocol/contract/bundled, шардовані перевірки контрактів каналів, shard-и `check`, крім lint, shard-и й агрегати `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, shard-и Linux Node-тестів, shard-и тестів bundled plugin, `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`; для fork використовується резервний варіант `macos-latest` | -| `blacksmith-12vcpu-macos-latest` | `macos-swift` у `openclaw/openclaw`; для fork використовується резервний варіант `macos-latest` | +| 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` | ## Локальні еквіваленти ```bash pnpm changed:lanes # переглянути локальний класифікатор changed-lane для origin/main...HEAD -pnpm check:changed # розумний локальний шлюз: changed typecheck/lint/tests за boundary lane -pnpm check # швидкий локальний шлюз: production tsgo + шардований lint + паралельні fast guard +pnpm check:changed # розумний локальний gate: changed typecheck/lint/tests за boundary lane +pnpm check # швидкий локальний gate: production tsgo + шардований lint + паралельні швидкі guard-перевірки pnpm check:test-types -pnpm check:timed # той самий шлюз із таймінгами для кожного етапу +pnpm check:timed # той самий gate з таймінгами по етапах 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 check:docs # форматування документації + lint + зламані посилання pnpm build # зібрати dist, коли мають значення лінії CI artifact/build-smoke -pnpm ci:timings # зведення для останнього CI-запуску push у origin/main -pnpm ci:timings:recent # порівняти нещодавні успішні CI-запуски main -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 --recent 10 # порівняти нещодавні успішні CI-запуски main +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 --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 0f7405706..175ab76d7 100644 --- a/docs/uk/help/testing.md +++ b/docs/uk/help/testing.md @@ -1,237 +1,247 @@ --- read_when: - Запуск тестів локально або в CI - - Додавання регресійних тестів для помилок моделей/провайдерів - - Налагодження поведінки Gateway + agent -summary: 'Набір для тестування: набори unit/e2e/live, Docker-ранери та що охоплює кожен тест' + - Додавання регресійних тестів для багів моделі/провайдера + - Налагодження поведінки Gateway + агента +summary: 'Набір для тестування: набори unit/e2e/live, ранери Docker і що охоплює кожен тест' title: Тестування x-i18n: - generated_at: "2026-04-26T10:46:33Z" + generated_at: "2026-04-26T22:14:42Z" model: gpt-5.4 provider: openai - source_hash: 46c01493284511d99c37a18fc695cc0af19f87eb6d99eb2ef1beec331c290155 + source_hash: 425a86fc79b306f1957308c4060874d8d10a5ac61fb29b6cb91b7df3f445db91 source_path: help/testing.md workflow: 15 --- OpenClaw має три набори Vitest (unit/integration, e2e, live) і невеликий набір -Docker-ранерів. Цей документ — посібник «як ми тестуємо»: +ранерів Docker. Цей документ — посібник «як ми тестуємо»: - Що охоплює кожен набір (і що він навмисно _не_ охоплює). -- Які команди запускати для типових сценаріїв роботи (локально, перед push, налагодження). +- Які команди запускати для типових сценаріїв (локально, перед push, налагодження). - Як live-тести знаходять облікові дані та вибирають моделі/провайдерів. -- Як додавати регресійні тести для реальних проблем моделей/провайдерів. +- Як додавати регресійні тести для реальних проблем із моделями/провайдерами. ## Швидкий старт У більшості випадків: -- Повний gate (очікується перед push): `pnpm build && pnpm check && pnpm check:test-types && pnpm test` -- Швидший локальний запуск усіх наборів на машині з достатніми ресурсами: `pnpm test:max` +- Повний набір перевірок (очікується перед 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` -- Під час ітерацій над однією помилкою спочатку віддавайте перевагу точковим запускам. +- Під час ітерації над однією помилкою спочатку віддавайте перевагу цільовим запускам. - QA-сайт на базі Docker: `pnpm qa:lab:up` -- QA lane на базі Linux VM: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` +- QA-lane на базі Linux VM: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` -Коли ви змінюєте тести або хочете більше впевненості: +Коли ви змінюєте тести або хочете додаткової впевненості: -- Gate покриття: `pnpm test:coverage` +- Перевірка покриття: `pnpm test:coverage` - Набір E2E: `pnpm test:e2e` -Під час налагодження реальних провайдерів/моделей (потрібні справжні облікові дані): +Під час налагодження реальних провайдерів/моделей (потрібні реальні облікові дані): -- Live-набір (моделі + probes інструментів/зображень Gateway): `pnpm test:live` -- Точково запустити один live-файл у тихому режимі: `pnpm test:live -- src/agents/models.profiles.live.test.ts` +- Live-набір (моделі + перевірки інструментів/зображень Gateway): `pnpm test:live` +- Точковий запуск одного live-файлу без зайвого виводу: `pnpm test:live -- src/agents/models.profiles.live.test.ts` - Docker-прогін live-моделей: `pnpm test:docker:live-models` - - Кожна вибрана модель тепер виконує текстовий хід, а також невеликий probe у стилі читання файла. - Моделі, метадані яких оголошують вхід `image`, також виконують маленький хід із зображенням. - Вимкніть додаткові probes за допомогою `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` або + - Кожна вибрана модель тепер виконує текстовий хід плюс невелику перевірку у стилі читання файлу. + Моделі, у метаданих яких заявлено вхід `image`, також виконують невеликий хід із зображенням. + Вимкніть додаткові перевірки за допомогою `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` або `OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0`, коли ізолюєте збої провайдера. - Покриття в CI: щоденний `OpenClaw Scheduled Live And E2E Checks` і ручний - `OpenClaw Release Checks` обидва викликають повторно використовуваний workflow live/E2E з - `include_live_suites: true`, який включає окремі матричні завдання Docker live-моделей, - розбиті за провайдером. - - Для точкових повторних запусків у CI викликайте `OpenClaw Live And E2E Checks (Reusable)` + `OpenClaw Release Checks` обидва викликають повторно використовуваний live/E2E workflow з + `include_live_suites: true`, що включає окремі матричні Docker-завдання live-моделей, + розшардовані за провайдером. + - Для точкових повторних запусків у CI запустіть `OpenClaw Live And E2E Checks (Reusable)` з `include_live_suites: true` і `live_models_only: true`. - - Додавайте нові високосигнальні секрети провайдерів до `scripts/ci-hydrate-live-auth.sh`, а також до `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` і його - викликів за розкладом/для релізів. -- Native Codex bind-chat smoke: `pnpm test:docker:live-codex-bind` + - Додавайте нові високосигнальні секрети провайдерів до `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, прив’язує синтетичний - Slack DM за допомогою `/codex bind`, виконує `/codex fast` і - `/codex permissions`, а потім перевіряє, що звичайна відповідь і вкладення зображення - проходять через native binding plugin, а не через ACP. -- Smoke для harness app-server Codex: `pnpm test:docker:live-codex-harness` - - Проганяє agent-turn-и Gateway через harness app-server Codex, який належить Plugin, - перевіряє `/codex status` і `/codex models`, а також за замовчуванням виконує probes для image, - cron MCP, sub-agent і Guardian. Вимкніть probe sub-agent за допомогою + 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, + перевіряє `/codex status` і `/codex models`, а також за замовчуванням виконує перевірки image, + cron MCP, sub-agent і Guardian. Вимкніть перевірку sub-agent за допомогою `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0`, коли ізолюєте інші збої app-server Codex. - Для точкової перевірки sub-agent вимкніть інші probes: + Для точкової перевірки 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`. - Це завершується після probe sub-agent, якщо тільки не встановлено + Це завершиться після перевірки sub-agent, якщо не встановлено `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`. -- Smoke команди порятунку Crestodian: `pnpm test:live:crestodian-rescue-channel` - - Додаткова belt-and-suspenders перевірка поверхні команди порятунку каналу повідомлень. - Вона виконує `/crestodian status`, ставить у чергу постійну зміну моделі, - відповідає `/crestodian yes` і перевіряє шлях запису аудиту/конфігурації. -- Docker smoke planner Crestodian: `pnpm test:docker:crestodian-planner` - - Запускає Crestodian у контейнері без конфігурації з фальшивим Claude CLI у `PATH` - і перевіряє, що резервний fuzzy planner перетворюється на аудований типізований запис конфігурації. -- Docker smoke першого запуску Crestodian: `pnpm test:docker:crestodian-first-run` - - Починає з порожнього каталогу стану OpenClaw, маршрутизує голий `openclaw` до +- Smoke-тест rescue command Crestodian: `pnpm test:live:crestodian-rescue-channel` + - Опціональна додаткова перевірка поверхні rescue command для каналу повідомлень. + Вона виконує `/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` до Crestodian, застосовує записи setup/model/agent/Discord plugin + SecretRef, - валідує конфігурацію та перевіряє записи аудиту. Той самий шлях налаштування Ring 0 - також покривається в QA Lab за допомогою + перевіряє конфігурацію і записи audit. Той самий шлях налаштування Ring 0 + також покрито в QA Lab через `pnpm openclaw qa suite --scenario crestodian-ring-zero-setup`. -- Smoke вартості Moonshot/Kimi: якщо встановлено `MOONSHOT_API_KEY`, виконайте +- 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 і що + транскрипт помічника зберігає нормалізований `usage.cost`. -Порада: якщо вам потрібен лише один збійний випадок, віддавайте перевагу звуженню live-тестів через env vars allowlist, описані нижче. +Порада: коли вам потрібен лише один збійний випадок, віддавайте перевагу звуженню live-тестів за допомогою змінних середовища allowlist, описаних нижче. -## QA-специфічні ранери +## Ранери для QA -Ці команди розташовані поруч з основними наборами тестів, коли вам потрібен реалізм QA Lab: +Ці команди працюють поруч з основними наборами тестів, коли вам потрібен реалізм QA-lab: -CI запускає QA Lab в окремих workflow. `Parity gate` запускається на відповідних PR і -з ручного виклику з mock-провайдерами. `QA-Lab - All Lanes` запускається щоночі на -`main` і з ручного виклику з mock parity gate, live Matrix lane та live Telegram lane під керуванням Convex як паралельні завдання. `OpenClaw Release Checks` -запускає ті самі lane-и перед затвердженням релізу. +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 перед затвердженням релізу. - `pnpm openclaw qa suite` - - Запускає QA-сценарії на базі репозиторію безпосередньо на хості. + - Запускає QA-сценарії з репозиторію безпосередньо на хості. - За замовчуванням запускає кілька вибраних сценаріїв паралельно з ізольованими - воркерами Gateway. `qa-channel` за замовчуванням має concurrency 4 (обмежену + Gateway workers. `qa-channel` за замовчуванням має concurrency 4 (обмежується кількістю вибраних сценаріїв). Використовуйте `--concurrency `, щоб налаштувати - кількість воркерів, або `--concurrency 1` для старішого послідовного lane. - - Завершується з ненульовим кодом, якщо будь-який сценарій зазнав невдачі. Використовуйте `--allow-failures`, якщо - хочете отримати артефакти без коду завершення з помилкою. + кількість workers, або `--concurrency 1` для старішого послідовного lane. + - Повертає ненульовий код виходу, якщо будь-який сценарій завершується помилкою. + Використовуйте `--allow-failures`, якщо вам потрібні артефакти без помилкового коду виходу. - Підтримує режими провайдерів `live-frontier`, `mock-openai` і `aimock`. `aimock` запускає локальний сервер провайдера на базі AIMock для експериментального - покриття fixture і protocol-mock без заміни lane `mock-openai`, що враховує сценарії. + покриття fixture і protocol-mock без заміни lane `mock-openai`, який знає про сценарії. - `pnpm openclaw qa suite --runner multipass` - - Запускає той самий QA-набір усередині одноразової Linux VM Multipass. + - Запускає той самий QA-набір усередині тимчасової Linux VM Multipass. - Зберігає ту саму поведінку вибору сценаріїв, що й `qa suite` на хості. - Повторно використовує ті самі прапорці вибору провайдера/моделі, що й `qa suite`. - - Live-запуски передають підтримувані QA-входи автентифікації, практичні для гостьової системи: - ключі провайдерів на основі env, шлях до конфігурації live-провайдера QA і `CODEX_HOME`, якщо він є. - - Каталоги виводу мають залишатися в межах кореня репозиторію, щоб гостьова система могла записувати назад через + - Live-запуски передають у guest підтримувані вхідні QA-дані автентифікації, які для нього практичні: + ключі провайдерів через env, шлях до конфігурації live-провайдера QA і `CODEX_HOME`, якщо він наявний. + - Каталоги виводу мають залишатися в межах кореня репозиторію, щоб guest міг записувати назад через змонтований workspace. - - Записує звичайний звіт + summary QA, а також журнали Multipass до + - Записує звичайний QA-звіт і підсумок, а також логи 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 OpenAI API-key, за замовчуванням налаштовує Telegram, - перевіряє, що ввімкнення plugin встановлює runtime-залежності на вимогу, - запускає doctor і виконує один локальний agent-turn проти змоканого OpenAI endpoint. + Docker, виконує неінтерактивний onboarding із ключем API OpenAI, налаштовує Telegram + за замовчуванням, перевіряє, що ввімкнення Plugin встановлює runtime-залежності на вимогу, + запускає doctor і виконує один локальний хід агента проти замоканого endpoint OpenAI. - Використовуйте `OPENCLAW_NPM_ONBOARD_CHANNEL=discord`, щоб запустити той самий lane - інсталяції з пакета з Discord. + packaged-install з Discord. - `pnpm test:docker:session-runtime-context` - - Запускає детермінований Docker smoke для зібраного застосунку для transcript-ів - вбудованого runtime context. Він перевіряє, що прихований runtime context OpenClaw - зберігається як спеціальне повідомлення, що не відображається, замість витоку у видимий хід користувача, - потім підкладає зламаний session JSONL і перевіряє, що - `openclaw doctor --fix` переписує його на активну гілку з резервною копією. + - Виконує детермінований Docker smoke-тест built-app для вбудованих транскриптів runtime context. + Він перевіряє, що прихований runtime context OpenClaw зберігається як + спеціальне повідомлення, яке не відображається, замість витоку у видимий хід користувача, + потім підкладає пошкоджений JSONL сеансу і перевіряє, що + `openclaw doctor --fix` переписує його в активну гілку з резервною копією. - `pnpm test:docker:npm-telegram-live` - - Встановлює опублікований пакет OpenClaw у Docker, запускає onboarding встановленого пакета, + - Встановлює опублікований пакет OpenClaw у Docker, виконує onboarding для встановленого пакета, налаштовує Telegram через встановлений CLI, а потім повторно використовує live Telegram QA lane з цим встановленим пакетом як SUT Gateway. - За замовчуванням використовується `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`. - - Використовує ті самі облікові дані Telegram з env або джерело облікових даних Convex, що й - `pnpm openclaw qa telegram`. Для автоматизації CI/релізів встановіть - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex` разом із - `OPENCLAW_QA_CONVEX_SITE_URL` і секретом ролі. Якщо - `OPENCLAW_QA_CONVEX_SITE_URL` і секрет ролі Convex присутні в CI, - Docker-обгортка автоматично вибирає Convex. + - Використовує ті самі облікові дані Telegram через env або джерело облікових даних Convex, що й + `pnpm openclaw qa telegram`. Для автоматизації в CI/релізах установіть + `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 для мейнтейнерів `NPM Telegram Beta E2E`. Він не запускається під час merge. Workflow використовує середовище `qa-live-shared` і оренду облікових даних Convex CI. - `pnpm test:docker:bundled-channel-deps` - - Пакує й установлює поточну збірку OpenClaw у Docker, запускає Gateway з налаштованим OpenAI, а потім вмикає bundled channel/plugins через зміни конфігурації. - - Перевіряє, що виявлення налаштування залишає runtime-залежності - не налаштованого Plugin відсутніми, перший налаштований запуск Gateway або doctor встановлює runtime-залежності кожного bundled Plugin на вимогу, а другий перезапуск не перевстановлює залежності, які вже були активовані. - - Також встановлює відомий старіший npm baseline, вмикає Telegram перед запуском - `openclaw update --tag ` і перевіряє, що post-update doctor кандидата - виправляє runtime-залежності bundled channel без відновлення postinstall з боку harness. + - Пакує і встановлює поточну збірку OpenClaw у Docker, запускає Gateway + зі сконфігурованим OpenAI, а потім вмикає bundled channel/plugins через редагування конфігурації. + - Перевіряє, що виявлення setup залишає невстановленими runtime-залежності + не налаштованих Plugin, що перший налаштований запуск Gateway або doctor встановлює + runtime-залежності кожного bundled Plugin на вимогу, і що другий restart не перевстановлює + залежності, які вже були активовані. + - Також встановлює відому старішу npm-базову версію, вмикає Telegram перед запуском + `openclaw update --tag `, і перевіряє, що + post-update doctor у кандидаті відновлює runtime-залежності bundled channel без + postinstall-відновлення з боку harness. - `pnpm test:parallels:npm-update` - - Запускає native smoke оновлення встановленого пакета у гостьових системах Parallels. Кожна - вибрана платформа спочатку встановлює запитаний baseline package, потім запускає - встановлену команду `openclaw update` у тій самій гостьовій системі й перевіряє встановлену - версію, статус оновлення, готовність gateway та один локальний agent-turn. - - Використовуйте `--platform macos`, `--platform windows` або `--platform linux` під час - ітерації над однією гостьовою системою. Використовуйте `--json` для шляху до summary artifact і + - Запускає native smoke-тест оновлення packaged-install на guest-системах Parallels. Кожна + вибрана платформа спочатку встановлює вказаний базовий пакет, потім виконує команду + встановленого `openclaw update` у тій самій guest-системі і перевіряє встановлену + версію, статус оновлення, готовність gateway і один локальний хід агента. + - Використовуйте `--platform macos`, `--platform windows` або `--platform linux`, коли + ітеруєте над однією guest-системою. Використовуйте `--json` для шляху до підсумкового артефакту і статусу кожного lane. - - За замовчуванням lane OpenAI використовує `openai/gpt-5.5` для live-доказу agent-turn. + - За замовчуванням lane OpenAI використовує `openai/gpt-5.5` для live-перевірки ходу агента. Передайте `--model ` або встановіть `OPENCLAW_PARALLELS_OPENAI_MODEL`, якщо навмисно перевіряєте іншу модель OpenAI. - - Обгортайте тривалі локальні запуски хостовим timeout, щоб збої транспорту Parallels не - спожили решту вікна тестування: + - Обгортайте довгі локальні запуски в 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`, - перш ніж припускати, що зовнішня обгортка зависла. - - Оновлення Windows може витрачати 10–15 хвилин на відновлення doctor/runtime-залежностей після оновлення на холодній гостьовій системі; - це все ще нормальний стан, якщо вкладений npm debug log продовжує оновлюватися. - - Не запускайте цю агреговану обгортку паралельно з окремими smoke lane-ами Parallels - для macOS, Windows або Linux. Вони спільно використовують стан VM і можуть конфліктувати через - відновлення snapshot, обслуговування пакетів або стан guest Gateway. - - Доказ після оновлення запускає звичайну поверхню bundled Plugin, оскільки - capability facades, такі як speech, image generation і media - understanding, завантажуються через bundled runtime APIs, навіть якщо сам - agent-turn перевіряє лише просту текстову відповідь. + - Скрипт записує вкладені логи lane у `/tmp/openclaw-parallels-npm-update.*`. + Перегляньте `windows-update.log`, `macos-update.log` або `linux-update.log`, + перш ніж вважати, що зовнішня обгортка зависла. + - Оновлення Windows може займати від 10 до 15 хвилин на post-update doctor/runtime + repair залежностей на холодній guest-системі; це все ще є нормальним, якщо вкладений + npm debug log продовжує оновлюватися. + - Не запускайте цю агреговану обгортку паралельно з окремими smoke-lane Parallels + для macOS, Windows або Linux. Вони спільно використовують стан VM і можуть конфліктувати під час + відновлення snapshot, видачі пакетів або стану guest gateway. + - Перевірка після оновлення виконує звичайну поверхню bundled Plugin, оскільки + capability facades, як-от мовлення, генерація зображень і + розуміння медіа, завантажуються через bundled runtime API, навіть якщо сам + хід агента перевіряє лише просту текстову відповідь. - `pnpm openclaw qa aimock` - - Запускає лише локальний сервер провайдера AIMock для прямого smoke-тестування протоколу. + - Запускає лише локальний сервер провайдера AIMock для прямого smoke-тестування + протоколу. - `pnpm openclaw qa matrix` - - Запускає live QA lane Matrix проти одноразового homeserver Tuwunel на базі Docker. - - Цей QA-хост наразі призначений лише для repo/dev. Пакетні інсталяції OpenClaw не постачають `qa-lab`, тому не надають `openclaw qa`. - - Checkout-и репозиторію завантажують bundled runner безпосередньо; окремий крок встановлення Plugin не потрібен. + - Запускає live QA lane 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, summary, артефакт 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`. + - За замовчуванням використовує зафіксований стабільний образ 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`. - `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 chat id. - - Підтримує `--credential-source convex` для спільних pooled credentials. За замовчуванням використовуйте режим env, або встановіть `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`, щоб увімкнути pooled leases. - - Завершується з ненульовим кодом, якщо будь-який сценарій зазнав невдачі. Використовуйте `--allow-failures`, якщо хочете отримати артефакти без коду завершення з помилкою. - - Потребує двох різних ботів в одній приватній групі, при цьому бот SUT має мати Telegram username. + - Потребує `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, summary і артефакт observed-messages до `.artifacts/qa-e2e/...`. Сценарії з відповідями включають RTT від запиту надсилання driver до спостереженої відповіді SUT. + - Записує звіт Telegram QA, підсумок і артефакт observed-messages у `.artifacts/qa-e2e/...`. Сценарії з відповідями включають RTT від запиту на відправлення driver до спостережуваної відповіді SUT. -Live transport lane-и мають один спільний стандартний контракт, щоб нові транспорти не дрейфували: +Live transport lane використовують один стандартний контракт, щоб нові транспорти не розходилися в поведінці: -`qa-channel` залишається широким синтетичним QA-набором і не є частиною матриці покриття live transport. +`qa-channel` залишається широким синтетичним набором QA і не входить до матриці покриття live transport. -| Lane | Canary | Mention gating | Allowlist block | Top-level reply | Restart resume | Thread follow-up | Thread isolation | Reaction observation | Help command | -| -------- | ------ | -------------- | --------------- | --------------- | -------------- | ---------------- | ---------------- | -------------------- | ------------ | -| Matrix | x | x | x | x | x | x | x | x | | -| Telegram | x | | | | | | | | x | +| Lane | Canary | Блокування згадувань | Блок allowlist | Відповідь верхнього рівня | Відновлення після перезапуску | Подальша відповідь у треді | Ізоляція тредів | Спостереження за реакціями | Команда довідки | +| -------- | ------ | -------------------- | -------------- | ------------------------- | ----------------------------- | -------------------------- | --------------- | -------------------------- | --------------- | +| 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, поки lane працює, і звільняє lease під час завершення роботи. -Опорний scaffold проєкту Convex: +Еталонний scaffold проєкту Convex: - `qa/convex-credential-broker/` -Обов’язкові env vars: +Обов’язкові змінні env: - `OPENCLAW_QA_CONVEX_SITE_URL` (наприклад, `https://your-deployment.convex.site`) - Один секрет для вибраної ролі: @@ -239,24 +249,24 @@ QA lab отримує ексклюзивну lease із пулу на базі C - `OPENCLAW_QA_CONVEX_SECRET_CI` для `ci` - Вибір ролі облікових даних: - CLI: `--credential-role maintainer|ci` - - Значення env за замовчуванням: `OPENCLAW_QA_CREDENTIAL_ROLE` (за замовчуванням `ci` у CI, інакше `maintainer`) + - Типове значення env: `OPENCLAW_QA_CREDENTIAL_ROLE` (типово `ci` у CI, інакше `maintainer`) -Необов’язкові env vars: +Необов’язкові змінні env: -- `OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS` (за замовчуванням `1200000`) -- `OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS` (за замовчуванням `30000`) -- `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS` (за замовчуванням `90000`) -- `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS` (за замовчуванням `15000`) -- `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX` (за замовчуванням `/qa-credentials/v1`) +- `OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS` (типово `1200000`) +- `OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS` (типово `30000`) +- `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS` (типово `90000`) +- `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS` (типово `15000`) +- `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX` (типово `/qa-credentials/v1`) - `OPENCLAW_QA_CREDENTIAL_OWNER_ID` (необов’язковий trace id) -- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` дозволяє loopback `http://` URL-адреси Convex лише для локальної розробки. +- `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 @@ -265,11 +275,11 @@ pnpm openclaw qa credentials list --kind telegram pnpm openclaw qa credentials remove --credential-id ``` -Використовуйте `doctor` перед live-запусками, щоб перевірити 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`): +Типовий контракт endpoint (`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): - `POST /acquire` - Запит: `{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }` @@ -287,7 +297,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 }` @@ -295,60 +305,60 @@ pnpm openclaw qa credentials remove --credential-id Форма payload для типу Telegram: - `{ groupId: string, driverToken: string, sutToken: string }` -- `groupId` має бути рядком із числовим Telegram chat id. +- `groupId` має бути рядком із числовим ідентифікатором чату Telegram. - `admin/add` перевіряє цю форму для `kind: "telegram"` і відхиляє некоректні payload. ### Додавання каналу до QA -Додавання каналу до markdown-системи QA вимагає рівно двох речей: +Додавання каналу до системи markdown QA вимагає рівно двох речей: -1. Адаптер транспорту для каналу. -2. Пакет сценаріїв, який перевіряє контракт каналу. +1. Transport adapter для каналу. +2. Набір сценаріїв, який перевіряє контракт каналу. -Не додавайте новий кореневий QA-командний root верхнього рівня, якщо спільний хост `qa-lab` може -керувати цим потоком. +Не додавайте новий кореневий QA-командний простір верхнього рівня, якщо спільний хост `qa-lab` +може керувати цим потоком. -`qa-lab` володіє спільною механікою хоста: +`qa-lab` відповідає за спільну механіку хоста: -- кореневою командою `openclaw qa` -- запуском і завершенням набору -- concurrency воркерів -- записом артефактів -- генерацією звітів -- виконанням сценаріїв -- compatibility aliases для старіших сценаріїв `qa-channel` +- кореневий простір команд `openclaw qa` +- запуск і завершення набору +- concurrency workers +- запис артефактів +- генерацію звітів +- виконання сценаріїв +- alias сумісності для старіших сценаріїв `qa-channel` -Runner Plugins володіють транспортним контрактом: +Runner plugins відповідають за транспортний контракт: - як `openclaw qa ` монтується під спільним коренем `qa` -- як Gateway налаштовується для цього транспорту +- як gateway налаштовується для цього транспорту - як перевіряється готовність -- як ін’єктуються вхідні події +- як інжектуються вхідні події - як спостерігаються вихідні повідомлення -- як відкриваються transcript-и та нормалізований стан транспорту -- як виконуються дії, підтримувані транспортом -- як обробляються специфічні для транспорту reset або cleanup +- як надаються транскрипти й нормалізований стан транспорту +- як виконуються дії, забезпечені транспортом +- як обробляються транспортно-специфічне скидання або очищення -Мінімальний поріг впровадження для нового каналу: +Мінімальний поріг впровадження нового каналу: 1. Залишайте `qa-lab` власником спільного кореня `qa`. -2. Реалізуйте transport runner на межі спільного хоста `qa-lab`. -3. Зберігайте специфічну для транспорту механіку всередині runner Plugin або harness каналу. -4. Монтуйте runner як `openclaw qa `, а не реєструйте конкуруючу кореневу команду. - Runner Plugins мають оголошувати `qaRunners` у `openclaw.plugin.json` і експортувати відповідний масив `qaRunnerCliRegistrations` з `runtime-api.ts`. - Зберігайте `runtime-api.ts` легким; lazy CLI і виконання runner мають залишатися за окремими entrypoint. +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. 5. Створюйте або адаптуйте markdown-сценарії в тематичних каталогах `qa/scenarios/`. -6. Використовуйте generic scenario helpers для нових сценаріїв. -7. Зберігайте наявні compatibility aliases працездатними, якщо тільки репозиторій не виконує навмисну міграцію. +6. Для нових сценаріїв використовуйте generic helpers. +7. Зберігайте чинні alias сумісності, якщо репозиторій не виконує навмисну міграцію. -Правило прийняття рішення суворе: +Правило прийняття рішень суворе: -- Якщо поведінку можна виразити один раз у `qa-lab`, розміщуйте її в `qa-lab`. -- Якщо поведінка залежить від одного channel transport, зберігайте її в runner Plugin або harness цього Plugin. -- Якщо сценарію потрібна нова можливість, яку може використати більше ніж один канал, додайте generic helper замість channel-specific гілки в `suite.ts`. -- Якщо поведінка має сенс лише для одного транспорту, зберігайте сценарій специфічним для цього транспорту й явно зазначайте це в контракті сценарію. +- Якщо поведінку можна один раз виразити в `qa-lab`, розміщуйте її в `qa-lab`. +- Якщо поведінка залежить від одного транспорту каналу, залишайте її в runner plugin або harness цього Plugin. +- Якщо сценарію потрібна нова можливість, яку може використати більше ніж один канал, додавайте generic helper замість специфічної для каналу гілки в `suite.ts`. +- Якщо поведінка має сенс лише для одного транспорту, залишайте сценарій транспортно-специфічним і явно позначайте це в контракті сценарію. -Бажані назви generic helper для нових сценаріїв: +Для нових сценаріїв бажані назви generic helper такі: - `waitForTransportReady` - `waitForChannelReady` @@ -363,7 +373,7 @@ Runner Plugins володіють транспортним контрактом: - `formatTransportTranscript` - `resetTransport` -Compatibility aliases залишаються доступними для наявних сценаріїв, зокрема: +Alias сумісності залишаються доступними для наявних сценаріїв, зокрема: - `waitForQaChannelReady` - `waitForOutboundMessage` @@ -371,121 +381,122 @@ Compatibility aliases залишаються доступними для ная - `formatConversationTranscript` - `resetBus` -Нова робота над каналами має використовувати generic helper names. -Compatibility aliases існують, щоб уникнути міграції типу flag day, а не як модель -для написання нових сценаріїв. +Нова робота з каналами має використовувати назви generic helper. +Alias сумісності існують, щоб уникнути міграції типу flag day, а не як модель +для створення нових сценаріїв. ## Набори тестів (що де запускається) -Сприймайте набори як «зростання реалізму» (і зростання flaky/cost): +Сприймайте набори як «зростання реалізму» (і зростання флакiв/вартості): -### Unit / integration (за замовчуванням) +### Unit / integration (типово) - Команда: `pnpm test` -- Конфігурація: нетаргетовані запуски використовують набір shard `vitest.full-*.config.ts` і можуть розгортати multi-project shards у конфігурації для окремих проєктів для паралельного планування -- Файли: інвентарі core/unit у `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts` і whitelist-нуті node-тести `ui`, які покриває `vitest.unit.config.ts` +- Конфігурація: нетаргетовані запуски використовують набір шардів `vitest.full-*.config.ts` і можуть розгортати багатопроєктні шарди в конфігурації для окремих проєктів для паралельного планування +- Файли: інвентарі core/unit у `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts` і whitelist node-тести `ui`, покриті `vitest.unit.config.ts` - Обсяг: - Чисті unit-тести - - In-process integration-тести (автентифікація gateway, маршрутизація, tooling, парсинг, конфігурація) - - Детерміновані регресії для відомих помилок + - In-process integration-тести (автентифікація gateway, маршрутизація, інструменти, парсинг, конфігурація) + - Детерміновані регресії для відомих багів - Очікування: - - Запускається в CI - - Не потребує реальних ключів - - Має бути швидким і стабільним + - Запускаються в CI + - Реальні ключі не потрібні + - Мають бути швидкими й стабільними - + - - Нетаргетовані запуски `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`) замість одного гігантського root-project процесу. Це зменшує піковий RSS на завантажених машинах і не дає роботі `auto-reply`/extension виснажувати не пов’язані набори. - - `pnpm test --watch` усе ще використовує native граф проєктів root `vitest.config.ts`, оскільки цикл watch із кількома shard не є практичним. - - `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 торкається лише routable файлів source/test; редагування config/setup усе ще повертаються до широкого повторного запуску root project. - - `pnpm check:changed` — це звичний smart local 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 замість повного набору, із захистом, що відхиляє зміни пакета поза полем версії верхнього рівня. - - Зміни live Docker ACP harness запускають фокусований локальний gate: shell syntax для live Docker auth scripts, dry-run live Docker scheduler, unit-тести ACP bind і тести extension ACPX. Зміни `package.json` включаються лише тоді, коли diff обмежено `scripts["test:docker:live-*"]`; зміни dependencies, exports, versions та інших поверхонь пакета все ще використовують ширші guard-и. - - Import-light unit-тести з agents, commands, plugins, helper-ів `auto-reply`, `plugin-sdk` та подібних чистих utility-областей маршрутизуються через lane `unit-fast`, який пропускає `test/setup-openclaw-runtime.ts`; stateful/runtime-heavy файли залишаються на наявних lane-ах. - - Вибрані helper-файли source з `plugin-sdk` і `commands` також зіставляють запуски в режимі changed з явними sibling test у цих light lane-ах, тож зміни 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 tail. + - Нетаргетований `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. - - Коли ви змінюєте вхідні дані виявлення message-tool або runtime context Compaction, зберігайте обидва рівні покриття. + - Коли ви змінюєте входи виявлення message-tool або runtime context Compaction, + зберігайте обидва рівні покриття. - Додавайте сфокусовані helper-регресії для чистих меж маршрутизації та нормалізації. - - Підтримуйте в робочому стані integration-набори embedded runner: + - Підтримуйте в здоровому стані 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 типово використовує `threads`. - Спільна конфігурація Vitest фіксує `isolate: false` і використовує - неізольований runner у root projects, а також у конфігураціях e2e і live. - - Root lane UI зберігає свій `jsdom` setup та optimizer, але також працює на + неізольований runner у root projects, e2e і live configs. + - Кореневий UI lane зберігає своє налаштування `jsdom` і optimizer, але також працює на спільному неізольованому runner. - - Кожен shard `pnpm test` успадковує ті самі типові значення `threads` + `isolate: false` + - Кожен шард `pnpm test` успадковує ті самі типові значення `threads` + `isolate: false` зі спільної конфігурації Vitest. - - `scripts/run-vitest.mjs` за замовчуванням додає `--no-maglev` для дочірніх Node-процесів 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 виконує лише форматування. Він повторно додає відформатовані файли до stage і + - `pnpm changed:lanes` показує, які архітектурні lane запускає diff. + - Pre-commit hook виконує лише форматування. Він повторно індексує відформатовані файли і не запускає lint, typecheck або тести. - - Запускайте `pnpm check:changed` явно перед передачею роботи або push, коли - вам потрібен smart local gate. Зміни публічного Plugin SDK і plugin-contract + - Явно запускайте `pnpm check:changed` перед передаванням або push, коли + вам потрібен розумний локальний gate. Зміни публічного Plugin SDK і plugin-contract включають один прохід валідації extension. - - `pnpm test:changed` маршрутизує через scoped lane-и, коли змінені шляхи - чисто зіставляються з меншим набором. + - `pnpm test:changed` маршрутизує через scoped lane, коли змінені шляхи + однозначно зіставляються з меншим набором. - `pnpm test:max` і `pnpm test:changed:max` зберігають ту саму поведінку маршрутизації, - лише з вищим лімітом воркерів. - - Автомасштабування локальних воркерів навмисно консервативне і знижує навантаження, - коли середнє навантаження хоста вже високе, тому кілька одночасних - запусків Vitest за замовчуванням завдають менше шкоди. - - Базова конфігурація Vitest позначає проєкти/конфігураційні файли як + лише з вищим лімітом workers. + - Автоматичне масштабування локальних workers навмисно є консервативним і знижує навантаження, + коли середнє навантаження хоста вже високе, тож кілька одночасних + запусків Vitest типово завдають менше шкоди. + - Базова конфігурація Vitest позначає файли projects/config як `forceRerunTriggers`, щоб повторні запуски в режимі changed залишалися коректними, - коли змінюється wiring тестів. + коли змінюється зв’язування тестів. - Конфігурація зберігає `OPENCLAW_VITEST_FS_MODULE_CACHE` увімкненим на підтримуваних - хостах; встановіть `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`, якщо хочете - одну явну локацію кешу для прямого профілювання. + хостах; установіть `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`, якщо вам потрібне + одне явне розташування кешу для прямого профілювання. - - `pnpm test:perf:imports` вмикає звітність Vitest про тривалість імпортів, а також - вивід розбивки імпортів. - - `pnpm test:perf:imports:changed` обмежує той самий профільований вигляд + - `pnpm test:perf:imports` вмикає звітність Vitest про тривалість імпорту плюс + вивід import-breakdown. + - `pnpm test:perf:imports:changed` обмежує той самий режим профілювання файлами, зміненими відносно `origin/main`. - - Дані таймінгів shard записуються до `.artifacts/vitest-shard-timings.json`. - Запуски цілої конфігурації використовують шлях до config як ключ; shard-и CI за include-pattern - додають ім’я shard, щоб відфільтровані shard-и можна було відстежувати - окремо. - - Коли один гарячий тест усе ще витрачає більшість часу на стартові імпорти, - зберігайте важкі залежності за вузькою локальною межею `*.runtime.ts` і - мокайте цю межу напряму замість глибокого імпорту helper-ів runtime лише - для того, щоб передати їх через `vi.mock(...)`. + - Дані часу шардів записуються в `.artifacts/vitest-shard-timings.json`. + Запуски цілої конфігурації використовують шлях конфігурації як ключ; шарди CI + з include-pattern додають ім’я шарда, щоб відфільтровані шарди можна було + відстежувати окремо. + - Коли один гарячий тест усе ще витрачає більшу частину часу на стартові імпорти, + тримайте важкі залежності за вузьким локальним seam `*.runtime.ts` і мокуйте + цей seam напряму замість глибокого імпорту runtime helper лише + для передачі їх через `vi.mock(...)`. - `pnpm test:perf:changed:bench -- --ref ` порівнює маршрутизований - `test:changed` з native шляхом root-project для цього зафіксованого + `test:changed` з native шляхом root project для цього закоміченого diff і виводить wall time плюс macOS max RSS. - - `pnpm test:perf:changed:bench -- --worktree` бенчмаркає поточне - брудне дерево, маршрутизуючи список змінених файлів через - `scripts/test-projects.mjs` і root-конфігурацію Vitest. + - `pnpm test:perf:changed:bench -- --worktree` виконує бенчмарк поточного + брудного дерева, маршрутизуючи список змінених файлів через + `scripts/test-projects.mjs` і кореневу конфігурацію Vitest. - `pnpm test:perf:profile:main` записує CPU-профіль main thread для - накладних витрат запуску та transform у Vitest/Vite. - - `pnpm test:perf:profile:runner` записує профілі CPU+heap для runner - unit-набору з вимкненим файловим паралелізмом. + накладних витрат запуску та трансформації Vitest/Vite. + - `pnpm test:perf:profile:runner` записує профілі CPU+heap runner для + unit-набору з вимкненим паралелізмом файлів. @@ -493,250 +504,250 @@ Compatibility aliases існують, щоб уникнути міграції ### Стабільність (gateway) - Команда: `pnpm test:stability:gateway` -- Конфігурація: `vitest.gateway.config.ts`, примусово один воркер +- Конфігурація: `vitest.gateway.config.ts`, примусово один worker - Обсяг: - Запускає реальний loopback Gateway з увімкненою діагностикою за замовчуванням - - Пропускає синтетичні churn повідомлень gateway, пам’яті та великих payload через шлях діагностичних подій - - Виконує запити до `diagnostics.stability` через WS RPC Gateway - - Покриває helper-и збереження diagnostic stability bundle - - Перевіряє, що recorder залишається обмеженим, синтетичні вибірки RSS не перевищують бюджет тиску, а глибини черг на рівні сесії повертаються до нуля + - Пропускає синтетичне навантаження повідомленнями gateway, пам’яттю та великими payload через шлях діагностичних подій + - Запитує `diagnostics.stability` через WS RPC Gateway + - Покриває helper персистентності diagnostic stability bundle + - Перевіряє, що recorder залишається обмеженим, синтетичні зразки RSS лишаються в межах бюджету тиску, а глибини черг на сесію повертаються до нуля - Очікування: - Безпечно для CI і без ключів - - Вузький lane для подальшої роботи над регресіями стабільності, а не заміна повному набору Gateway + - Вузький lane для подальшого опрацювання регресій стабільності, а не заміна повного набору Gateway ### E2E (gateway smoke) - Команда: `pnpm test:e2e` - Конфігурація: `vitest.e2e.config.ts` - Файли: `src/**/*.e2e.test.ts`, `test/**/*.e2e.test.ts` і bundled-plugin E2E-тести в `extensions/` -- Типові значення runtime: +- Типові параметри runtime: - Використовує Vitest `threads` з `isolate: false`, як і решта репозиторію. - - Використовує adaptive workers (CI: до 2, локально: 1 за замовчуванням). - - За замовчуванням працює в silent mode, щоб зменшити накладні витрати на console I/O. + - Використовує адаптивну кількість workers (CI: до 2, локально: 1 за замовчуванням). + - За замовчуванням працює в тихому режимі, щоб зменшити накладні витрати на консольний I/O. - Корисні перевизначення: - - `OPENCLAW_E2E_WORKERS=` для примусового встановлення кількості воркерів (обмежено 16). - - `OPENCLAW_E2E_VERBOSE=1`, щоб знову увімкнути докладний вивід у консоль. + - `OPENCLAW_E2E_WORKERS=` щоб примусово задати кількість workers (обмежено 16). + - `OPENCLAW_E2E_VERBOSE=1` щоб знову ввімкнути докладний консольний вивід. - Обсяг: - - End-to-end поведінка gateway з кількома інстансами - - Поверхні WebSocket/HTTP, pairing Node і важче мережеве навантаження + - Наскрізна поведінка gateway із кількома інстансами + - Поверхні WebSocket/HTTP, pairинг Node і важча мережева взаємодія - Очікування: - - Запускається в CI (коли ввімкнено в pipeline) - - Не потребує реальних ключів + - Запускається в CI (коли увімкнено в pipeline) + - Реальні ключі не потрібні - Має більше рухомих частин, ніж unit-тести (може бути повільнішим) -### E2E: smoke backend OpenShell +### E2E: smoke OpenShell backend - Команда: `pnpm test:e2e:openshell` - Файл: `extensions/openshell/src/backend.e2e.test.ts` - Обсяг: - Запускає ізольований Gateway OpenShell на хості через Docker - - Створює sandbox з тимчасового локального Dockerfile - - Перевіряє backend OpenShell в OpenClaw через реальні `sandbox ssh-config` + SSH exec - - Перевіряє remote-canonical поведінку файлової системи через fs bridge sandbox + - Створює sandbox із тимчасового локального Dockerfile + - Перевіряє OpenShell backend OpenClaw через реальні `sandbox ssh-config` + SSH exec + - Перевіряє канонічну для remote поведінку файлової системи через fs bridge sandbox - Очікування: - - Лише за явним бажанням; не входить до типового запуску `pnpm test:e2e` - - Потребує локального CLI `openshell` і працездатного Docker daemon + - Лише за бажанням; не входить до типового запуску `pnpm test:e2e` + - Потребує локального CLI `openshell` і справного демона Docker - Використовує ізольовані `HOME` / `XDG_CONFIG_HOME`, а потім знищує test gateway і sandbox - Корисні перевизначення: - `OPENCLAW_E2E_OPENSHELL=1`, щоб увімкнути тест під час ручного запуску ширшого набору e2e - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`, щоб вказати нестандартний бінарний файл CLI або wrapper script + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`, щоб указати нестандартний CLI-бінарник або wrapper-скрипт ### Live (реальні провайдери + реальні моделі) - Команда: `pnpm test:live` - Конфігурація: `vitest.live.config.ts` - Файли: `src/**/*.live.test.ts`, `test/**/*.live.test.ts` і bundled-plugin live-тести в `extensions/` -- За замовчуванням: **увімкнено** через `pnpm test:live` (встановлює `OPENCLAW_LIVE_TEST=1`) +- Типово: **увімкнено** через `pnpm test:live` (встановлює `OPENCLAW_LIVE_TEST=1`) - Обсяг: - - «Чи справді цей провайдер/модель працює _сьогодні_ з реальними обліковими даними?» - - Виявлення змін формату провайдера, особливостей виклику tools, проблем автентифікації та поведінки rate limit + - «Чи справді цей провайдер/модель _сьогодні_ працює з реальними обліковими даними?» + - Виявляє зміни формату провайдера, особливості виклику інструментів, проблеми автентифікації та поведінку rate limit - Очікування: - - За задумом не є стабільним для CI (реальні мережі, реальні політики провайдерів, квоти, збої) - - Коштує грошей / витрачає rate limit + - За задумом нестабільні для CI (реальні мережі, реальні політики провайдерів, квоти, відмови) + - Коштують грошей / використовують rate limit - Краще запускати звужені підмножини, а не «все» -- Live-запуски підвантажують `~/.profile`, щоб отримати відсутні API key. -- За замовчуванням live-запуски все одно ізолюють `HOME` і копіюють матеріали config/auth у тимчасовий test home, щоб unit fixtures не могли змінити ваш реальний `~/.openclaw`. -- Встановлюйте `OPENCLAW_LIVE_USE_REAL_HOME=1` лише тоді, коли навмисно хочете, щоб live-тести використовували ваш реальний home directory. -- `pnpm test:live` тепер за замовчуванням працює в тихішому режимі: він зберігає вивід прогресу `[live] ...`, але приглушує додаткове повідомлення `~/.profile` і вимикає журнали bootstrap gateway/шум Bonjour. Встановіть `OPENCLAW_LIVE_TEST_QUIET=0`, якщо хочете повернути повні стартові журнали. -- Ротація 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. -- Вивід progress/Heartbeat: - - Live-набори тепер виводять рядки прогресу в stderr, тож довгі виклики провайдера залишаються видимо активними, навіть коли захоплення консолі Vitest тихе. - - `vitest.live.config.ts` вимикає перехоплення консолі Vitest, тому рядки progress провайдера/gateway транслюються негайно під час live-запусків. - - Налаштовуйте Heartbeat прямих моделей через `OPENCLAW_LIVE_HEARTBEAT_MS`. +- Live-запуски підключають `~/.profile`, щоб підхопити відсутні API-ключі. +- За замовчуванням 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. +- Вивід прогресу/Heartbeat: + - Live-набори тепер виводять рядки прогресу в stderr, щоб довгі виклики провайдера було видно як активні, навіть коли перехоплення консолі Vitest працює тихо. + - `vitest.live.config.ts` вимикає перехоплення консолі 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 protocol / pairing: додайте `pnpm test:e2e` -- Налагоджуєте «мій бот не працює» / специфічні для провайдера збої / виклик tools: запускайте звужений `pnpm test:live` +- Торкаєтеся мережевої взаємодії gateway / протоколу WS / pairингy: додайте `pnpm test:e2e` +- Налагоджуєте «мій бот не працює» / збої, специфічні для провайдера / виклик інструментів: запускайте звужений `pnpm test:live` -## Live (мережеві) тести +## Live-тести (які торкаються мережі) -Для матриці live-моделей, smoke-тестів CLI backend, smoke-тестів ACP, harness Codex app-server -та всіх live-тестів медіапровайдерів (Deepgram, BytePlus, ComfyUI, image, +Для live-матриці моделей, smoke-тестів CLI backend, smoke-тестів ACP, harness Codex app-server +і всіх live-тестів медіапровайдерів (Deepgram, BytePlus, ComfyUI, image, music, video, media harness) — а також обробки облікових даних для live-запусків — див. [Тестування — live-набори](/uk/help/testing-live). -## Docker-ранери (необов’язкові перевірки «працює в Linux») +## Ранери Docker (необов’язкові перевірки «працює в Linux») -Ці Docker-ранери поділяються на дві групи: +Ці ранери Docker поділяються на дві категорії: -- Live-model runners: `test:docker:live-models` і `test:docker:live-gateway` запускають лише відповідний live-файл з ключем профілю всередині Docker image репозиторію (`src/agents/models.profiles.live.test.ts` і `src/gateway/gateway-models.profiles.live.test.ts`), монтують ваш локальний каталог конфігурації й workspace (і підвантажують `~/.profile`, якщо його змонтовано). Відповідні локальні entrypoint-и: `test:live:models-profiles` і `test:live:gateway-profiles`. -- Docker live runners за замовчуванням мають менший smoke-ліміт, щоб повний Docker-прогін залишався практичним: - `test:docker:live-models` за замовчуванням використовує `OPENCLAW_LIVE_MAX_MODELS=12`, а - `test:docker:live-gateway` — `OPENCLAW_LIVE_GATEWAY_SMOKE=1`, +- Ранери 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-прогін залишався практичним: + `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 vars, коли + `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Перевизначайте ці змінні env, коли вам явно потрібне більше вичерпне сканування. -- `test:docker:all` один раз збирає live Docker image через `test:docker:live-build`, а потім повторно використовує його для live Docker lane-ів. Також він збирає один спільний image `scripts/e2e/Dockerfile` через `test:docker:e2e-build` і повторно використовує його для E2E smoke-ранерів у контейнерах, які перевіряють зібраний застосунок. Агрегат використовує зважений локальний планувальник: `OPENCLAW_DOCKER_ALL_PARALLELISM` керує слотами процесів, а обмеження ресурсів не дають усім важким live, npm-install і multi-service lane-ам стартувати одночасно. За замовчуванням це 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-хост має більше запасу ресурсів. За замовчуванням runner виконує Docker preflight, видаляє застарілі OpenClaw E2E-контейнери, виводить статус кожні 30 секунд, зберігає таймінги успішних lane-ів у `.artifacts/docker-tests/lane-timings.json` і використовує ці таймінги, щоб у наступних запусках запускати довші lane-и першими. Використовуйте `OPENCLAW_DOCKER_ALL_DRY_RUN=1`, щоб вивести зважений маніфест lane-ів без збирання й запуску Docker. -- Container smoke runners: `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` запускають один або кілька реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня. +- `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` запускають один або більше реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня. -Docker-ранери live-моделей також bind-mount-ять лише потрібні home-каталоги для автентифікації CLI (або всі підтримувані, якщо запуск не звужено), а потім копіюють їх у home контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени, не змінюючи сховище автентифікації хоста: +Docker-ранери live-моделей також bind-монтують лише потрібні CLI auth home (або всі підтримувані, якщо запуск не звужено), а потім копіюють їх у домашній каталог контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени без зміни auth-store на хості: -- Direct models: `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, зі strict-покриттям Droid/OpenCode через `pnpm test:docker:live-acp-bind:droid` і `pnpm test:docker:live-acp-bind:opencode`) +- Прямі моделі: `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 harness Codex app-server: `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, повне scaffold-налаштування): `pnpm test:docker:onboard` (скрипт: `scripts/e2e/onboard-docker.sh`) -- Npm tarball onboarding/channel/agent smoke: `pnpm test:docker:npm-onboard-channel-agent` глобально встановлює запакований tarball OpenClaw у Docker, налаштовує OpenAI через onboarding env-ref і за замовчуванням Telegram, перевіряє, що doctor відновлює runtime deps активованого Plugin, і запускає один змоканий agent-turn 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, перемикається з 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 providers замість зависання. Повторно використовуйте попередньо зібраний tarball через `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, пропустіть збирання на хості через `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` або скопіюйте `dist/` із зібраного Docker image через `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` як stable baseline перед оновленням до tarball кандидата. Перевірки інсталятора без root зберігають ізольований npm cache, щоб записи cache, що належать root, не маскували поведінку локальної інсталяції користувача. Встановіть `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache`, щоб повторно використовувати cache root/update/direct-npm між локальними повторними запусками. -- Install Smoke CI пропускає дубльований direct-npm global update через `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1`; запускайте скрипт локально без цього env, коли потрібне покриття прямого `npm install -g`. -- CLI smoke видалення спільного workspace агентів: `pnpm test:docker:agents-delete-shared-workspace` (скрипт: `scripts/e2e/agents-delete-shared-workspace-docker.sh`) за замовчуванням збирає root Dockerfile image, створює два агенти з одним workspace в ізольованому home контейнера, запускає `agents delete --json` і перевіряє коректний JSON плюс поведінку збереження workspace. Повторно використовуйте image 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 браузерного CDP: `pnpm test:docker:browser-cdp-snapshot` (скрипт: `scripts/e2e/browser-cdp-snapshot-docker.sh`) збирає source E2E image плюс шар Chromium, запускає Chromium з raw CDP, виконує `browser doctor --deep` і перевіряє, що CDP role snapshots охоплюють URL-адреси посилань, clickable-елементи, підняті курсором, iframe refs і frame metadata. -- Мінімальна 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`, потім примусово викликає відхилення provider schema й перевіряє, що сирі деталі з’являються в журналах Gateway. -- Міст каналу MCP (seeded Gateway + stdio bridge + raw smoke notification-frame Claude): `pnpm test:docker:mcp-channels` (скрипт: `scripts/e2e/mcp-channels-docker.sh`) -- Інструменти MCP у Pi bundle (реальний stdio MCP server + smoke allow/deny вбудованого профілю Pi): `pnpm test:docker:pi-bundle-mcp-tools` (скрипт: `scripts/e2e/pi-bundle-mcp-tools-docker.sh`) -- Очищення Cron/subagent MCP (реальний Gateway + teardown дочірнього 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, або перевизначте пакет за замовчуванням через `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` і `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID`. +- 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 у локальних повторних запусках. +- 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`. +- Мережева взаємодія 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 незмінного оновлення Plugin: `pnpm test:docker:plugin-update` (скрипт: `scripts/e2e/plugin-update-unchanged-docker.sh`) -- Smoke метаданих перезавантаження конфігурації: `pnpm test:docker:config-reload` (скрипт: `scripts/e2e/config-reload-source-docker.sh`) -- Runtime deps bundled Plugin: `pnpm test:docker:bundled-channel-deps` за замовчуванням збирає невеликий Docker runner image, один раз збирає й пакує OpenClaw на хості, а потім монтує цей tarball у кожен сценарій інсталяції Linux. Повторно використовуйте image через `OPENCLAW_SKIP_DOCKER_BUILD=1`, пропустіть перебудову на хості після свіжого локального збирання через `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` або вкажіть наявний tarball через `OPENCLAW_BUNDLED_CHANNEL_PACKAGE_TGZ=/path/to/openclaw-*.tgz`. Повний Docker aggregate попередньо пакує цей 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` пригнічують відновлення doctor/runtime-dependency. -- Звужуйте runtime deps bundled Plugin під час ітерацій, вимикаючи не пов’язані сценарії, наприклад: +- 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 під час ітерації, вимикаючи нерелевантні сценарії, наприклад: `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`. -Щоб вручну попередньо зібрати й повторно використовувати спільний built-app image: +Щоб вручну попередньо зібрати й повторно використати спільний функціональний образ: ```bash -OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e:local pnpm test:docker:e2e-build -OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels +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 ``` -Перевизначення image для конкретного набору, такі як `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE`, усе ще мають пріоритет, якщо встановлені. Коли `OPENCLAW_SKIP_DOCKER_BUILD=1` вказує на віддалений спільний image, скрипти завантажують його, якщо його ще немає локально. Docker-тести QR та installer зберігають власні Dockerfile, оскільки вони перевіряють поведінку пакета/інсталяції, а не спільний runtime зібраного застосунку. +Перевизначення образів для конкретних наборів, як-от `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE`, усе ще мають пріоритет, якщо встановлені. Коли `OPENCLAW_SKIP_DOCKER_BUILD=1` вказує на віддалений спільний образ, скрипти завантажують його, якщо його ще немає локально. Тести Docker для QR та інсталятора зберігають власні Dockerfile, оскільки вони перевіряють поведінку пакета/встановлення, а не спільний runtime built-app. -Docker-ранери live-моделей також bind-mount-ять поточний checkout у режимі лише для читання й -розгортають його в тимчасовий workdir усередині контейнера. Це зберігає runtime -image компактним, але водночас дозволяє запускати Vitest точно на вашому локальному source/config. -Крок staging пропускає великі локальні cache та результати збирання застосунків, такі як -`.pnpm-store`, `.worktrees`, `__openclaw_vitest__` і локальні для застосунків каталоги -`.build` або вивід Gradle, щоб Docker live-запуски не витрачали хвилини на копіювання +Docker-ранери live-моделей також bind-монтують поточний checkout лише для читання і +розміщують його в тимчасовому workdir усередині контейнера. Це зберігає runtime- +образ компактним, але все одно запускає Vitest точно на вашому локальному source/config. +Крок staging пропускає великі локальні кеші та результати збірки застосунків, як-от +`.pnpm-store`, `.worktrees`, `__openclaw_vitest__`, а також локальні для застосунку каталоги `.build` або +виводу Gradle, щоб Docker live-запуски не витрачали хвилини на копіювання артефактів, специфічних для машини. -Вони також встановлюють `OPENCLAW_SKIP_CHANNELS=1`, щоб live-probe-и gateway не запускали -реальні channel workers Telegram/Discord тощо всередині контейнера. +Вони також встановлюють `OPENCLAW_SKIP_CHANNELS=1`, щоб live-проби gateway не запускали +реальні workers каналів Telegram/Discord тощо всередині контейнера. `test:docker:live-models` усе ще запускає `pnpm test:live`, тому також передавайте -`OPENCLAW_LIVE_GATEWAY_*`, коли потрібно звузити або виключити gateway live-покриття з цього Docker lane. -`test:docker:openwebui` — це smoke перевірка сумісності вищого рівня: вона запускає -контейнер Gateway OpenClaw з увімкненими OpenAI-compatible HTTP endpoint, запускає -закріплений контейнер Open WebUI проти цього gateway, виконує вхід через -Open WebUI, перевіряє, що `/api/models` показує `openclaw/default`, а потім надсилає -реальний запит чату через проксі `/api/chat/completions` Open WebUI. -Перший запуск може бути помітно повільнішим, оскільки Docker може потребувати завантаження -image Open WebUI, а Open WebUI може потребувати завершення власного cold-start налаштування. -Цей lane очікує придатний live key моделі, а `OPENCLAW_PROFILE_FILE` -(за замовчуванням `~/.profile`) є основним способом надати його в Dockerized-запусках. +`OPENCLAW_LIVE_GATEWAY_*`, коли вам потрібно звузити або виключити live-покриття gateway із цього Docker lane. +`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-запусках. Успішні запуски виводять невеликий JSON payload на кшталт `{ "ok": true, "model": "openclaw/default", ... }`. -`test:docker:mcp-channels` є навмисно детермінованим і не потребує -реального облікового запису Telegram, Discord або iMessage. Він запускає seeded контейнер -Gateway, стартує другий контейнер, який запускає `openclaw mcp serve`, а потім -перевіряє виявлення маршрутизованих conversation, читання transcript, метадані вкладень, -поведінку черги live events, маршрутизацію outbound send і сповіщення про channel + -permissions у стилі Claude через реальний stdio міст MCP. Перевірка сповіщень -напряму аналізує сирі stdio MCP frames, тож smoke перевіряє те, що міст -фактично випромінює, а не лише те, що випадково показує конкретний client SDK. -`test:docker:pi-bundle-mcp-tools` є детермінованим і не потребує live -key моделі. Він збирає Docker image репозиторію, запускає реальний probe server stdio MCP +`test:docker:mcp-channels` навмисно є детермінованим і не потребує +реального облікового запису Telegram, Discord або iMessage. Він запускає seeded Gateway +контейнер, стартує другий контейнер, який запускає `openclaw mcp serve`, а потім +перевіряє виявлення маршрутизованих розмов, читання транскриптів, метадані вкладень, +поведінку черги live-подій, маршрутизацію вихідної відправки та сповіщення у стилі Claude про канал + +дозволи через реальний stdio MCP bridge. Перевірка сповіщень +безпосередньо досліджує сирі stdio MCP frame, тож smoke перевіряє те, що міст +справді виводить, а не лише те, що випадково показує конкретний client SDK. +`test:docker:pi-bundle-mcp-tools` є детермінованим і не потребує +ключа live-моделі. Він збирає Docker-образ репозиторію, запускає реальний stdio MCP probe server усередині контейнера, матеріалізує цей сервер через вбудований runtime Pi bundle -MCP, виконує tool, а потім перевіряє, що `coding` і `messaging` зберігають -інструменти `bundle-mcp`, тоді як `minimal` і `tools.deny: ["bundle-mcp"]` їх фільтрують. -`test:docker:cron-mcp-cleanup` є детермінованим і не потребує live -key моделі. Він запускає seeded Gateway з реальним probe server stdio MCP, виконує -ізольований хід cron і одноразовий дочірній хід `/subagents spawn`, а потім перевіряє, -що дочірній процес MCP завершується після кожного запуску. +MCP, виконує інструмент, а потім перевіряє, що `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-процес завершується після кожного запуску. Ручний smoke plain-language thread для ACP (не CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` - Зберігайте цей скрипт для сценаріїв регресії/налагодження. Він може знову знадобитися для перевірки маршрутизації ACP thread, тому не видаляйте його. -Корисні env vars: +Корисні змінні 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 vars, підвантажені з `OPENCLAW_PROFILE_FILE`, використовуючи тимчасові каталоги config/workspace і без монтування зовнішньої CLI-автентифікації -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (за замовчуванням: `~/.cache/openclaw/docker-cli-tools`) монтується в `/home/node/.npm-global` для кешованих інсталяцій CLI всередині Docker -- Зовнішні каталоги/файли 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_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/...` перед запуском тестів + - Типові каталоги: `.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`, щоб повторно використовувати наявний image `openclaw:local-live` для повторних запусків, які не потребують перебудови -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб гарантувати, що облікові дані надходять зі сховища profile, а не з env -- `OPENCLAW_OPENWEBUI_MODEL=...`, щоб вибрати модель, яку gateway показує для smoke Open WebUI -- `OPENCLAW_OPENWEBUI_PROMPT=...`, щоб перевизначити nonce-check prompt, який використовує smoke Open WebUI -- `OPENWEBUI_IMAGE=...`, щоб перевизначити закріплений тег image Open WebUI +- `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 +- `OPENWEBUI_IMAGE=...`, щоб перевизначити зафіксований тег образу Open WebUI ## Перевірка документації -Запускайте перевірки документації після змін у документації: `pnpm check:docs`. -Запускайте повну перевірку anchor у Mintlify, коли також потрібні перевірки заголовків усередині сторінки: `pnpm docs:check-links:anchors`. +Після редагування документації запускайте перевірки docs: `pnpm check:docs`. +Запускайте повну перевірку anchor у Mintlify, коли вам також потрібні перевірки заголовків на сторінці: `pnpm docs:check-links:anchors`. -## Офлайн-регресія (безпечно для CI) +## Офлайн-регресія (безпечна для CI) Це регресії «реального pipeline» без реальних провайдерів: -- Виклик tools Gateway (mock OpenAI, реальний gateway + agent loop): `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 enforced): `src/gateway/gateway.test.ts` (випадок: "runs wizard over ws and writes auth token config") +- Виклик інструментів 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") -## Оцінювання надійності agent (Skills) +## Оцінювання надійності агента (Skills) -У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності agent»: +У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності агента»: -- Mock-виклик tools через реальний gateway + agent loop (`src/gateway/gateway.test.ts`). -- End-to-end потоки wizard, які перевіряють wiring сесії та ефекти конфігурації (`src/gateway/gateway.test.ts`). +- Mock-виклик інструментів через реальний цикл gateway + agent (`src/gateway/gateway.test.ts`). +- Наскрізні потоки wizard, які перевіряють зв’язування сесії та ефекти конфігурації (`src/gateway/gateway.test.ts`). -Чого ще бракує для Skills (див. [Skills](/uk/tools/skills)): +Чого все ще бракує для Skills (див. [Skills](/uk/tools/skills)): -- **Decisioning:** коли Skills перелічені в prompt, чи вибирає agent правильний Skill (або уникає нерелевантних)? -- **Compliance:** чи читає agent `SKILL.md` перед використанням і чи дотримується потрібних кроків/аргументів? -- **Workflow contracts:** багатохідні сценарії, які перевіряють порядок tools, перенесення історії сесії та межі sandbox. +- **Прийняття рішень:** коли Skills перелічені в prompt, чи вибирає агент правильний skill (або уникає нерелевантних)? +- **Відповідність вимогам:** чи читає агент `SKILL.md` перед використанням і виконує потрібні кроки/аргументи? +- **Контракти workflow:** багатокрокові сценарії, які перевіряють порядок інструментів, перенесення історії сесії та межі sandbox. -Майбутні оцінювання мають спочатку залишатися детермінованими: +Майбутні eval мають спершу залишатися детермінованими: -- Runner сценаріїв із mock-провайдерами для перевірки викликів tools + їхнього порядку, читання Skill-файлів і wiring сесії. -- Невеликий набір сценаріїв, сфокусованих на Skills (використовувати чи уникати, gating, injection у prompt). -- Необов’язкові live-оцінювання (opt-in, з керуванням через env) лише після того, як з’явиться безпечний для CI набір. +- Runner сценаріїв із mock-провайдерами для перевірки викликів інструментів + порядку, читання skill-файлів і зв’язування сесії. +- Невеликий набір сценаріїв, сфокусованих на skills (використовувати чи уникати, gating, prompt injection). +- Необов’язкові live-eval (opt-in, із керуванням через env) лише після того, як буде готовий набір, безпечний для CI. ## Контрактні тести (форма Plugin і channel) Контрактні тести перевіряють, що кожен зареєстрований Plugin і channel відповідає своєму -інтерфейсному контракту. Вони проходять по всіх виявлених Plugins і запускають набір -перевірок форми та поведінки. Типовий unit lane `pnpm test` навмисно +інтерфейсному контракту. Вони проходять по всіх виявлених Plugin і запускають набір +перевірок форми та поведінки. Типовий unit-lane `pnpm test` навмисно пропускає ці спільні seam- і smoke-файли; запускайте контрактні команди явно, -коли торкаєтесь спільних поверхонь channel або provider. +коли торкаєтеся спільних поверхонь channel або provider. ### Команди @@ -748,29 +759,29 @@ key моделі. Він запускає seeded Gateway з реальним pro Розташовані в `src/channels/plugins/contracts/*.contract.test.ts`: -- **plugin** - Базова форма Plugin (id, name, capabilities) +- **plugin** - Базова форма Plugin (`id`, `name`, `capabilities`) - **setup** - Контракт wizard налаштування - **session-binding** - Поведінка прив’язки сесії - **outbound-payload** - Структура payload повідомлення - **inbound** - Обробка вхідних повідомлень - **actions** - Обробники дій channel - **threading** - Обробка ID thread -- **directory** - API directory/roster -- **group-policy** - Застосування політики групи +- **directory** - API каталогу/складу +- **group-policy** - Застосування групової політики ### Контракти статусу provider Розташовані в `src/plugins/contracts/*.contract.test.ts`. -- **status** - Проби статусу channel -- **registry** - Форма registry Plugin +- **status** - Перевірки статусу channel +- **registry** - Форма реєстру Plugin ### Контракти provider Розташовані в `src/plugins/contracts/*.contract.test.ts`: -- **auth** - Контракт потоку автентифікації -- **auth-choice** - Вибір/добір автентифікації +- **auth** - Контракт потоку auth +- **auth-choice** - Вибір/встановлення auth - **catalog** - API каталогу моделей - **discovery** - Виявлення Plugin - **loader** - Завантаження Plugin @@ -780,24 +791,24 @@ key моделі. Він запускає seeded Gateway з реальним pro ### Коли запускати -- Після змін exports або subpath у plugin-sdk -- Після додавання або зміни channel чи provider Plugin +- Після зміни export або subpath у plugin-sdk +- Після додавання або зміни Plugin channel або provider - Після рефакторингу реєстрації або виявлення Plugin -Контрактні тести запускаються в CI й не потребують реальних API key. +Контрактні тести запускаються в CI і не потребують реальних API-ключів. -## Додавання регресій (рекомендації) +## Додавання регресійних тестів (рекомендації) Коли ви виправляєте проблему provider/model, виявлену в live: -- Додавайте безпечну для CI регресію, якщо це можливо (mock/stub provider або фіксація точної трансформації форми запиту) -- Якщо проблема за своєю природою лише live (rate limit, політики auth), зберігайте live-тест вузьким і opt-in через env vars -- Віддавайте перевагу націлюванню на найменший шар, який виявляє помилку: - - помилка конвертації/відтворення запиту provider → direct models test - - помилка pipeline session/history/tool у gateway → gateway live smoke або безпечний для CI gateway mock test -- Guardrail обходу SecretRef: - - `src/secrets/exec-secret-ref-id-parity.test.ts` виводить одну вибіркову ціль на клас SecretRef із метаданих registry (`listSecretTargetRegistryEntries()`), а потім перевіряє, що exec id сегментів обходу відхиляються. - - Якщо ви додаєте нову родину цілей SecretRef `includeInPlan` у `src/secrets/target-registry-data.ts`, оновіть `classifyTargetClass` у цьому тесті. Тест навмисно падає на некласифікованих target id, щоб нові класи не можна було тихо пропустити. +- Додайте безпечну для 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, щоб нові класи не можна було тихо пропустити. ## Пов’язане diff --git a/docs/uk/reference/test.md b/docs/uk/reference/test.md index f6f248f16..ee8e2e3c3 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-26T21:58:20Z" + generated_at: "2026-04-26T22:14:38Z" model: gpt-5.4 provider: openai - source_hash: cc575df6f7a6edd72fe5db766b140587e16c2daf887bb3ce3f9d273a0e7cf311 + source_hash: 676abe8e753d49719f3bc333680e50e0a0ec9f82c5c85b5ef7c1ec55452f10ed source_path: reference/test.md workflow: 15 --- -- Повний набір для тестування (сьюти, live, Docker): [Тестування](/uk/help/testing) +- Повний набір для тестування (набори тестів, live, Docker): [Тестування](/uk/help/testing) -- `pnpm test:force`: завершує будь-який завислий процес Gateway, який утримує стандартний порт керування, а потім запускає повний набір Vitest з ізольованим портом Gateway, щоб серверні тести не конфліктували із запущеним екземпляром. Використовуйте це, коли попередній запуск Gateway залишив зайнятим порт 18789. -- `pnpm test:coverage`: запускає набір unit-тестів із покриттям V8 (через `vitest.unit.config.ts`). Це перевірка покриття unit-тестами для завантажених файлів, а не загальнорепозиторне покриття всіх файлів. Порогові значення становлять 70% для lines/functions/statements і 55% для branches. Оскільки `coverage.all` має значення false, перевірка вимірює файли, завантажені набором unit-тестів із покриттям, замість того щоб вважати всі вихідні файли split-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 у відповідні маршрутизовані lane-и Vitest, коли diff торкається лише маршрутизованих вихідних/тестових файлів. Зміни конфігурації/налаштування все одно повертаються до нативного запуску root projects, щоб зміни в wiring перевірялися ширше, коли це потрібно. -- `pnpm test:changed:focused`: запуск змінених тестів для внутрішнього циклу розробки. Він запускає лише точні цілі з прямих змін тестів, сусідніх файлів `*.test.ts`, явних мапінгів вихідних файлів і локального графа імпортів. Широкі зміни/config/package пропускаються замість розгортання до повного резервного запуску changed-test. -- `pnpm changed:lanes`: показує архітектурні lane-и, активовані diff відносно `origin/main`. -- `pnpm check:changed`: запускає розумну перевірку changed gate для diff відносно `origin/main`. Вона запускає core-роботи разом із core test lanes, роботу extension — разом із extension test lanes, зміни лише в тестах — лише з test typecheck/tests, розгортає зміни публічного Plugin SDK або plugin-contract до одного проходу валідації extension, а також залишає version bumps лише в release metadata на цільових перевірках version/config/root-dependency. -- `pnpm test`: маршрутизує явні цілі файлів/каталогів через відповідні lane-и Vitest. Запуски без цілей використовують фіксовані групи shard-ів і розгортаються до leaf configs для локального паралельного виконання; група extension завжди розгортається до конфігурацій shard-ів окремих extension, а не до одного гігантського процесу root-project. -- Повні запуски, запуски extension і запуски shard-ів за include-pattern оновлюють локальні дані часу виконання в `.artifacts/vitest-shard-timings.json`; наступні запуски всієї конфігурації використовують ці дані, щоб збалансувати повільні та швидкі shard-и. CI-shard-и за include-pattern додають ім’я shard-а до ключа часу, що дозволяє зберігати видимість часу відфільтрованих shard-ів, не замінюючи дані часу всієї конфігурації. Встановіть `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 не домінував над легшими тестами status/token/helper верхнього рівня. -- Базова конфігурація Vitest тепер за замовчуванням використовує `pool: "threads"` і `isolate: false`, а спільний неізольований runner увімкнено в усіх конфігураціях репозиторію. +- `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:channels` запускає `vitest.channels.config.ts`. -- `pnpm test:extensions` і `pnpm test extensions` запускають усі shard-и extension/plugin. Важкі channel plugins, browser plugin і OpenAI запускаються як окремі shard-и; інші групи plugin залишаються згрупованими. Використовуйте `pnpm test extensions/` для одного lane-а зібраного plugin. -- `pnpm test:perf:imports`: вмикає звітність Vitest про тривалість імпорту та import-breakdown, водночас і далі використовуючи маршрутизацію відповідних lane-ів для явних цілей файлів/каталогів. -- `pnpm test:perf:imports:changed`: той самий import profiling, але лише для файлів, змінених відносно `origin/main`. -- `pnpm test:perf:changed:bench -- --ref ` виконує бенчмарк маршрутизованого режиму changed-mode порівняно з нативним запуском root-project для того самого зафіксованого git diff. -- `pnpm test:perf:changed:bench -- --worktree` виконує бенчмарк поточного набору змін worktree без попереднього коміту. +- `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: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-артефактами для кожної конфігурації. Агент продуктивності тестів використовує це як базову лінію перед спробами виправлення повільних тестів. -- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`: порівнює згруповані звіти після зміни, орієнтованої на продуктивність. +- `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`: порівнює згруповані звіти після зміни, зосередженої на продуктивності. - Інтеграція 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-тестів і два образи Docker E2E, а потім запускає Docker smoke lanes з `OPENCLAW_SKIP_DOCKER_BUILD=1` через зважений планувальник. Базовий образ (`OPENCLAW_DOCKER_E2E_BARE_IMAGE`) використовується для lane-ів installer/update/plugin-dependency; функціональний образ (`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`) заздалегідь готує залежності runtime для bundled plugin для звичайних lane-ів функціональності. `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; змінити це можна через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=`. Runner за замовчуванням виконує попередню перевірку Docker, очищує застарілі контейнери OpenClaw E2E, кожні 30 секунд виводить статус активних lane-ів, спільно використовує кеші 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-провайдерів; package aliases — `pnpm test:docker:local:all` і `pnpm test:docker:live:all`. У режимі лише live основні та tail live lane-и об’єднуються в один пул із пріоритетом найдовших, щоб кошики провайдерів могли спільно пакувати навантаження 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 backend мають окремий timeout через `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` (за замовчуванням 180). Логи кожного lane-а та часи фаз `summary.json` записуються в `.artifacts/docker-tests//`. -- `pnpm test:docker:browser-cdp-snapshot`: збирає вихідний E2E-контейнер на базі Chromium, запускає raw CDP разом з ізольованим Gateway, виконує `browser doctor --deep` і перевіряє, що CDP role snapshots містять URL-посилань, clickables, підняті курсором, iframe refs і метадані frame. -- Live Docker probes для CLI backend можна запускати як цільові 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 є відповідні aliases `: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`: запускає seeded-контейнер Gateway і другий клієнтський контейнер, який запускає `openclaw mcp serve`, а потім перевіряє routed conversation discovery, читання transcript, метадані вкладень, поведінку live event queue, маршрутизацію outbound send, а також сповіщення про channel + permissions у стилі Claude через реальний міст stdio. Перевірка сповіщень Claude читає необроблені stdio MCP frames безпосередньо, щоб smoke-тест відображав те, що міст реально надсилає. +- `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-тест відображав те, що міст фактично надсилає. -## Локальна перевірка PR +## Локальний PR gate -Для локальних перевірок land/gate PR виконайте: +Для локальних перевірок land/gate PR запускайте: - `pnpm check:changed` - `pnpm check` @@ -57,7 +57,7 @@ x-i18n: - `pnpm test` - `pnpm check:docs` -Якщо `pnpm test` дає flaky-результат на завантаженому хості, перезапустіть один раз, перш ніж вважати це регресією, а потім ізолюйте через `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` @@ -69,13 +69,13 @@ x-i18n: Використання: - `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10` -- Необов’язкові env: `MINIMAX_API_KEY`, `MINIMAX_BASE_URL`, `MINIMAX_MODEL`, `ANTHROPIC_API_KEY` -- Стандартний prompt: “Reply with a single word: ok. No punctuation or extra text.” +- Необов’язкові змінні середовища: `MINIMAX_API_KEY`, `MINIMAX_BASE_URL`, `MINIMAX_MODEL`, `ANTHROPIC_API_KEY` +- Типовий prompt: “Reply with a single word: ok. No punctuation or extra text.” Останній запуск (2025-12-31, 20 запусків): -- minimax median 1279ms (min 1114, max 2431) -- opus median 2454ms (min 1224, max 3170) +- minimax медіана 1279ms (мін. 1114, макс. 2431) +- opus медіана 2454ms (мін. 1224, макс. 3170) ## Бенчмарк запуску CLI @@ -98,19 +98,19 @@ 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` -Preset-и: +Presets: - `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`: обидва preset-и +- `all`: обидва presets -Вивід містить `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, розподіл exit-code/signal і підсумки 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: @@ -120,9 +120,9 @@ Preset-и: ## Onboarding E2E (Docker) -Docker є необов’язковим; це потрібно лише для контейнеризованих smoke-тестів onboarding. +Docker необов’язковий; це потрібно лише для containerized smoke-тестів onboarding. -Повний cold-start flow у чистому Linux-контейнері: +Повний cold-start потік у чистому контейнері Linux: ```bash scripts/e2e/onboard-docker.sh @@ -130,9 +130,9 @@ scripts/e2e/onboard-docker.sh Цей скрипт керує інтерактивним майстром через pseudo-tty, перевіряє файли config/workspace/session, потім запускає Gateway і виконує `openclaw health`. -## Smoke-тест імпорту QR (Docker) +## QR import smoke (Docker) -Гарантує, що підтримуваний helper runtime для QR завантажується в підтримуваних Node runtime Docker (Node 24 за замовчуванням, Node 22 сумісний): +Гарантує, що підтримуваний допоміжний 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)