Testing
آزمایش
OpenClaw سه مجموعهٔ Vitest دارد (واحد/یکپارچهسازی، e2e، زنده) و مجموعهٔ کوچکی از اجراکنندههای Docker. این سند راهنمای «ما چگونه تست میکنیم» است:
- هر مجموعه چه چیزهایی را پوشش میدهد (و عمداً چه چیزهایی را پوشش نمیدهد).
- برای جریانهای کاری رایج (محلی، پیش از ارسال، اشکالزدایی) کدام فرمانها را اجرا کنید.
- تستهای زنده چگونه اعتبارنامهها را پیدا میکنند و مدلها/ارائهدهندگان را انتخاب میکنند.
- چگونه برای مشکلات واقعی مدل/ارائهدهنده، رگرسیون اضافه کنید.
شروع سریع
در بیشتر روزها:
- گیت کامل (پیش از ارسال انتظار میرود):
pnpm build && pnpm check && pnpm check:test-types && pnpm test - اجرای سریعتر مجموعهٔ کامل محلی روی ماشینی با منابع کافی:
pnpm test:max - چرخهٔ watch مستقیم Vitest:
pnpm test:watch - هدفگیری مستقیم فایل اکنون مسیرهای افزونه/کانال را هم مسیریابی میکند:
pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts - وقتی روی یک خرابی واحد در حال تکرار هستید، ابتدا اجراهای هدفمند را ترجیح دهید.
- سایت تضمین کیفیت متکی بر Docker:
pnpm qa:lab:up - مسیر تضمین کیفیت متکی بر ماشین مجازی Linux:
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline
وقتی تستها را لمس میکنید یا اطمینان بیشتری میخواهید:
- گیت پوشش:
pnpm test:coverage - مجموعهٔ E2E:
pnpm test:e2e
هنگام اشکالزدایی ارائهدهندگان/مدلهای واقعی (نیازمند اعتبارنامههای واقعی):
- مجموعهٔ زنده (مدلها + کاوشهای ابزار/تصویر Gateway):
pnpm test:live - هدفگیری بیسروصدای یک فایل زنده:
pnpm test:live -- src/agents/models.profiles.live.test.ts - گزارشهای کارایی زمان اجرا:
OpenClaw Performanceرا باlive_gpt54=trueبرای یک نوبت عامل واقعیopenai/gpt-5.4یاdeep_profile=trueبرای آرتیفکتهای CPU/heap/trace مربوط به Kova اجرا کنید. اجراهای زمانبندیشدهٔ روزانه وقتیCLAWGRIT_REPORTS_TOKENپیکربندی شده باشد، آرتیفکتهای مسیر mock-provider، deep-profile و GPT 5.4 را درopenclaw/clawgrit-reportsمنتشر میکنند. گزارش mock-provider همچنین شامل اعداد راهاندازی Gateway در سطح منبع، حافظه، فشار Plugin، حلقهٔ سلام تکراری fake-model و شروع CLI است. - جاروب مدل زندهٔ Docker:
pnpm test:docker:live-models- هر مدل انتخابشده اکنون یک نوبت متنی بهعلاوهٔ یک کاوش کوچک به سبک خواندن فایل را اجرا میکند.
مدلهایی که فرادادهشان ورودی
imageرا اعلام میکند، یک نوبت تصویر کوچک هم اجرا میکنند. هنگام ایزولهکردن خرابیهای ارائهدهنده، کاوشهای اضافه را باOPENCLAW_LIVE_MODEL_FILE_PROBE=0یاOPENCLAW_LIVE_MODEL_IMAGE_PROBE=0غیرفعال کنید. - پوشش یکپارچهسازی پیوسته:
OpenClaw Scheduled Live And E2E Checksروزانه وOpenClaw Release Checksدستی هر دو گردشکار قابلاستفادهٔ مجدد زنده/E2E را باinclude_live_suites: trueفراخوانی میکنند که شامل jobهای ماتریس مدل زندهٔ Docker جداگانه است که بر اساس ارائهدهنده شارد شدهاند. - برای اجرای دوبارهٔ متمرکز در یکپارچهسازی پیوسته،
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و فراخوانهای زمانبندیشده/انتشار آن اضافه کنید.
- هر مدل انتخابشده اکنون یک نوبت متنی بهعلاوهٔ یک کاوش کوچک به سبک خواندن فایل را اجرا میکند.
مدلهایی که فرادادهشان ورودی
- دودسنجی گفتوگوی متصل بومی Codex:
pnpm test:docker:live-codex-bind- یک مسیر زندهٔ Docker را در برابر مسیر app-server مربوط به Codex اجرا میکند، یک پیام مستقیم مصنوعی
Slack را با
/codex bindمتصل میکند،/codex fastو/codex permissionsرا تمرین میدهد، سپس تأیید میکند که یک پاسخ ساده و یک پیوست تصویر بهجای ACP از مسیر اتصال Plugin بومی عبور میکنند.
- یک مسیر زندهٔ Docker را در برابر مسیر app-server مربوط به Codex اجرا میکند، یک پیام مستقیم مصنوعی
Slack را با
- دودسنجی هارنس app-server مربوط به Codex:
pnpm test:docker:live-codex-harness- نوبتهای عامل Gateway را از هارنس app-server مربوط به Codex که مالکیتش با Plugin است عبور میدهد،
/codex statusو/codex modelsرا تأیید میکند و بهصورت پیشفرض تصویر، cron MCP، زیرعامل و کاوشهای Guardian را تمرین میدهد. هنگام ایزولهکردن سایر خرابیهای app-server مربوط به Codex، کاوش زیرعامل را باOPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0غیرفعال کنید. برای بررسی متمرکز زیرعامل، کاوشهای دیگر را غیرفعال کنید: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. این پس از کاوش زیرعامل خارج میشود مگر اینکهOPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0تنظیم شده باشد.
- نوبتهای عامل Gateway را از هارنس app-server مربوط به Codex که مالکیتش با Plugin است عبور میدهد،
- دودسنجی نصب درخواستی Codex:
pnpm test:docker:codex-on-demand- tarball بستهبندیشدهٔ OpenClaw را در Docker نصب میکند، راهاندازی با کلید API مربوط به OpenAI را اجرا میکند،
و تأیید میکند که Plugin مربوط به Codex بهعلاوهٔ وابستگی
@openai/codexبرحسب تقاضا در ریشهٔ npm مدیریتشده دانلود شدهاند.
- tarball بستهبندیشدهٔ OpenClaw را در Docker نصب میکند، راهاندازی با کلید API مربوط به OpenAI را اجرا میکند،
و تأیید میکند که Plugin مربوط به Codex بهعلاوهٔ وابستگی
- دودسنجی وابستگی ابزار Plugin زنده:
pnpm test:docker:live-plugin-tool- یک Plugin fixture با وابستگی واقعی
slugifyرا بستهبندی میکند، آن را از طریقnpm-pack:نصب میکند، وابستگی را زیر ریشهٔ npm مدیریتشده تأیید میکند، سپس از یک مدل زندهٔ OpenAI میخواهد ابزار Plugin را فراخوانی کند و slug پنهان را برگرداند.
- یک Plugin fixture با وابستگی واقعی
- دودسنجی فرمان نجات Crestodian:
pnpm test:live:crestodian-rescue-channel- بررسی انتخابی و چندلایه برای سطح فرمان نجات کانال پیام.
/crestodian statusرا تمرین میدهد، یک تغییر ماندگار مدل را در صف میگذارد، به/crestodian yesپاسخ میدهد، و مسیر نوشتن audit/config را تأیید میکند.
- بررسی انتخابی و چندلایه برای سطح فرمان نجات کانال پیام.
- دودسنجی Docker برنامهریز Crestodian:
pnpm test:docker:crestodian-planner- Crestodian را در یک کانتینر بدون پیکربندی با یک CLI جعلی Claude روی
PATHاجرا میکند و تأیید میکند که fallback برنامهریز فازی به یک نوشتن پیکربندی تایپشده و auditشده تبدیل میشود.
- Crestodian را در یک کانتینر بدون پیکربندی با یک CLI جعلی Claude روی
- دودسنجی Docker اجرای نخست Crestodian:
pnpm test:docker:crestodian-first-run- از یک دایرکتوری وضعیت خالی OpenClaw شروع میکند،
openclawخام را به Crestodian مسیریابی میکند، نوشتنهای setup/model/agent/Plugin مربوط به Discord + SecretRef را اعمال میکند، پیکربندی را اعتبارسنجی میکند و ورودیهای audit را تأیید میکند. همان مسیر راهاندازی Ring 0 در QA Lab هم باpnpm openclaw qa suite --scenario crestodian-ring-zero-setupپوشش داده میشود.
- از یک دایرکتوری وضعیت خالی OpenClaw شروع میکند،
- دودسنجی هزینهٔ 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نرمالسازیشده را ذخیره میکند.
اجراکنندههای مخصوص تضمین کیفیت
وقتی به واقعگرایی QA-lab نیاز دارید، این فرمانها کنار مجموعههای تست اصلی قرار میگیرند:
یکپارچهسازی پیوسته QA Lab را در گردشکارهای اختصاصی اجرا میکند. برابری عاملمحور زیر
QA-Lab - All Lanes و اعتبارسنجی انتشار قرار دارد، نه یک گردشکار مستقل برای PR.
اعتبارسنجی گسترده باید از Full Release Validation با
rerun_group=qa-parity یا گروه تضمین کیفیت release-checks استفاده کند. بررسیهای انتشار پایدار/پیشفرض
soak کامل زنده/Docker را پشت run_release_soak=true نگه میدارند؛
پروفایل full soak را اجباری میکند. QA-Lab - All Lanes
هر شب روی main و از dispatch دستی با مسیر برابری mock، مسیر Matrix زنده، مسیر Telegram زندهٔ مدیریتشده با Convex، و مسیر Discord زندهٔ مدیریتشده با Convex
بهعنوان jobهای موازی اجرا میشود. تضمین کیفیت زمانبندیشده و بررسیهای انتشار Matrix
--profile fast را صریحاً پاس میدهند، در حالی که CLI مربوط به Matrix و ورودی گردشکار دستی
همچنان پیشفرض all دارند؛ dispatch دستی میتواند all را به jobهای transport،
media، e2ee-smoke، e2ee-deep، و e2ee-cli شارد کند. OpenClaw Release Checks پیش از تأیید انتشار، برابری بهعلاوهٔ مسیرهای سریع Matrix و Telegram را اجرا میکند،
و برای بررسیهای انتقال انتشار از mock-openai/gpt-5.5 استفاده میکند تا قطعی بمانند
و از راهاندازی معمول Plugin ارائهدهنده پرهیز کنند. این Gatewayهای انتقال زنده
جستوجوی حافظه را غیرفعال میکنند؛ رفتار حافظه همچنان توسط مجموعههای برابری تضمین کیفیت
پوشش داده میشود.
شاردهای رسانهٔ زندهٔ انتشار کامل از
ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04 استفاده میکنند که از قبل
ffmpeg و ffprobe دارد. شاردهای مدل/Backend زندهٔ Docker از تصویر مشترک
ghcr.io/openclaw/openclaw-live-test:<sha> استفاده میکنند که برای هر commit انتخابشده یکبار ساخته میشود،
سپس بهجای ساخت دوباره در هر شارد، آن را با OPENCLAW_SKIP_DOCKER_BUILD=1 دریافت میکنند.
pnpm openclaw qa suite- سناریوهای QA متکی به مخزن را مستقیماً روی میزبان اجرا میکند.
- چند سناریوی انتخابشده را بهطور پیشفرض بهصورت موازی با workerهای Gateway
ایزوله اجرا میکند.
qa-channelبهطور پیشفرض همروندی 4 دارد (محدود به تعداد سناریوهای انتخابشده). برای تنظیم تعداد workerها از--concurrency <count>استفاده کنید، یا برای مسیر سریال قدیمیتر از--concurrency 1استفاده کنید. - وقتی هر سناریویی شکست بخورد با کد غیرصفر خارج میشود. وقتی artifactها را بدون
کد خروج شکستخورده میخواهید، از
--allow-failuresاستفاده کنید. - از حالتهای فراهمکننده
live-frontier،mock-openaiوaimockپشتیبانی میکند.aimockیک سرور فراهمکننده محلی مبتنی بر AIMock را برای پوشش آزمایشی fixture و mock پروتکل راهاندازی میکند، بدون اینکه مسیر آگاه از سناریویmock-openaiرا جایگزین کند.
pnpm test:plugins:kitchen-sink-live- آزمون سنگین Plugin زنده OpenAI Kitchen Sink را از طریق QA Lab اجرا میکند. این
بسته خارجی Kitchen Sink را نصب میکند، موجودی سطح plugin SDK را تأیید میکند،
/healthzو/readyzرا probe میکند، شواهد CPU/RSS مربوط به Gateway را ثبت میکند، یک نوبت زنده OpenAI را اجرا میکند، و عیبیابیهای adversarial را بررسی میکند. به احراز هویت زنده OpenAI مانندOPENAI_API_KEYنیاز دارد. در نشستهای Testbox آمادهسازیشده، وقتی helper مربوط بهopenclaw-testbox-envحاضر باشد، پروفایل احراز هویت زنده Testbox را بهطور خودکار source میکند.
- آزمون سنگین Plugin زنده OpenAI Kitchen Sink را از طریق QA Lab اجرا میکند. این
بسته خارجی Kitchen Sink را نصب میکند، موجودی سطح plugin SDK را تأیید میکند،
pnpm test:gateway:cpu-scenarios- benchmark راهاندازی Gateway بههمراه یک بسته کوچک سناریوی mock QA Lab
(
channel-chat-baseline،memory-failure-fallback،gateway-restart-inflight-run) را اجرا میکند و یک خلاصه ترکیبی از مشاهده CPU را زیر.artifacts/gateway-cpu-scenarios/مینویسد. - بهطور پیشفرض فقط مشاهدههای CPU داغ و پایدار را flag میکند (
--cpu-core-warnبههمراه--hot-wall-warn-ms)، بنابراین جهشهای کوتاه زمان راهاندازی بهعنوان metric ثبت میشوند بدون اینکه شبیه رگرسیون peg چنددقیقهای Gateway به نظر برسند. - از artifactهای ساختهشده
distاستفاده میکند؛ وقتی checkout از قبل خروجی runtime تازه ندارد، ابتدا build را اجرا کنید.
- benchmark راهاندازی Gateway بههمراه یک بسته کوچک سناریوی mock QA Lab
(
pnpm openclaw qa suite --runner multipass- همان مجموعه QA را داخل یک VM لینوکسی یکبارمصرف Multipass اجرا میکند.
- همان رفتار انتخاب سناریو را مانند
qa suiteروی میزبان نگه میدارد. - همان flagهای انتخاب فراهمکننده/مدل را مانند
qa suiteدوباره استفاده میکند. - اجراهای زنده ورودیهای احراز هویت QA پشتیبانیشدهای را که برای guest عملی هستند forward میکنند:
کلیدهای فراهمکننده مبتنی بر env، مسیر config فراهمکننده زنده QA، و
CODEX_HOMEوقتی حاضر باشد. - دایرکتوریهای خروجی باید زیر ریشه مخزن بمانند تا guest بتواند از طریق workspace mountشده به عقب بنویسد.
- گزارش و خلاصه معمول QA بههمراه logهای Multipass را زیر
.artifacts/qa-e2e/...مینویسد.
pnpm qa:lab:up- سایت QA مبتنی بر Docker را برای کار QA به سبک operator راهاندازی میکند.
pnpm test:docker:npm-onboard-channel-agent- یک tarball npm از checkout فعلی میسازد، آن را بهصورت global در Docker نصب میکند، onboarding غیرتعاملی با کلید API OpenAI را اجرا میکند، بهطور پیشفرض Telegram را پیکربندی میکند، تأیید میکند runtime مربوط به Plugin بستهبندیشده بدون repair وابستگی در زمان راهاندازی load میشود، doctor را اجرا میکند، و یک نوبت agent محلی را در برابر endpoint شبیهسازیشده OpenAI اجرا میکند.
- برای اجرای همان مسیر نصب بستهبندیشده با Discord از
OPENCLAW_NPM_ONBOARD_CHANNEL=discordاستفاده کنید.
pnpm test:docker:session-runtime-context- یک smoke قطعی Docker برای app ساختهشده و transcriptهای context runtime
embedded اجرا میکند. تأیید میکند context runtime پنهان OpenClaw بهجای نشت
به نوبت قابلمشاهده کاربر، بهعنوان یک پیام سفارشی غیرنمایشی persist میشود؛
سپس یک JSONL نشست خراب متأثر را seed میکند و تأیید میکند
openclaw doctor --fixآن را با backup به branch فعال بازنویسی میکند.
- یک smoke قطعی Docker برای app ساختهشده و transcriptهای context runtime
embedded اجرا میکند. تأیید میکند context runtime پنهان OpenClaw بهجای نشت
به نوبت قابلمشاهده کاربر، بهعنوان یک پیام سفارشی غیرنمایشی persist میشود؛
سپس یک JSONL نشست خراب متأثر را seed میکند و تأیید میکند
pnpm test:docker:npm-telegram-live- یک candidate بسته OpenClaw را در Docker نصب میکند، onboarding بسته نصبشده را اجرا میکند، Telegram را از طریق CLI نصبشده پیکربندی میکند، سپس مسیر QA زنده Telegram را با آن بسته نصبشده بهعنوان SUT Gateway دوباره استفاده میکند.
- wrapper فقط source مربوط به harness
qa-labرا از checkout mount میکند؛ بسته نصبشده مالکdist،openclaw/plugin-sdkو runtime مربوط به Pluginهای bundled است تا مسیر، Pluginهای checkout فعلی را با بسته در حال آزمون مخلوط نکند. - مقدار پیشفرض
OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@betaاست؛ برای آزمودن یک tarball محلی resolveشده بهجای نصب از registry،OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgzیاOPENCLAW_CURRENT_PACKAGE_TGZرا تنظیم کنید. - از همان credentialهای env مربوط به Telegram یا منبع credential مربوط به Convex
مانند
pnpm openclaw qa telegramاستفاده میکند. برای automation مربوط به CI/release،OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convexرا بههمراهOPENCLAW_QA_CONVEX_SITE_URLو secret نقش تنظیم کنید. اگرOPENCLAW_QA_CONVEX_SITE_URLو یک secret نقش Convex در CI حاضر باشند، wrapper مربوط به Docker بهطور خودکار Convex را انتخاب میکند. - wrapper پیش از کار build/install در Docker، env مربوط به credentialهای Telegram
یا Convex را روی میزبان اعتبارسنجی میکند. فقط وقتی عمداً در حال debug کردن
setup پیش از credential هستید،
OPENCLAW_NPM_TELEGRAM_SKIP_CREDENTIAL_PREFLIGHT=1را تنظیم کنید. OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainerفقط برای این مسیر،OPENCLAW_QA_CREDENTIAL_ROLEمشترک را override میکند.- GitHub Actions این مسیر را بهعنوان workflow دستی maintainer با نام
NPM Telegram Beta E2Eارائه میکند. روی merge اجرا نمیشود. این workflow از محیطqa-live-sharedو leaseهای credential مربوط به Convex CI استفاده میکند.
- GitHub Actions همچنین
Package Acceptanceرا برای اثبات محصول side-run در برابر یک بسته candidate ارائه میکند. یک ref مورداعتماد، spec منتشرشده npm، URL tarball HTTPS بههمراه SHA-256، یا artifact tarball از اجرای دیگر را میپذیرد،openclaw-current.tgzنرمالسازیشده را بهعنوانpackage-under-testupload میکند، سپس scheduler موجود Docker E2E را با پروفایلهای مسیر smoke، package، product، full یا custom اجرا میکند. برای اجرای workflow مربوط به Telegram QA در برابر همان artifact مربوط بهpackage-under-test،telegram_mode=mock-openaiیاlive-frontierرا تنظیم کنید.- اثبات محصول آخرین beta:
gh workflow run package-acceptance.yml --ref main \ -f source=npm \ -f package_spec=openclaw@beta \ -f suite_profile=product \ -f telegram_mode=mock-openai- اثبات URL دقیق tarball به digest نیاز دارد:
gh workflow run package-acceptance.yml --ref main \ -f source=url \ -f package_url=https://registry.npmjs.org/openclaw/-/openclaw-VERSION.tgz \ -f package_sha256=<sha256> \ -f suite_profile=package- اثبات artifact یک artifact از نوع tarball را از اجرای دیگر Actions دانلود میکند:
gh workflow run package-acceptance.yml --ref main \ -f source=artifact \ -f artifact_run_id=<run-id> \ -f artifact_name=<artifact-name> \ -f suite_profile=smoke-
pnpm test:docker:plugins- build فعلی OpenClaw را در Docker pack و install میکند، Gateway را با OpenAI پیکربندیشده راهاندازی میکند، سپس channel/Pluginهای bundled را از طریق ویرایش config فعال میکند.
- تأیید میکند discovery مربوط به setup، Pluginهای قابل دانلود پیکربندینشده را غایب نگه میدارد، اولین repair پیکربندیشده doctor هر Plugin قابل دانلود گمشده را بهطور صریح نصب میکند، و restart دوم repair پنهان وابستگی را اجرا نمیکند.
- همچنین یک baseline npm قدیمی شناختهشده را نصب میکند، پیش از اجرای
openclaw update --tag <candidate>، Telegram را فعال میکند، و تأیید میکند doctor پس از update مربوط به candidate، debris قدیمی وابستگی Plugin را بدون repair postinstall سمت harness پاک میکند.
-
pnpm test:parallels:npm-update-
smoke مربوط به update نصب بسته native را در guestهای Parallels اجرا میکند. هر platform انتخابشده ابتدا بسته baseline درخواستشده را نصب میکند، سپس دستور نصبشده
openclaw updateرا در همان guest اجرا میکند و نسخه نصبشده، وضعیت update، آمادگی Gateway و یک نوبت agent محلی را تأیید میکند. -
هنگام iterate روی یک guest، از
--platform macos،--platform windowsیا--platform linuxاستفاده کنید. برای مسیر artifact خلاصه و وضعیت هر مسیر از--jsonاستفاده کنید. -
مسیر OpenAI بهطور پیشفرض از
openai/gpt-5.5برای اثبات نوبت agent زنده استفاده میکند. وقتی عمداً مدل OpenAI دیگری را اعتبارسنجی میکنید،--model <provider/model>را pass کنید یاOPENCLAW_PARALLELS_OPENAI_MODELرا تنظیم کنید. -
اجراهای محلی طولانی را در timeout میزبان wrap کنید تا stallهای transport مربوط به Parallels نتوانند باقی پنجره testing را مصرف کنند:
bash timeout --foreground 150m pnpm test:parallels:npm-update -- --jsontimeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json -
script، logهای nested هر مسیر را زیر
/tmp/openclaw-parallels-npm-update.*مینویسد. پیش از فرض کردن hung بودن wrapper بیرونی،windows-update.log،macos-update.logیاlinux-update.logرا بررسی کنید. -
update ویندوز روی یک guest سرد میتواند 10 تا 15 دقیقه را در doctor پس از update و کار update بسته صرف کند؛ وقتی log debug nested مربوط به npm در حال پیشروی است، این وضعیت همچنان سالم است.
-
این wrapper تجمیعی را بهصورت موازی با مسیرهای smoke جداگانه Parallels مربوط به macOS، Windows یا Linux اجرا نکنید. آنها state مربوط به VM را به اشتراک میگذارند و میتوانند در restore کردن snapshot، سرو کردن بسته، یا state مربوط به Gateway در guest با هم برخورد کنند.
-
اثبات پس از update سطح معمول Pluginهای bundled را اجرا میکند، چون facadeهای capability مانند گفتار، تولید تصویر، و درک رسانه از طریق APIهای runtime bundled load میشوند، حتی وقتی خود نوبت agent فقط یک پاسخ متنی ساده را بررسی میکند.
-
-
pnpm openclaw qa aimock- فقط سرور فراهمکننده محلی AIMock را برای smoke testing مستقیم پروتکل راهاندازی میکند.
-
pnpm openclaw qa matrix- مسیر QA زنده Matrix را در برابر یک homeserver یکبارمصرف Tuwunel مبتنی بر Docker اجرا میکند. فقط source-checkout - نصبهای بستهبندیشده
qa-labرا ship نمیکنند. - CLI کامل، کاتالوگ پروفایل/سناریو، env varها و layout مربوط به artifact: Matrix QA.
- مسیر QA زنده Matrix را در برابر یک homeserver یکبارمصرف Tuwunel مبتنی بر Docker اجرا میکند. فقط source-checkout - نصبهای بستهبندیشده
-
pnpm openclaw qa telegram- مسیر QA زنده Telegram را در برابر یک گروه خصوصی واقعی با استفاده از tokenهای driver و bot مربوط به SUT از env اجرا میکند.
- به
OPENCLAW_QA_TELEGRAM_GROUP_ID،OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKENوOPENCLAW_QA_TELEGRAM_SUT_BOT_TOKENنیاز دارد. شناسه گروه باید شناسه عددی chat در Telegram باشد. - از
--credential-source convexبرای credentialهای pooled مشترک پشتیبانی میکند. بهطور پیشفرض از حالت env استفاده کنید، یا برای opt in به leaseهای pooled،OPENCLAW_QA_CREDENTIAL_SOURCE=convexرا تنظیم کنید. - پیشفرضها canary، mention gating، command addressing،
/status، پاسخهای mentionشده bot-to-bot و پاسخهای فرمان native هسته را پوشش میدهند. پیشفرضهایmock-openaiهمچنین رگرسیونهای قطعی reply-chain و streaming پیام نهایی Telegram را پوشش میدهند. برای probeهای اختیاری مانندsession_statusاز--list-scenariosاستفاده کنید. - وقتی هر سناریویی شکست بخورد با کد غیرصفر خارج میشود. وقتی artifactها را بدون کد خروج شکستخورده میخواهید، از
--allow-failuresاستفاده کنید. - به دو bot متمایز در همان گروه خصوصی نیاز دارد، و bot مربوط به SUT باید یک username در Telegram ارائه کند.
- برای مشاهده پایدار bot-to-bot، Bot-to-Bot Communication Mode را در
@BotFatherبرای هر دو bot فعال کنید و مطمئن شوید bot مربوط به driver میتواند ترافیک bot گروه را مشاهده کند. - یک گزارش QA مربوط به Telegram، خلاصه، و artifact پیامهای مشاهدهشده را زیر
.artifacts/qa-e2e/...مینویسد. سناریوهای پاسخدهنده شامل RTT از درخواست ارسال driver تا پاسخ مشاهدهشده SUT هستند.
Mantis Telegram Live wrapper شواهد PR پیرامون این مسیر است. ref مربوط به
candidate را با credentialهای Telegram leaseشده از Convex اجرا میکند، transcript
پیام مشاهدهشده redactشده را در یک مرورگر دسکتاپ Crabbox render میکند، شواهد MP4
را ضبط میکند، یک GIF motion-trimmed تولید میکند، bundle مربوط به artifact را
upload میکند، و وقتی pr_number تنظیم شده باشد، شواهد inline PR را از طریق GitHub App
مربوط به Mantis post میکند. maintainerها میتوانند آن را از UI مربوط به Actions از
طریق Mantis Scenario (scenario_id: telegram-live) یا مستقیماً از یک comment روی pull request شروع کنند:
@Mantis telegram@Mantis telegram scenario=telegram-status-command@Mantis telegram scenarios=telegram-status-command,telegram-mentioned-message-replyMantis Telegram Desktop Proof wrapper agentic native Telegram Desktop برای
اثبات بصری پیش/پس از PR است. آن را از UI مربوط به Actions با instructions آزاد،
از طریق Mantis Scenario (scenario_id: telegram-desktop-proof) یا از یک comment روی PR شروع کنید:
@Mantis telegram desktop proofعامل Mantis، PR را میخواند، تصمیم میگیرد چه رفتار قابلمشاهدهای در Telegram تغییر را اثبات میکند، مسیر اثبات Crabbox Telegram Desktop با کاربر واقعی را روی ارجاعهای baseline و candidate اجرا میکند، تا زمانی که GIFهای بومی مفید شوند تکرار میکند، یک مانیفست جفتشدهٔ motionPreview مینویسد، و وقتی pr_number تنظیم شده باشد، همان جدول GIF دو ستونه را از طریق Mantis GitHub App ارسال میکند.
pnpm openclaw qa mantis telegram-desktop-builder- یک دسکتاپ لینوکسی Crabbox را اجاره میکند یا دوباره به کار میبرد، Telegram Desktop بومی را نصب میکند، OpenClaw را با توکن بات SUT اجارهشدهٔ Telegram پیکربندی میکند، Gateway را راهاندازی میکند، و شواهد اسکرینشات/MP4 را از دسکتاپ VNC قابلمشاهده ضبط میکند.
- مقدار پیشفرض
--credential-source convexاست تا workflowها فقط به راز broker متعلق به Convex نیاز داشته باشند. از--credential-source envبا همان متغیرهایOPENCLAW_QA_TELEGRAM_*که درpnpm openclaw qa telegramاستفاده میشوند استفاده کنید. - Telegram Desktop همچنان به ورود/پروفایل کاربر نیاز دارد. توکن بات فقط OpenClaw را پیکربندی میکند. برای یک آرشیو پروفایل
.tgzبا base64 از--telegram-profile-archive-env <name>استفاده کنید، یا از--keep-leaseاستفاده کنید و یکبار از طریق VNC بهصورت دستی وارد شوید. - فایلهای
mantis-telegram-desktop-builder-report.md،mantis-telegram-desktop-builder-summary.json،telegram-desktop-builder.png، وtelegram-desktop-builder.mp4را زیر پوشهٔ خروجی مینویسد.
مسیرهای انتقال زنده یک قرارداد استاندارد مشترک دارند تا انتقالهای جدید دچار انحراف نشوند؛ ماتریس پوشش هر مسیر در نمای کلی QA ← پوشش انتقال زنده قرار دارد. qa-channel مجموعهٔ ترکیبی گسترده است و بخشی از آن ماتریس نیست.
اعتبارنامههای مشترک Telegram از طریق Convex (v1)
وقتی --credential-source convex (یا OPENCLAW_QA_CREDENTIAL_SOURCE=convex) برای QA انتقال زنده فعال باشد، QA lab یک lease انحصاری از یک pool پشتیبانیشده با Convex دریافت میکند، تا وقتی مسیر در حال اجراست برای آن lease Heartbeat میفرستد، و هنگام خاموشی lease را آزاد میکند. نام این بخش قدیمیتر از پشتیبانی Discord، Slack و WhatsApp است؛ قرارداد lease میان kindها مشترک است.
اسکلت پروژهٔ مرجع Convex:
qa/convex-credential-broker/
متغیرهای env ضروری:
OPENCLAW_QA_CONVEX_SITE_URL(برای مثالhttps://your-deployment.convex.site)- یک راز برای نقش انتخابشده:
OPENCLAW_QA_CONVEX_SECRET_MAINTAINERبرایmaintainerOPENCLAW_QA_CONVEX_SECRET_CIبرایci
- انتخاب نقش اعتبارنامه:
- CLI:
--credential-role maintainer|ci - مقدار پیشفرض env:
OPENCLAW_QA_CREDENTIAL_ROLE(در CI بهصورت پیشفرضciاست، و در غیر این صورتmaintainer)
- CLI:
متغیرهای 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_OWNER_ID(شناسهٔ trace اختیاری)OPENCLAW_QA_ALLOW_INSECURE_HTTP=1اجازه میدهد برای توسعهٔ فقط محلی از URLهای Convex با loopbackhttp://استفاده شود.
OPENCLAW_QA_CONVEX_SITE_URL در عملیات عادی باید از https:// استفاده کند.
دستورهای مدیریتی maintainer (افزودن/حذف/فهرست کردن pool) مشخصا به OPENCLAW_QA_CONVEX_SECRET_MAINTAINER نیاز دارند.
ابزارهای کمکی CLI برای maintainerها:
pnpm openclaw qa credentials doctorpnpm openclaw qa credentials add --kind telegram --payload-file qa/telegram-credential.jsonpnpm openclaw qa credentials list --kind telegrampnpm openclaw qa credentials remove --credential-id <credential-id>پیش از اجراهای زنده از doctor استفاده کنید تا URL سایت Convex، رازهای broker، prefix endpoint، timeout HTTP، و دسترسیپذیری admin/list را بدون چاپ مقادیر راز بررسی کنید. برای خروجی قابلخواندن توسط ماشین در اسکریپتها و ابزارهای CI از --json استفاده کنید.
قرارداد endpoint پیشفرض (OPENCLAW_QA_CONVEX_SITE_URL + /qa-credentials/v1):
POST /acquire- درخواست:
{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs } - موفقیت:
{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? } - تمامشده/قابلتلاش دوباره:
{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }
- درخواست:
POST /payload-chunk- درخواست:
{ kind, ownerId, actorRole, credentialId, leaseToken, index } - موفقیت:
{ status: "ok", index, data }
- درخواست:
POST /heartbeat- درخواست:
{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs } - موفقیت:
{ status: "ok" }(یا2xxخالی)
- درخواست:
POST /release- درخواست:
{ kind, ownerId, actorRole, credentialId, leaseToken } - موفقیت:
{ status: "ok" }(یا2xxخالی)
- درخواست:
POST /admin/add(فقط راز maintainer)- درخواست:
{ kind, actorId, payload, note?, status? } - موفقیت:
{ status: "ok", credential }
- درخواست:
POST /admin/remove(فقط راز maintainer)- درخواست:
{ credentialId, actorId } - موفقیت:
{ status: "ok", changed, credential } - محافظ lease فعال:
{ status: "error", code: "LEASE_ACTIVE", ... }
- درخواست:
POST /admin/list(فقط راز maintainer)- درخواست:
{ kind?, status?, includePayload?, limit? } - موفقیت:
{ status: "ok", credentials, count }
- درخواست:
شکل payload برای kind مربوط به Telegram:
{ groupId: string, driverToken: string, sutToken: string }groupIdباید یک رشتهٔ عددی برای شناسهٔ چت Telegram باشد.admin/addاین شکل را برایkind: "telegram"اعتبارسنجی میکند و payloadهای بدشکل را رد میکند.
شکل payload برای kind مربوط به کاربر واقعی Telegram:
{ groupId: string, sutToken: string, testerUserId: string, testerUsername: string, telegramApiId: string, telegramApiHash: string, tdlibDatabaseEncryptionKey: string, tdlibArchiveBase64: string, tdlibArchiveSha256: string, desktopTdataArchiveBase64: string, desktopTdataArchiveSha256: string }groupId،testerUserId، وtelegramApiIdباید رشتههای عددی باشند.tdlibArchiveSha256وdesktopTdataArchiveSha256باید رشتههای hex مربوط به SHA-256 باشند.kind: "telegram-user"نمایندهٔ یک حساب burner در Telegram است. lease را در سطح کل حساب در نظر بگیرید: درایور CLI متعلق به TDLib و شاهد تصویری Telegram Desktop از همان payload بازیابی میشوند، و در هر لحظه فقط یک job باید lease را نگه دارد.
بازیابی lease کاربر واقعی Telegram:
tmp=$(mktemp -d /tmp/openclaw-telegram-user.XXXXXX)node --import tsx scripts/e2e/telegram-user-credential.ts lease-restore \ --user-driver-dir "$tmp/user-driver" \ --desktop-workdir "$tmp/desktop" \ --lease-file "$tmp/lease.json"TELEGRAM_USER_DRIVER_STATE_DIR="$tmp/user-driver" \ uv run ~/.codex/skills/custom/telegram-e2e-bot-to-bot/scripts/user-driver.py status --jsonnode --import tsx scripts/e2e/telegram-user-credential.ts release --lease-file "$tmp/lease.json"وقتی ضبط تصویری لازم است، از پروفایل Desktop بازیابیشده با Telegram -workdir "$tmp/desktop" استفاده کنید. در محیطهای operator محلی، اگر متغیرهای env مربوط به process وجود نداشته باشند، scripts/e2e/telegram-user-credential.ts بهصورت پیشفرض ~/.codex/skills/custom/telegram-e2e-bot-to-bot/convex.local.env را میخواند.
جلسهٔ Crabbox هدایتشده توسط عامل:
pnpm qa:telegram-user:crabbox -- start \ --tdlib-url http://artifacts.openclaw.ai/tdlib-v1.8.0-linux-x64.tgz \ --output-dir .artifacts/qa-e2e/telegram-user-crabbox/pr-reviewpnpm qa:telegram-user:crabbox -- send \ --session .artifacts/qa-e2e/telegram-user-crabbox/pr-review/session.json \ --text /statuspnpm qa:telegram-user:crabbox -- finish \ --session .artifacts/qa-e2e/telegram-user-crabbox/pr-review/session.jsonstart اعتبارنامهٔ telegram-user را lease میکند، همان حساب را در TDLib و Telegram Desktop روی یک دسکتاپ لینوکسی Crabbox بازیابی میکند، یک Gateway محلی mock SUT را از checkout فعلی راهاندازی میکند، چت Telegram قابلمشاهده را باز میکند، ضبط دسکتاپ را شروع میکند، و یک session.json خصوصی مینویسد. تا وقتی جلسه زنده است، یک عامل میتواند تا زمان رضایت کامل به آزمایش ادامه دهد:
send --session <file> --text <message>از طریق کاربر واقعی TDLib ارسال میکند و منتظر پاسخ SUT میماند.run --session <file> -- <remote command>یک فرمان دلخواه را روی Crabbox اجرا میکند و خروجی آن را ذخیره میکند، برای مثالbash -lc 'source /tmp/openclaw-telegram-user-crabbox/env.sh && python3 /tmp/openclaw-telegram-user-crabbox/user-driver.py transcript --limit 20 --json'.screenshot --session <file>دسکتاپ قابلمشاهدهٔ فعلی را capture میکند.status --session <file>فرمان lease و WebVNC را چاپ میکند.finish --session <file>ضبطکننده را متوقف میکند، اسکرینشات/ویدیو/آرتیفکتهای motion-trim را capture میکند، اعتبارنامهٔ Convex را آزاد میکند، پردازههای SUT محلی را متوقف میکند، و lease مربوط به Crabbox را متوقف میکند مگر اینکه--keep-boxداده شده باشد.publish --session <file> --pr <number>بهصورت پیشفرض یک نظر PR فقط شامل GIF منتشر میکند.--full-artifactsرا فقط وقتی ارسال کنید که logها یا آرتیفکتهای JSON عمدا لازم باشند.
برای بازتولیدهای تصویری deterministic، --mock-response-file <path> را به start یا به shorthand تکفرمانی probe بدهید. runner بهصورت پیشفرض از کلاس استاندارد Crabbox، ضبط 24fps، پیشنمایشهای GIF حرکتی 24fps، و عرض GIF برابر 1920px استفاده میکند. فقط وقتی اثبات به تنظیمات capture متفاوت نیاز دارد، با --class، --record-fps، --preview-fps، و --preview-width بازنویسی کنید.
اثبات Crabbox تکفرمانی:
pnpm qa:telegram-user:crabbox -- --text /statusفرمان پیشفرض probe خلاصهای برای یک چرخهٔ start/send/finish است. از آن برای یک smoke سریع /status استفاده کنید. برای بازبینی PR، کار بازتولید باگ، یا هر موردی که عامل پیش از تصمیمگیری دربارهٔ کامل بودن اثبات به چند دقیقه آزمایش دلخواه نیاز دارد، از فرمانهای جلسه استفاده کنید. برای استفادهٔ دوباره از یک lease دسکتاپ گرم از --id <cbx_...> استفاده کنید، برای باز نگه داشتن VNC پس از finish از --keep-box، برای انتخاب چت قابلمشاهده از --desktop-chat-title <name>، و وقتی بهجای ساخت TDLib روی یک box تازه از آرشیو لینوکسی از پیش آمادهشدهٔ libtdjson.so استفاده میکنید از --tdlib-url <tgz> استفاده کنید. runner مقدار --tdlib-url را با --tdlib-sha256 <hex> یا، بهصورت پیشفرض، با فایل همخانوادهٔ <url>.sha256 بررسی میکند.
payloadهای چندکانالهٔ اعتبارسنجیشده توسط broker:
- Discord:
{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string, voiceChannelId?: string } - WhatsApp:
{ driverPhoneE164: string, sutPhoneE164: string, driverAuthArchiveBase64: string, sutAuthArchiveBase64: string, groupJid?: string }
مسیرهای Slack نیز میتوانند از pool اجاره کنند، اما اعتبارسنجی payload در حال حاضر بهجای broker در runner مربوط به QA برای Slack قرار دارد. برای ردیفهای Slack از { channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string } استفاده کنید.
افزودن یک کانال به QA
نامهای معماری و scenario-helper برای adapterهای کانال جدید در نمای کلی QA ← افزودن یک کانال قرار دارند. حداقل معیار: runner انتقال را روی seam میزبان مشترک qa-lab پیادهسازی کنید، qaRunners را در مانیفست Plugin اعلام کنید، آن را بهصورت openclaw qa <runner> mount کنید، و scenarioها را زیر qa/scenarios/ بنویسید.
مجموعههای آزمون (چه چیزی کجا اجرا میشود)
suiteها را بهعنوان «واقعگرایی افزایشی» در نظر بگیرید (و همچنین flakiness/هزینهٔ افزایشی):
Unit / integration (پیشفرض)
- فرمان:
pnpm test - پیکربندی: اجراهای بدون هدف از مجموعهٔ shard با
vitest.full-*.config.tsاستفاده میکنند و ممکن است shardهای چندپروژهای را برای زمانبندی موازی به پیکربندیهای هر پروژه گسترش دهند - فایلها: inventoryهای core/unit زیر
src/**/*.test.ts،packages/**/*.test.ts، وtest/**/*.test.ts؛ آزمونهای unit مربوط به UI در shard اختصاصیunit-uiاجرا میشوند - دامنه:
- آزمونهای unit خالص
- آزمونهای integration درونپردازهای (احراز هویت Gateway، مسیریابی، ابزارها، parsing، config)
- regressionهای deterministic برای باگهای شناختهشده
- انتظارات:
- در CI اجرا میشود
- به کلیدهای واقعی نیاز ندارد
- باید سریع و پایدار باشد
- آزمونهای resolver و loader سطح عمومی باید رفتار fallback گستردهٔ
api.jsوruntime-api.jsرا با fixtureهای کوچک تولیدشدهٔ Plugin ثابت کنند، نه با APIهای منبع Pluginهای واقعی bundled. بارگذاری API مربوط به Plugin واقعی به suiteهای contract/integration تحت مالکیت Plugin تعلق دارد.
سیاست dependency بومی:
- نصبهای آزمون پیشفرض، ساختهای native اختیاری Discord opus را رد میکنند. دریافت صدای Discord از رمزگشای pure-JS
opusscriptاستفاده میکند، و@discordjs/opusدرallowBuildsغیرفعال میماند تا آزمونهای محلی و مسیرهای Testbox افزونه native را کامپایل نکنند. - اگر عمداً لازم است یک ساخت native opus را مقایسه کنید، از یک مسیر اختصاصی عملکرد صدای Discord یا مسیر live استفاده کنید.
@discordjs/opusرا درallowBuildsپیشفرض رویtrueتنظیم نکنید؛ این کار باعث میشود چرخههای نصب/آزمون نامرتبط، کد native را کامپایل کنند.
پروژهها، shardها، و مسیرهای scoped
pnpm testبدون هدفگذاری، بهجای یک فرایند عظیم native برای پروژه ریشه، دوازده پیکربندی 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) را اجرا میکند. این کار اوج RSS را روی ماشینهای پربار کاهش میدهد و از اینکه کارهای auto-reply/extension مجموعههای نامرتبط را گرسنه کنند جلوگیری میکند.pnpm test --watchهمچنان از گراف پروژه native ریشهvitest.config.tsاستفاده میکند، چون یک چرخه watch چند-shard عملی نیست.pnpm test،pnpm test:watch، وpnpm test:perf:importsهدفهای صریح فایل/دایرکتوری را ابتدا از مسیرهای scoped عبور میدهند، بنابراینpnpm test extensions/discord/src/monitor/message-handler.preflight.test.tsهزینه شروع کامل پروژه ریشه را نمیپردازد.pnpm test:changedمسیرهای git تغییرکرده را بهطور پیشفرض به مسیرهای scoped ارزان گسترش میدهد: ویرایشهای مستقیم آزمون، فایلهای همخانواده*.test.ts، نگاشتهای صریح منبع، و وابستههای محلی گراف import. ویرایشهای config/setup/package آزمونها را بهصورت گسترده اجرا نمیکنند، مگر اینکه صریحاً ازOPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changedاستفاده کنید.pnpm check:changedدروازه معمول بررسی محلی هوشمند برای کارهای محدود است. این دستور diff را به core، آزمونهای core، extensions، آزمونهای extension، apps، docs، فراداده انتشار، ابزار live Docker، و tooling طبقهبندی میکند، سپس دستورهای typecheck، lint، و guard متناظر را اجرا میکند. آزمونهای Vitest را اجرا نمیکند؛ برای اثبات آزمون،pnpm test:changedیاpnpm test <target>صریح را فراخوانی کنید. افزایش نسخههایی که فقط فراداده انتشار را تغییر میدهند، بررسیهای هدفمند version/config/root-dependency را اجرا میکنند، همراه با guardای که تغییرات package خارج از فیلد version سطح بالا را رد میکند.- ویرایشهای harness مربوط به live Docker ACP بررسیهای متمرکز اجرا میکنند: syntax پوسته برای اسکریپتهای auth مربوط به live Docker و یک dry-run زمانبند live Docker. تغییرات
package.jsonفقط وقتی شامل میشوند که diff بهscripts["test:docker:live-*"]محدود باشد؛ ویرایشهای dependency، export، version، و دیگر سطوح package همچنان از guardهای گستردهتر استفاده میکنند. - آزمونهای واحد سبک از نظر import از agents، commands، plugins، helperهای auto-reply،
plugin-sdk، و نواحی utility خالص مشابه، از مسیرunit-fastعبور میکنند کهtest/setup-openclaw-runtime.tsرا رد میکند؛ فایلهای stateful/runtime-heavy روی مسیرهای موجود باقی میمانند. - فایلهای منبع helper منتخب در
plugin-sdkوcommandsنیز اجراهای changed-mode را به آزمونهای همخانواده صریح در همان مسیرهای سبک نگاشت میکنند، بنابراین ویرایشهای helper از اجرای دوباره کل مجموعه سنگین آن دایرکتوری پرهیز میکنند. auto-replybucketهای اختصاصی برای helperهای core سطح بالا، آزمونهای integration سطح بالایreply.*، و زیرشاخهsrc/auto-reply/reply/**دارد. CI زیرشاخه reply را بیشتر به shardهای agent-runner، dispatch، و commands/state-routing تقسیم میکند تا یک bucket سنگین از نظر import مالک کل دنباله Node نباشد.- CI عادی PR/main عمداً sweep دستهای extension و shard فقط-انتشار
agentic-pluginsرا رد میکند. Full Release Validation گردشکار فرزند جداگانهPlugin Prereleaseرا برای آن مجموعههای سنگین plugin/extension روی نامزدهای انتشار dispatch میکند.
پوشش runner جاسازیشده
- وقتی ورودیهای کشف message-tool یا context زمان اجرای compaction را تغییر میدهید، هر دو سطح پوشش را نگه دارید.
- regressionهای متمرکز helper را برای مرزهای routing و normalization خالص اضافه کنید.
- مجموعههای integration مربوط به 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 و رفتار compaction همچنان
از مسیرهای واقعی
run.ts/compact.tsعبور میکنند؛ آزمونهای فقط-helper جایگزین کافی برای آن مسیرهای integration نیستند.
پیشفرضهای pool و isolation در Vitest
- پیکربندی پایه Vitest بهطور پیشفرض از
threadsاستفاده میکند. - پیکربندی مشترک Vitest مقدار
isolate: falseرا ثابت میکند و از runner non-isolated در پروژههای ریشه، e2e، و پیکربندیهای live استفاده میکند. - مسیر UI ریشه، setup و optimizer مربوط به
jsdomخود را نگه میدارد، اما آن هم روی runner مشترک non-isolated اجرا میشود. - هر shard از
pnpm testهمان پیشفرضهایthreads+isolate: falseرا از پیکربندی مشترک Vitest به ارث میبرد. scripts/run-vitest.mjsبهطور پیشفرض--no-maglevرا برای فرایندهای فرزند Node مربوط به Vitest اضافه میکند تا churn کامپایل V8 در اجراهای محلی بزرگ کاهش یابد. برای مقایسه با رفتار استاندارد V8،OPENCLAW_VITEST_ENABLE_MAGLEV=1را تنظیم کنید.
تکرار سریع محلی
pnpm changed:lanesنشان میدهد یک diff کدام مسیرهای معماری را فعال میکند.- hook مربوط به pre-commit فقط قالببندی انجام میدهد. فایلهای قالببندیشده را دوباره stage میکند و lint، typecheck، یا آزمون اجرا نمیکند.
- وقتی پیش از handoff یا push به دروازه بررسی محلی هوشمند نیاز دارید،
pnpm check:changedرا صریحاً اجرا کنید. pnpm test:changedبهطور پیشفرض از مسیرهای scoped ارزان عبور میکند. فقط وقتی agent تصمیم میگیرد یک ویرایش harness، config، package، یا contract واقعاً به پوشش گستردهتر Vitest نیاز دارد، ازOPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changedاستفاده کنید.pnpm test:maxوpnpm test:changed:maxهمان رفتار routing را نگه میدارند، فقط با سقف worker بالاتر.- auto-scaling محلی worker عمداً محافظهکارانه است و وقتی میانگین بار host از قبل بالا باشد عقبنشینی میکند، بنابراین چند اجرای همزمان Vitest بهطور پیشفرض آسیب کمتری میزنند.
- پیکربندی پایه Vitest، پروژهها/فایلهای config را بهعنوان
forceRerunTriggersعلامتگذاری میکند تا rerunهای changed-mode هنگام تغییر wiring آزمون درست بمانند. - پیکربندی،
OPENCLAW_VITEST_FS_MODULE_CACHEرا روی hostهای پشتیبانیشده فعال نگه میدارد؛ اگر یک مکان cache صریح برای profiling مستقیم میخواهید،OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/pathرا تنظیم کنید.
اشکالزدایی عملکرد
pnpm test:perf:importsگزارش مدتزمان import در Vitest بههمراه خروجی import-breakdown را فعال میکند.pnpm test:perf:imports:changedهمان نمای profiling را به فایلهای تغییرکرده از زمانorigin/mainمحدود میکند.- دادههای زمانبندی shard در
.artifacts/vitest-shard-timings.jsonنوشته میشود. اجراهای whole-config از مسیر config بهعنوان key استفاده میکنند؛ shardهای CI مبتنی بر include-pattern نام shard را اضافه میکنند تا shardهای فیلترشده جداگانه قابل ردیابی باشند. - وقتی یک آزمون داغ همچنان بیشتر زمان خود را در importهای startup صرف میکند،
وابستگیهای سنگین را پشت یک seam محلی باریک
*.runtime.tsنگه دارید و همان seam را مستقیماً mock کنید، بهجای اینکه helperهای runtime را فقط برای عبور دادن ازvi.mock(...)بهصورت deep-import وارد کنید. pnpm test:perf:changed:bench -- --ref <git-ref>مسیرtest:changedrouted را با مسیر native root-project برای آن diff commitشده مقایسه میکند و wall time بههمراه max RSS در macOS را چاپ میکند.pnpm test:perf:changed:bench -- --worktreeدرخت dirty فعلی را با routing فهرست فایلهای تغییرکرده از طریقscripts/test-projects.mjsو پیکربندی ریشه Vitest benchmark میکند.pnpm test:perf:profile:mainیک profile CPU از main-thread برای سربار startup و transform در Vitest/Vite مینویسد.pnpm test:perf:profile:runnerprofileهای CPU+heap مربوط به runner را برای مجموعه unit با file parallelism غیرفعال مینویسد.
پایداری (gateway)
- دستور:
pnpm test:stability:gateway - پیکربندی:
vitest.gateway.config.ts، اجباراً با یک worker - محدوده:
- یک Gateway واقعی loopback را با diagnostics فعال بهطور پیشفرض شروع میکند
- churn مربوط به پیام gateway مصنوعی، memory، و payloadهای بزرگ را از مسیر diagnostic event عبور میدهد
diagnostics.stabilityرا از طریق Gateway WS RPC query میکند- helperهای persistence مربوط به diagnostic stability bundle را پوشش میدهد
- assert میکند recorder محدود باقی میماند، نمونههای RSS مصنوعی زیر budget فشار میمانند، و عمق صفهای per-session به صفر برمیگردند
- انتظارات:
- برای CI امن است و به key نیاز ندارد
- مسیر محدود برای پیگیری regression پایداری است، نه جایگزین مجموعه کامل Gateway
E2E (smoke مربوط به gateway)
- دستور:
pnpm test:e2e - پیکربندی:
vitest.e2e.config.ts - فایلها:
src/**/*.e2e.test.ts،test/**/*.e2e.test.ts، و آزمونهای E2E مربوط به bundled-plugin زیرextensions/ - پیشفرضهای runtime:
- از
threadsدر Vitest باisolate: falseاستفاده میکند، مطابق با بقیه repo. - از workerهای adaptive استفاده میکند (CI: تا 2، محلی: پیشفرض 1).
- بهطور پیشفرض در silent mode اجرا میشود تا سربار console I/O کاهش یابد.
- از
- overrideهای مفید:
OPENCLAW_E2E_WORKERS=<n>برای اجبار تعداد workerها (با سقف 16).OPENCLAW_E2E_VERBOSE=1برای فعالسازی دوباره خروجی verbose console.
- محدوده:
- رفتار end-to-end مربوط به multi-instance gateway
- سطوح WebSocket/HTTP، pairing گرهها، و شبکهسازی سنگینتر
- انتظارات:
- در CI اجرا میشود (وقتی در pipeline فعال باشد)
- به key واقعی نیاز ندارد
- قطعات متحرک بیشتری نسبت به آزمونهای unit دارد (میتواند کندتر باشد)
E2E: smoke مربوط به backend OpenShell
- دستور:
pnpm test:e2e:openshell - فایل:
extensions/openshell/src/backend.e2e.test.ts - محدوده:
- یک OpenShell gateway ایزوله را از طریق Docker روی host شروع میکند
- یک sandbox از یک Dockerfile محلی موقت میسازد
- backend OpenShell در OpenClaw را از طریق
sandbox ssh-configواقعی + اجرای SSH تمرین میدهد - رفتار filesystem با canonical remote را از طریق sandbox fs bridge تأیید میکند
- انتظارات:
- فقط opt-in است؛ بخشی از اجرای پیشفرض
pnpm test:e2eنیست - به یک CLI محلی
openshellو یک Docker daemon فعال نیاز دارد - از
HOME/XDG_CONFIG_HOMEایزوله استفاده میکند، سپس test gateway و sandbox را نابود میکند
- فقط opt-in است؛ بخشی از اجرای پیشفرض
- overrideهای مفید:
OPENCLAW_E2E_OPENSHELL=1برای فعالسازی آزمون هنگام اجرای دستی مجموعه گستردهتر e2eOPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshellبرای اشاره به binary یا wrapper script غیرپیشفرض CLI
Live (ارائهدهندگان واقعی + مدلهای واقعی)
- دستور:
pnpm test:live - پیکربندی:
vitest.live.config.ts - فایلها:
src/**/*.live.test.ts،test/**/*.live.test.ts، و آزمونهای زندهی Pluginهای همراه زیرextensions/ - پیشفرض: با
pnpm test:liveفعال است (OPENCLAW_LIVE_TEST=1را تنظیم میکند) - دامنه:
- «آیا این ارائهدهنده/مدل واقعاً امروز با اعتبارنامههای واقعی کار میکند؟»
- تشخیص تغییرات قالب ارائهدهنده، ریزهکاریهای فراخوانی ابزار، مشکلات احراز هویت، و رفتار محدودیت نرخ
- انتظارات:
- عمداً پایدار برای CI نیست (شبکههای واقعی، سیاستهای واقعی ارائهدهندگان، سهمیهها، قطعیها)
- هزینه دارد / از محدودیتهای نرخ استفاده میکند
- اجرای زیرمجموعههای محدودشده را به «همهچیز» ترجیح دهید
- اجراهای زنده برای برداشتن کلیدهای API جاافتاده،
~/.profileرا source میکنند. - بهطور پیشفرض، اجراهای زنده همچنان
HOMEرا ایزوله میکنند و مواد پیکربندی/احراز هویت را در یک خانهی آزمون موقت کپی میکنند تا fixtureهای واحد نتوانند~/.openclawواقعی شما را تغییر دهند. - فقط زمانی
OPENCLAW_LIVE_USE_REAL_HOME=1را تنظیم کنید که عمداً نیاز دارید آزمونهای زنده از دایرکتوری خانهی واقعی شما استفاده کنند. pnpm test:liveاکنون بهصورت پیشفرض در حالت کمصداتری اجرا میشود: خروجی پیشرفت[live] ...را نگه میدارد، اما اعلان اضافی~/.profileرا پنهان میکند و لاگهای bootstrap Gateway/گفتوگوی Bonjour را بیصدا میکند. اگر میخواهید لاگهای کامل راهاندازی برگردند،OPENCLAW_LIVE_TEST_QUIET=0را تنظیم کنید.- چرخش کلید API (ویژهی ارائهدهنده):
*_API_KEYSرا با قالب کاما/نقطهویرگول یا*_API_KEY_1،*_API_KEY_2تنظیم کنید (برای مثالOPENAI_API_KEYS،ANTHROPIC_API_KEYS،GEMINI_API_KEYS) یا override مخصوص زنده را از طریقOPENCLAW_LIVE_*_KEYبدهید؛ آزمونها در پاسخهای محدودیت نرخ دوباره تلاش میکنند. - خروجی پیشرفت/Heartbeat:
- suiteهای زنده اکنون خطهای پیشرفت را به stderr میفرستند تا فراخوانیهای طولانی ارائهدهنده حتی وقتی capture کنسول Vitest کمصداست، بهصورت قابل مشاهده فعال باشند.
vitest.live.config.tsرهگیری کنسول Vitest را غیرفعال میکند تا خطهای پیشرفت ارائهدهنده/Gateway هنگام اجراهای زنده بیدرنگ stream شوند.- Heartbeatهای مدل مستقیم را با
OPENCLAW_LIVE_HEARTBEAT_MSتنظیم کنید. - Heartbeatهای Gateway/probe را با
OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MSتنظیم کنید.
کدام suite را اجرا کنم؟
از این جدول تصمیمگیری استفاده کنید:
- ویرایش منطق/آزمونها:
pnpm testرا اجرا کنید (و اگر تغییرات زیادی دادهایدpnpm test:coverage) - دستزدن به شبکهی Gateway / پروتکل WS / pairing:
pnpm test:e2eرا اضافه کنید - اشکالزدایی «بات من از کار افتاده» / خطاهای ویژهی ارائهدهنده / فراخوانی ابزار: یک
pnpm test:liveمحدودشده اجرا کنید
آزمونهای زنده (درگیر با شبکه)
برای ماتریس مدل زنده، smokeهای بکاند CLI، smokeهای ACP، harness سرور برنامهی Codex، و همهی آزمونهای زندهی ارائهدهندهی رسانه (Deepgram، BytePlus، ComfyUI، تصویر، موسیقی، ویدئو، harness رسانه) - بهعلاوهی مدیریت اعتبارنامه برای اجراهای زنده - به آزمودن suiteهای زنده مراجعه کنید. برای checklist اختصاصی بهروزرسانی و اعتبارسنجی Plugin، به آزمودن بهروزرسانیها و Pluginها مراجعه کنید.
اجراکنندههای Docker (بررسیهای اختیاری «در Linux کار میکند»)
این اجراکنندههای Docker به دو دسته تقسیم میشوند:
- اجراکنندههای مدل زنده:
test:docker:live-modelsوtest:docker:live-gatewayفقط فایل زندهی کلید پروفایل متناظر خود را داخل تصویر Docker مخزن اجرا میکنند (src/agents/models.profiles.live.test.tsوsrc/gateway/gateway-models.profiles.live.test.ts) و دایرکتوری پیکربندی محلی و workspace شما را mount میکنند (و اگر~/.profilemount شده باشد، آن را source میکنند). نقطههای ورود محلی متناظرtest:live:models-profilesوtest:live:gateway-profilesهستند. - اجراکنندههای زندهی Docker بهطور پیشفرض cap کوچکتری برای smoke دارند تا sweep کامل 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است. وقتی صراحتاً scan جامعتر و بزرگتر را میخواهید، آن متغیرهای env را override کنید. test:docker:allتصویر Docker زنده را یک بار از طریقtest:docker:live-buildمیسازد، OpenClaw را یک بار بهعنوان tarball npm از طریقscripts/package-openclaw-for-docker.mjsبستهبندی میکند، سپس دو تصویرscripts/e2e/Dockerfileرا میسازد/دوباره استفاده میکند. تصویر bare فقط اجراکنندهی Node/Git برای laneهای install/update/plugin-dependency است؛ آن laneها tarball ازپیشساخته را mount میکنند. تصویر functional همان tarball را برای laneهای عملکرد برنامهی ساختهشده در/appنصب میکند. تعریف laneهای Docker درscripts/lib/docker-e2e-scenarios.mjsقرار دارد؛ منطق planner درscripts/lib/docker-e2e-plan.mjsقرار دارد؛scripts/test-docker-all.mjsبرنامهی انتخابشده را اجرا میکند. aggregate از یک زمانبند محلی وزندار استفاده میکند:OPENCLAW_DOCKER_ALL_PARALLELISMslotهای پردازش را کنترل میکند، درحالیکه capهای منابع مانع میشوند laneهای سنگین زنده، نصب npm، و چندسرویسی همگی همزمان شروع شوند. اگر یک lane منفرد از capهای فعال سنگینتر باشد، زمانبند همچنان میتواند وقتی pool خالی است آن را شروع کند و سپس تا وقتی ظرفیت دوباره در دسترس شود، آن را تنها در حال اجرا نگه میدارد. پیشفرضها 10 slot،OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9،OPENCLAW_DOCKER_ALL_NPM_LIMIT=10، وOPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7هستند؛ فقط وقتی میزبان Docker ظرفیت بیشتری دارد،OPENCLAW_DOCKER_ALL_WEIGHT_LIMITیاOPENCLAW_DOCKER_ALL_DOCKER_LIMITرا تنظیم کنید. اجراکننده بهطور پیشفرض یک preflight Docker انجام میدهد، containerهای E2E قدیمی OpenClaw را حذف میکند، هر 30 ثانیه وضعیت را چاپ میکند، زمانبندی laneهای موفق را در.artifacts/docker-tests/lane-timings.jsonذخیره میکند، و در اجراهای بعدی از آن زمانبندیها برای شروع laneهای طولانیتر در ابتدا استفاده میکند. برای چاپ manifest lane وزندار بدون ساختن یا اجرای Docker ازOPENCLAW_DOCKER_ALL_DRY_RUN=1استفاده کنید، یا برای چاپ برنامهی CI برای laneهای انتخابشده، نیازهای بسته/تصویر، و اعتبارنامهها ازnode scripts/test-docker-all.mjs --plan-jsonاستفاده کنید.Package Acceptanceگیت package بومی GitHub برای «آیا این tarball قابل نصب بهعنوان یک محصول کار میکند؟» است. یک بستهی نامزد را ازsource=npm،source=ref،source=url، یاsource=artifactresolve میکند، آن را بهعنوانpackage-under-testupload میکند، سپس laneهای Docker E2E قابل استفادهی مجدد را بهجای بستهبندی دوبارهی ref انتخابشده، علیه همان tarball دقیق اجرا میکند. پروفایلها بهترتیب گستردگی مرتب شدهاند:smoke،package،product، وfull. برای قرارداد package/update/plugin، ماتریس survivor ارتقای منتشرشده، پیشفرضهای release، و triage خطا به آزمودن بهروزرسانیها و Pluginها مراجعه کنید.- بررسیهای build و release پس از tsdown،
scripts/check-cli-bootstrap-imports.mjsرا اجرا میکنند. guard گراف ساختهشدهی static را ازdist/entry.jsوdist/cli/run-main.jsپیمایش میکند و اگر startup پیش از dispatch وابستگیهای package مانند Commander، UI prompt، undici، یا logging را قبل از dispatch فرمان import کند، شکست میخورد؛ همچنین chunk اجرای Gateway همراه را زیر budget نگه میدارد و importهای static مسیرهای Gateway سرد شناختهشده را رد میکند. smoke بستهبندیشدهی CLI نیز help ریشه، help onboard، help doctor، status، schema پیکربندی، و یک فرمان model-list را پوشش میدهد. - سازگاری legacy در Package Acceptance تا
2026.4.25محدود است (2026.4.25-beta.*نیز شامل میشود). تا آن cutoff، harness فقط gapهای metadata بستهی shipped را تحمل میکند: ورودیهای inventory خصوصی QA حذفشده، نبودgateway install --wrapper، نبود patch fileها در fixture گیت مشتقشده از tarball، نبودupdate.channelپایدارشده، مکانهای legacy رکورد نصب Plugin، نبود پایداری رکورد نصب marketplace، و مهاجرت metadata پیکربندی هنگامplugins update. برای بستههای بعد از2026.4.25، آن مسیرها شکستهای strict هستند. - اجراکنندههای smoke container:
test:docker:openwebui،test:docker:onboard،test:docker:npm-onboard-channel-agent،test:docker:skill-install،test:docker:update-channel-switch،test:docker:upgrade-survivor،test:docker:published-upgrade-survivor،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:plugin-lifecycle-matrix، وtest:docker:config-reloadیک یا چند container واقعی را boot میکنند و مسیرهای یکپارچهسازی سطحبالاتر را verify میکنند.
اجراکنندههای Docker مدل زنده همچنین فقط خانههای احراز هویت CLI موردنیاز را bind-mount میکنند (یا وقتی اجرا محدود نشده باشد، همهی موارد پشتیبانیشده را)، سپس پیش از اجرا آنها را در خانهی container کپی میکنند تا OAuth مربوط به CLI خارجی بتواند tokenها را بدون تغییر دادن auth store میزبان refresh کند:
- مدلهای مستقیم:
pnpm test:docker:live-models(اسکریپت:scripts/test-live-models-docker.sh) - آزمون دود اتصال ACP:
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) - آزمون دود backend در CLI:
pnpm test:docker:live-cli-backend(اسکریپت:scripts/test-live-cli-backend-docker.sh) - آزمون دود هارنس app-server کدکس:
pnpm test:docker:live-codex-harness(اسکریپت:scripts/test-live-codex-harness-docker.sh) - Gateway + عامل توسعه:
pnpm test:docker:live-gateway(اسکریپت:scripts/test-live-gateway-models-docker.sh) - آزمون دود مشاهدهپذیری:
pnpm qa:otel:smokeیک مسیر خصوصی QA از checkout منبع است. این مورد عمداً بخشی از مسیرهای انتشار Docker بسته نیست، زیرا tarball npm شامل QA Lab نمیشود. - آزمون دود زنده Open WebUI:
pnpm test:docker:openwebui(اسکریپت:scripts/e2e/openwebui-docker.sh) - جادوی راهاندازی اولیه (TTY، داربستسازی کامل):
pnpm test:docker:onboard(اسکریپت:scripts/e2e/onboard-docker.sh) - آزمون دود tarball راهاندازی اولیه/کانال/عامل در Npm:
pnpm test:docker:npm-onboard-channel-agenttarball بستهبندیشده OpenClaw را بهصورت سراسری در Docker نصب میکند، OpenAI را از طریق راهاندازی اولیه با ارجاع env بههمراه Telegram بهطور پیشفرض پیکربندی میکند، doctor را اجرا میکند، و یک نوبت عامل OpenAI شبیهسازیشده را اجرا میکند. یک tarball از پیش ساختهشده را باOPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgzدوباره استفاده کنید، بازسازی میزبان را باOPENCLAW_NPM_ONBOARD_HOST_BUILD=0رد کنید، یا کانال را باOPENCLAW_NPM_ONBOARD_CHANNEL=discordیاOPENCLAW_NPM_ONBOARD_CHANNEL=slackتغییر دهید. - آزمون دود نصب Skill:
pnpm test:docker:skill-installtarball بستهبندیشده OpenClaw را بهصورت سراسری در Docker نصب میکند، نصبهای آرشیو آپلودشده را در پیکربندی غیرفعال میکند، slug فعلی Skill زنده ClawHub را از جستوجو resolve میکند، آن را باopenclaw skills installنصب میکند، و Skill نصبشده بههمراه فراداده origin/lock مربوط به.clawhubرا راستیآزمایی میکند. - آزمون دود تغییر کانال بهروزرسانی:
pnpm test:docker:update-channel-switchtarball بستهبندیشده OpenClaw را بهصورت سراسری در Docker نصب میکند، از بستهstableبه gitdevجابهجا میشود، کانال ماندگارشده و کار پس از بهروزرسانی Plugin را راستیآزمایی میکند، سپس به بستهstableبرمیگردد و وضعیت بهروزرسانی را بررسی میکند. - آزمون دود بازمانده ارتقا:
pnpm test:docker:upgrade-survivortarball بستهبندیشده OpenClaw را روی یک fixture کاربر قدیمی کثیف با عاملها، پیکربندی کانال، allowlistهای Plugin، وضعیت کهنه وابستگی Plugin، و فایلهای workspace/session موجود نصب میکند. این آزمون بهروزرسانی بسته بههمراه doctor غیرتعاملی را بدون کلیدهای ارائهدهنده زنده یا کانال اجرا میکند، سپس یک Gateway با loopback راهاندازی میکند و حفظ پیکربندی/وضعیت بههمراه بودجههای startup/status را بررسی میکند. - آزمون دود بازمانده ارتقای منتشرشده:
pnpm test:docker:published-upgrade-survivorبهطور پیشفرضopenclaw@latestرا نصب میکند، فایلهای کاربر موجود واقعگرایانه را seed میکند، آن baseline را با یک دستورالعمل فرمان پخته پیکربندی میکند، پیکربندی حاصل را اعتبارسنجی میکند، آن نصب منتشرشده را به tarball کاندید بهروزرسانی میکند، doctor غیرتعاملی را اجرا میکند،.artifacts/upgrade-survivor/summary.jsonرا مینویسد، سپس یک Gateway با loopback راهاندازی میکند و intentهای پیکربندیشده، حفظ وضعیت، startup،/healthz،/readyz، و بودجههای وضعیت RPC را بررسی میکند. یک baseline را باOPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECoverride کنید، از زمانبند تجمیعی بخواهید baselineهای محلی دقیق را باOPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECSمانندopenclaw@2026.5.2 openclaw@2026.4.23 openclaw@2026.4.15گسترش دهد، و fixtureهای مسئلهمحور را باOPENCLAW_UPGRADE_SURVIVOR_SCENARIOSمانندreported-issuesگسترش دهید؛ مجموعه reported-issues شاملconfigured-plugin-installsبرای تعمیر خودکار نصب Plugin خارجی OpenClaw است. Package Acceptance این موارد را بهصورتpublished_upgrade_survivor_baseline،published_upgrade_survivor_baselines، وpublished_upgrade_survivor_scenariosارائه میکند، توکنهای baseline متا مانندlast-stable-4یاall-since-2026.4.23را resolve میکند، و Full Release Validation گیت بسته release-soak را بهlast-stable-4 2026.4.23 2026.5.2 2026.4.15بههمراهreported-issuesگسترش میدهد. - آزمون دود زمینه runtime نشست:
pnpm test:docker:session-runtime-contextماندگاری transcript زمینه runtime پنهان بههمراه تعمیر doctor برای شاخههای تکراری prompt-rewrite آسیبدیده را راستیآزمایی میکند. - آزمون دود نصب سراسری Bun:
bash scripts/e2e/bun-global-install-smoke.shدرخت فعلی را بستهبندی میکند، آن را باbun install -gدر یک home ایزوله نصب میکند، و راستیآزمایی میکند کهopenclaw infer image providers --jsonبهجای هنگ کردن، ارائهدهندگان تصویر بستهبندیشده را برمیگرداند. یک tarball از پیش ساختهشده را باOPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgzدوباره استفاده کنید، build میزبان را باOPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0رد کنید، یاdist/را از یک تصویر Docker ساختهشده باOPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:localکپی کنید. - آزمون دود Docker نصبکننده:
bash scripts/test-install-sh-docker.shیک کش npm را میان کانتینرهای root، update، و direct-npm خود بهاشتراک میگذارد. آزمون دود update پیش از ارتقا به tarball کاندید، بهطور پیشفرض ازlatestدر npm بهعنوان baseline پایدار استفاده میکند. بهصورت محلی باOPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22override کنید، یا در GitHub با ورودیupdate_baseline_versionمربوط به workflow آزمون دود نصب. بررسیهای نصبکننده غیر root یک کش npm ایزوله نگه میدارند تا ورودیهای کش با مالکیت root رفتار نصب محلی کاربر را پنهان نکنند.OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cacheرا تنظیم کنید تا کش root/update/direct-npm را در اجرای دوباره محلی reuse کنید. - CI آزمون دود نصب، بهروزرسانی سراسری تکراری direct-npm را با
OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1رد میکند؛ وقتی پوشش مستقیمnpm install -gلازم است، اسکریپت را بهصورت محلی بدون آن env اجرا کنید. - آزمون دود CLI حذف workspace مشترک عاملها:
pnpm test:docker:agents-delete-shared-workspace(اسکریپت:scripts/e2e/agents-delete-shared-workspace-docker.sh) بهطور پیشفرض تصویر Dockerfile ریشه را میسازد، دو عامل را با یک workspace در home ایزوله کانتینر seed میکند،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 + سلامت):
pnpm test:docker:gateway-network(اسکریپت:scripts/e2e/gateway-network-docker.sh) - آزمون دود snapshot مرورگر CDP:
pnpm test:docker:browser-cdp-snapshot(اسکریپت:scripts/e2e/browser-cdp-snapshot-docker.sh) تصویر E2E منبع بههمراه یک لایه Chromium را میسازد، Chromium را با CDP خام شروع میکند،browser doctor --deepرا اجرا میکند، و راستیآزمایی میکند snapshotهای نقش CDP شامل URLهای لینک، عناصر کلیکپذیر ارتقایافته با cursor، ارجاعهای 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افزایش میدهد، سپس رد schema ارائهدهنده را اجباری میکند و بررسی میکند جزئیات خام در لاگهای Gateway ظاهر شود. - پل کانال MCP (Gateway seedشده + پل stdio + آزمون دود raw notification-frame در Claude):
pnpm test:docker:mcp-channels(اسکریپت:scripts/e2e/mcp-channels-docker.sh) - ابزارهای MCP بسته Pi (سرور stdio MCP واقعی + آزمون دود 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) - Pluginها (آزمون دود نصب/بهروزرسانی برای مسیر محلی،
file:، رجیستری npm با وابستگیهای hoistشده، refهای متحرک git، kitchen-sink در ClawHub، بهروزرسانیهای marketplace، و فعالسازی/بازرسی Claude-bundle):pnpm test:docker:plugins(اسکریپت:scripts/e2e/plugins-docker.sh) برای رد کردن بلوک ClawHub،OPENCLAW_PLUGINS_E2E_CLAWHUB=0را تنظیم کنید، یا جفت package/runtime پیشفرض kitchen-sink را باOPENCLAW_PLUGINS_E2E_CLAWHUB_SPECوOPENCLAW_PLUGINS_E2E_CLAWHUB_IDoverride کنید. بدونOPENCLAW_CLAWHUB_URL/CLAWHUB_URL، آزمون از یک سرور fixture محلی hermetic برای ClawHub استفاده میکند. - آزمون دود بدون تغییر بهروزرسانی Plugin:
pnpm test:docker:plugin-update(اسکریپت:scripts/e2e/plugin-update-unchanged-docker.sh) - آزمون دود ماتریس چرخه عمر Plugin:
pnpm test:docker:plugin-lifecycle-matrixtarball بستهبندیشده OpenClaw را در یک کانتینر bare نصب میکند، یک Plugin npm نصب میکند، enable/disable را toggle میکند، آن را از طریق یک رجیستری npm محلی ارتقا و تنزل میدهد، کد نصبشده را حذف میکند، سپس راستیآزمایی میکند uninstall همچنان وضعیت کهنه را حذف کند، در حالی که معیارهای RSS/CPU را برای هر فاز چرخه عمر log میکند. - آزمون دود فراداده reload پیکربندی:
pnpm test:docker:config-reload(اسکریپت:scripts/e2e/config-reload-source-docker.sh) - Pluginها:
pnpm test:docker:pluginsآزمون دود نصب/بهروزرسانی برای مسیر محلی،file:، رجیستری npm با وابستگیهای hoistشده، refهای متحرک git، fixtureهای ClawHub، بهروزرسانیهای marketplace، و فعالسازی/بازرسی Claude-bundle را پوشش میدهد.pnpm test:docker:plugin-updateرفتار بهروزرسانی بدون تغییر برای Pluginهای نصبشده را پوشش میدهد.pnpm test:docker:plugin-lifecycle-matrixنصب Plugin npm با ردیابی منابع، enable، disable، upgrade، downgrade، و uninstall در حالت کد مفقود را پوشش میدهد.
برای پیشساخت و استفاده دوباره دستی از تصویر عملکردی مشترک:
OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local pnpm test:docker:e2e-buildOPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channelsoverrideهای تصویر ویژه هر suite مانند OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE در صورت تنظیم همچنان اولویت دارند. وقتی OPENCLAW_SKIP_DOCKER_BUILD=1 به یک تصویر مشترک remote اشاره میکند، اگر از قبل محلی نباشد، اسکریپتها آن را pull میکنند. آزمونهای Docker مربوط به QR و نصبکننده Dockerfileهای خود را نگه میدارند، زیرا بهجای runtime برنامه ساختهشده مشترک، رفتار package/install را اعتبارسنجی میکنند.
اجراکنندههای Docker مدل زنده همچنین checkout فعلی را بهصورت فقطخواندنی bind-mount میکنند و
آن را داخل container در یک workdir موقت stage میکنند. این کار image زمان اجرا را
کمحجم نگه میدارد و در عین حال Vitest را روی دقیقاً همان source/config محلی شما اجرا میکند.
مرحله staging cacheهای بزرگِ فقطمحلی و خروجیهای build برنامه مانند
.pnpm-store، .worktrees، __openclaw_vitest__، و دایرکتوریهای خروجی .build محلیِ برنامه یا
Gradle را رد میکند تا اجراهای زنده Docker چند دقیقه را صرف کپی کردن
artifactهای وابسته به ماشین نکنند.
آنها همچنین OPENCLAW_SKIP_CHANNELS=1 را تنظیم میکنند تا probeهای زنده Gateway
workerهای channel واقعی Telegram/Discord/و غیره را داخل container شروع نکنند.
test:docker:live-models همچنان pnpm test:live را اجرا میکند، بنابراین وقتی لازم است
پوشش زنده Gateway را در آن lane Docker محدود یا مستثنا کنید، OPENCLAW_LIVE_GATEWAY_*
را هم عبور دهید.
test:docker:openwebui یک smoke سازگاری سطحبالاتر است: یک container Gateway
OpenClaw را با endpointهای HTTP سازگار با OpenAI فعالشده شروع میکند،
یک container پینشده Open WebUI را در برابر آن Gateway شروع میکند، از طریق
Open WebUI وارد میشود، تأیید میکند /api/models مقدار openclaw/default را expose میکند، سپس یک
درخواست chat واقعی را از طریق proxyِ /api/chat/completions مربوط به Open WebUI ارسال میکند.
برای checkهای CI مسیر release که باید پس از ورود Open WebUI و کشف مدل متوقف شوند،
بدون انتظار برای completion مدل زنده، OPENWEBUI_SMOKE_MODE=models را تنظیم کنید.
اجرای نخست میتواند بهطور محسوسی کندتر باشد، چون Docker ممکن است لازم باشد image
Open WebUI را pull کند و Open WebUI ممکن است لازم باشد راهاندازی سرد خودش را کامل کند.
این lane به یک key قابلاستفاده مدل زنده نیاز دارد، و OPENCLAW_PROFILE_FILE
(بهطور پیشفرض ~/.profile) راه اصلی فراهم کردن آن در اجراهای Dockerized است.
اجرای موفق یک payload کوچک JSON مانند { "ok": true, "model": "openclaw/default", ... } چاپ میکند.
test:docker:mcp-channels عمداً deterministic است و به حساب واقعی
Telegram، Discord، یا iMessage نیاز ندارد. یک container Gateway seedشده را boot میکند،
container دومی را شروع میکند که openclaw mcp serve را spawn میکند، سپس
کشف مکالمه routed، خواندن transcript، metadata پیوست،
رفتار queue رویداد زنده، routing ارسال outbound، و اعلانهای channel +
permission به سبک Claude را روی bridge واقعی stdio MCP تأیید میکند. بررسی اعلان
frameهای خام stdio MCP را مستقیماً inspect میکند تا smoke همان چیزی را validate کند که
bridge واقعاً emit میکند، نه فقط چیزی که یک SDK client خاص اتفاقاً surface میکند.
test:docker:pi-bundle-mcp-tools deterministic است و به key مدل زنده نیاز ندارد.
image Docker repo را build میکند، یک server probe واقعی stdio MCP را
داخل container شروع میکند، آن server را از طریق runtime MCP بسته Pi embedded materialize میکند،
tool را اجرا میکند، سپس تأیید میکند coding و messaging ابزارهای
bundle-mcp را نگه میدارند، در حالی که minimal و tools.deny: ["bundle-mcp"] آنها را filter میکنند.
test:docker:cron-mcp-cleanup deterministic است و به key مدل زنده نیاز ندارد.
یک Gateway seedشده را با یک server probe واقعی stdio MCP شروع میکند، یک
turn ایزوله cron و یک turn فرزند one-shot با /subagents spawn اجرا میکند، سپس تأیید میکند
process فرزند MCP پس از هر اجرا exit میکند.
smoke دستی thread زبان طبیعی ACP (CI نیست):
bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...- این script را برای workflowهای regression/debug نگه دارید. ممکن است برای validation مسیردهی threadهای ACP دوباره لازم شود، بنابراین آن را حذف نکنید.
متغیرهای env مفید:
OPENCLAW_CONFIG_DIR=...(پیشفرض:~/.openclaw) که به/home/node/.openclawmount میشودOPENCLAW_WORKSPACE_DIR=...(پیشفرض:~/.openclaw/workspace) که به/home/node/.openclaw/workspacemount میشودOPENCLAW_PROFILE_FILE=...(پیشفرض:~/.profile) که به/home/node/.profilemount میشود و پیش از اجرای testها source میشودOPENCLAW_DOCKER_PROFILE_ENV_ONLY=1برای verify کردن فقط env varهایی که ازOPENCLAW_PROFILE_FILEsource شدهاند، با استفاده از دایرکتوریهای config/workspace موقت و بدون mountهای auth خارجی CLIOPENCLAW_DOCKER_CLI_TOOLS_DIR=...(پیشفرض:~/.cache/openclaw/docker-cli-tools) که برای installهای cacheشده CLI داخل Docker به/home/node/.npm-globalmount میشود- دایرکتوریها/فایلهای auth خارجی CLI زیر
$HOMEبهصورت فقطخواندنی زیر/host-auth...mount میشوند، سپس پیش از شروع testها به/home/node/...کپی میشوند- دایرکتوریهای پیشفرض:
.minimax - فایلهای پیشفرض:
~/.codex/auth.json،~/.codex/config.toml،.claude.json،~/.claude/.credentials.json،~/.claude/settings.json،~/.claude/settings.local.json - اجراهای provider محدودشده فقط دایرکتوریها/فایلهای لازم را که از
OPENCLAW_LIVE_PROVIDERS/OPENCLAW_LIVE_GATEWAY_PROVIDERSinfer شدهاند mount میکنند - بهصورت دستی با
OPENCLAW_DOCKER_AUTH_DIRS=all،OPENCLAW_DOCKER_AUTH_DIRS=none، یا یک فهرست comma مانندOPENCLAW_DOCKER_AUTH_DIRS=.claude,.codexoverride کنید
- دایرکتوریهای پیشفرض:
OPENCLAW_LIVE_GATEWAY_MODELS=.../OPENCLAW_LIVE_MODELS=...برای محدود کردن runOPENCLAW_LIVE_GATEWAY_PROVIDERS=.../OPENCLAW_LIVE_PROVIDERS=...برای filter کردن providerها داخل containerOPENCLAW_SKIP_DOCKER_BUILD=1برای reuse کردن یک image موجودopenclaw:local-liveبرای rerunهایی که به rebuild نیاز ندارندOPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1برای اطمینان از اینکه credentials از profile store میآیند (نه env)OPENCLAW_OPENWEBUI_MODEL=...برای انتخاب مدلی که Gateway برای smokeِ Open WebUI expose میکندOPENCLAW_OPENWEBUI_PROMPT=...برای override کردن prompt بررسی nonce که smokeِ Open WebUI استفاده میکندOPENWEBUI_IMAGE=...برای override کردن tag image پینشده Open WebUI
sanity مستندات
پس از ویرایش مستندات، checkهای docs را اجرا کنید: pnpm check:docs.
وقتی به checkهای heading درون صفحه هم نیاز دارید، validation کامل anchorهای Mintlify را اجرا کنید: pnpm docs:check-links:anchors.
regression آفلاین (امن برای CI)
اینها regressionهای «pipeline واقعی» بدون providerهای واقعی هستند:
- tool calling در Gateway (OpenAI mock، Gateway واقعی + loop agent):
src/gateway/gateway.test.ts(case: "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(case: "runs wizard over ws and writes auth token config")
evalهای reliability agent (skills)
ما از قبل چند test امن برای CI داریم که مانند «evalهای reliability agent» رفتار میکنند:
- tool-calling mock از طریق Gateway واقعی + loop agent (
src/gateway/gateway.test.ts). - جریانهای wizard انتهابهانتها که wiring session و اثرهای config را validate میکنند (
src/gateway/gateway.test.ts).
چیزی که هنوز برای Skills کم است (ببینید Skills):
- Decisioning: وقتی skillها در prompt فهرست شدهاند، آیا agent skill درست را انتخاب میکند (یا از موارد نامرتبط اجتناب میکند)؟
- Compliance: آیا agent پیش از استفاده
SKILL.mdرا میخواند و steps/args لازم را دنبال میکند؟ - Workflow contracts: سناریوهای چند turn که ترتیب toolها، carryover تاریخچه session، و boundaryهای sandbox را assert میکنند.
evalهای آینده ابتدا باید deterministic بمانند:
- یک scenario runner با providerهای mock برای assert کردن tool callها + ترتیب، خواندن فایل skill، و wiring session.
- یک suite کوچک از سناریوهای متمرکز بر skill (استفاده در برابر اجتناب، gating، prompt injection).
- evalهای live اختیاری (opt-in، env-gated) فقط پس از آماده شدن suite امن برای CI.
Contract tests (شکل Plugin و channel)
Contract testها تأیید میکنند که هر Plugin و channel ثبتشده با
contract interface خودش سازگار است. آنها روی همه Pluginهای کشفشده iterate میکنند و یک suite از
assertionهای shape و behavior اجرا میکنند. lane واحد پیشفرض pnpm test عمداً
این فایلهای seam و smoke مشترک را رد میکند؛ وقتی surfaceهای shared channel یا provider را لمس میکنید،
commandهای contract را صراحتاً اجرا کنید.
Commands
- همه contractها:
pnpm test:contracts - فقط contractهای channel:
pnpm test:contracts:channels - فقط contractهای provider:
pnpm test:contracts:plugins
contractهای channel
در src/channels/plugins/contracts/*.contract.test.ts قرار دارند:
- Plugin - شکل پایه Plugin (id، name، capabilities)
- setup - contract ویزارد setup
- session-binding - رفتار binding session
- outbound-payload - ساختار payload پیام
- inbound - handling پیام inbound
- actions - handlerهای actionِ channel
- threading - handling شناسه thread
- directory - API دایرکتوری/roster
- group-policy - اعمال policy گروه
contractهای status provider
در src/plugins/contracts/*.contract.test.ts قرار دارند.
- status - probeهای status channel
- registry - شکل registry Plugin
contractهای provider
در src/plugins/contracts/*.contract.test.ts قرار دارند:
- auth - contract جریان auth
- auth-choice - انتخاب/گزینش auth
- catalog - API catalog مدل
- discovery - کشف Plugin
- loader - loading Plugin
- runtime - runtime provider
- shape - شکل/interfaceِ Plugin
- wizard - ویزارد setup
زمان اجرا
- پس از تغییر exportها یا subpathهای plugin-sdk
- پس از افزودن یا تغییر یک Pluginِ channel یا provider
- پس از refactor کردن registration یا discovery Plugin
Contract testها در CI اجرا میشوند و به keyهای واقعی API نیاز ندارند.
افزودن regressionها (راهنما)
وقتی issue مربوط به provider/model را که در live کشف شده fix میکنید:
- در صورت امکان یک regression امن برای CI اضافه کنید (providerِ mock/stub، یا capture کردن transformation دقیق request-shape)
- اگر ذاتاً فقط live است (rate limitها، policyهای auth)، test زنده را narrow و opt-in از طریق env varها نگه دارید
- ترجیح دهید کوچکترین layerی را هدف بگیرید که bug را میگیرد:
- bug تبدیل/replay درخواست provider → test مستقیم models
- bug pipelineِ session/history/tool در Gateway → smoke زنده Gateway یا test mock Gateway امن برای CI
- guardrail traversal برای SecretRef:
src/secrets/exec-secret-ref-id-parity.test.tsیک target نمونه برای هر classِ SecretRef را از metadata registry (listSecretTargetRegistryEntries()) derive میکند، سپس assert میکند exec idهای traversal-segment رد میشوند.- اگر یک خانواده target جدید SecretRef با
includeInPlanدرsrc/secrets/target-registry-data.tsاضافه میکنید،classifyTargetClassرا در آن test بهروزرسانی کنید. این test عمداً روی target idهای unclassified fail میشود تا classهای جدید بیصدا skip نشوند.