MnnLlmChat Smoke Tests
This folder contains LLM-friendly smoke testing assets for local Android testing.
Smoke Test Architecture
The smoke framework uses a hybrid architecture with two independent validation channels:
- UI channel:
adb + uiautomator dump + input tap/swipe + screencap - Non-UI channel:
tools/dumpappvia Stetho DumperPlugin
Main goals:
- Validate user-visible interaction paths (UI channel)
- Validate low-level benchmark/download capabilities (dumpapp channel)
- Preserve reproducible evidence (screenshots, logs, summaries, report)
Structure
instructions/: prompts/instructions for AI agentsworkflow/: human-readable smoke workflow and pass/fail criteriascripts/: executable scripts for install, regression, benchmark, and report generationartifacts/: generated screenshots, logs, summaries, and HTML report
Key scripts:
scripts/run_priority_regression.sh: baseline regression pipelinescripts/run_extended_priority_regression.sh: extended run with no-UI-first ordering, then UI stages and reportscripts/04_regress_qwen35_download_ops.sh: Qwen3.5 download/pause/resume/delete regressionscripts/noui/05_regress_qwen35_benchmark_noui.sh: Qwen3.5 benchmark regression (dumpapp only)scripts/05_regress_qwen35_benchmark_ui.sh: Qwen3.5 benchmark regression (UI only)scripts/05_regress_qwen35_benchmark.sh: compatibility entry, delegates to UI benchmark scriptscripts/06_regress_chat_text_image.sh: chat text + image-entry regressionscripts/12_regress_streaming_latex.sh: LaTeX streaming rendering smoke via mock content + screenshot evidencescripts/14_regress_streaming_table.sh: markdown table rendering smoke via mock streaming content + screenshot evidencescripts/13_regress_storage_ui.sh: storage management UI smoke via settings navigation + screenshot evidencescripts/noui/08_regress_api_dumpapp.sh: API compatibility + thinking-mode regression via dumpapp + curl (no-code)scripts/09_regress_api_uiautomator.sh: API settings UiAutomator instrumentation test (code-based)scripts/15_regress_model_settings_config_ui.sh: Model settings (home + ChatActivity) + config dump UiAutomator (guards #4259; verifies merged config after save)scripts/noui/10_regress_sana_diffusion_dumpapp.sh: Sana + Diffusion generation regression (dumpapp only)scripts/11_regress_sana_diffusion_uiautomator.sh: Sana + Diffusion model-entry regression (UI + uiautomator)scripts/noui/13_regress_storage_dumpapp_smoke.sh: dumpapp storage subcommand smoke (list/analysis/mmap/orphans/verify, integrity checks)scripts/noui/15_regress_voice_dumpapp.sh: dumpapp voice TTS smoke (init/test/destroy via dumpapp)scripts/16_regress_voice_ui.sh: Voice Chat UI smoke (enter/exit voice chat, status verification)scripts/07_generate_report.sh: generates single-pageartifacts/report.html
Quick Start
cd apps/Android/MnnLlmChat/tests/smoke
./scripts/run_priority_regression.sh
Single build mode:
BUILD_KIND=standard_debug ./scripts/run_smoke.sh
BUILD_KIND=aab_release ./scripts/run_smoke.sh
Extended run (recommended for full evidence):
./scripts/run_extended_priority_regression.sh
Optional env vars:
DEVICE_ID: adb device serial (default: first connected device)PACKAGE_NAME: defaultcom.alibaba.mnnllm.android.releaseAAB_PATH: defaultapps/Android/MnnLlmChat/release_outputs/googleplay/app-googleplay-release.aabDEBUG_APK_PATH: defaultapps/Android/MnnLlmChat/app/build/outputs/apk/standard/debug/app-standard-debug.apkBUNDLETOOL_JAR: default/tmp/bundletool-all-1.17.1.jarUNINSTALL_AT_START: defaultfalse; settrueto uninstall both debug and release packages before STEP1 (wipes model data; use if you hitINSTALL_FAILED_UPDATE_INCOMPATIBLE)UNINSTALL_CONFLICTING: defaulttrue, uninstall package before installBUILD_KIND:standard_debugoraab_release(default:aab_release)RUN_API_UIAUTOMATOR_TEST:trueto run step09_regress_api_uiautomator.shin extended pipeline (default:false)API_UIAUTOMATOR_TEST_CLASS: optional instrumentation class for step09(default:com.alibaba.mnnllm.android.api.ApiSettingsUiAutomatorTest)RUN_SANA_DIFFUSION_REGRESSION:trueto run step10/11Sana + Diffusion regressions in extended pipeline (default:false)SANA_MODEL_PATH: override model path for10_regress_sana_diffusion_dumpapp.shDIFFUSION_MODEL_ID: override model id for10_regress_sana_diffusion_dumpapp.shTHINKING_MAX_TOKENS: max completion tokens for step08_regress_api_dumpapp.shthinking probe (default:96)RUN_STORAGE_DUMPAPP_SMOKE: set totrueto run step 13 (dumpapp storage smoke) in extended pipeline (default:false)RUN_STORAGE_UI_SMOKE: set totrueto run storage management UI smoke in extended pipeline (default:false)RUN_LATEX_RENDER_SMOKE: set totrueto run LaTeX rendering smoke in extended pipeline (default:false)RUN_TABLE_RENDER_SMOKE: set totrueto run markdown table rendering smoke in extended pipeline (default:false)RUN_VOICE_DUMPAPP_SMOKE: set totrueto run Voice TTS dumpapp smoke in extended pipeline (default:false)RUN_VOICE_UI_SMOKE: set totrueto run Voice Chat UI smoke in extended pipeline (default:false)RUN_MODEL_SETTINGS_CONFIG_UI_SMOKE: run Model settings (home+chat) + config dump regression (guards #4259, system prompt persist); defaulttrue; setfalseto skip
Runtime Process
Typical end-to-end execution order:
- Environment/device check and app install
standardDebugsmokeaab releasesmoke- Qwen3.5 benchmark no-UI regression (dumpapp project, CPU/OpenCL cases)
- API compatibility regression (dumpapp no-code path)
- Qwen3.5 benchmark UI regression (CPU/OpenCL cases)
- Qwen3.5 chat text/image-entry regression
- Optional LaTeX rendering smoke
- Optional markdown table rendering smoke
- Qwen3.5 download regression
- Optional API settings UiAutomator regression
- Optional Sana + Diffusion dumpapp regression
- Optional Sana + Diffusion UiAutomator regression
- Optional storage dumpapp smoke
- Optional storage management UI smoke
- Optional Voice TTS dumpapp smoke
- Optional Voice Chat UI smoke
- Report generation to
artifacts/report.html
API compatibility stage details:
- dumpapp no-code path (
/v1/models, Anthropic/v1/messages, OpenAI/v1/chat/completionsauth gates, plus HTTPS runtime probe) - Anthropic Claude payload compatibility path:
messages[].contentas stringsystemas content-block array- both validated on local-forward and LAN direct base URLs
- dumpapp thinking-mode switch path (
dumpapp llm thinking set/get+ OpenAI reasoning-response differential check) - dumpapp path is service-only: no ChatActivity bootstrap fallback is allowed
- optional UiAutomator code path (API settings switch interaction)
- gesture caveat: step
09_regress_api_uiautomator.shdoes not validate history-drawer left-swipe; for gesture issues usemobile-mcp(mobile_swipe_on_screen, thenmobile_take_screenshot+mobile_list_elements_on_screen) and keep those artifacts
Key Implementation Logic
- UI actions are coordinate-driven from live UI XML, not fixed hardcoded points.
- Benchmark result success in UI path is detected by result-page signal (for example
基准测试结果) and screenshot evidence. - CPU and OpenCL are tracked as independent benchmark projects/cases.
- UI OpenCL case has dedicated timeout control via
OPENCL_UI_TIMEOUT_SEC(default60); timeout triggers app restart to reduce state interference. - dumpapp API stage ensures LLM runtime session via
dumpapp llm ensure <modelId>before OpenAI service probes. - Report is single-page and renders screenshots/logs inline for direct review.
- If OpenCL benchmark project fails, final OpenCL result screenshot is intentionally hidden in report to avoid misleading evidence.
Evidence Outputs
Primary artifacts:
- Stage summaries:
artifacts/**/summary.txtandartifacts/**/smoke_summary.txt - UI evidence:
artifacts/**/shots/*.png - dumpapp evidence:
artifacts/qwen35_benchmark/case_*.log - Aggregated report:
artifacts/report.html
Table rendering smoke specifics:
- Script:
scripts/14_regress_streaming_table.sh - Artifact root:
artifacts/table_io/ - Evidence: staged screenshots plus
generating_*.xml/finished.xml - Acceptance style: screenshot-first review; use human or vision-capable LLM review on screenshots to judge whether the markdown table rendered correctly
LaTeX rendering smoke specifics:
- Script:
scripts/12_regress_streaming_latex.sh - Artifact root:
artifacts/latex_io/ - Evidence: staged screenshots plus
generating_*.xml/finished.xml - Acceptance style: screenshot-first review; verify formulas render and streaming does not visibly break layout
Storage management UI smoke specifics:
- Script:
scripts/13_regress_storage_ui.sh - Artifact root:
artifacts/storage_ui/ - Evidence: settings page screenshot, storage summary screenshot, optional expanded row screenshot
- Safety: non-destructive by design; it does not tap delete or clean actions
Debugging My Models source tags (ModelScope / HuggingFace / Modelers)
If models downloaded from ModelScope (or HuggingFace / Modelers) do not show the expected source tag in the My Models tab, use dumpapp to inspect modelId and derived Source:
-
List models with source (same logic as UI):
dumpapp models listEach model shows
ID:,Source:(ModelScope / HuggingFace / Modelers / Builtin / (local) / (none)), andTags:. -
Inspect tags and source for all models:
dumpapp models tags --all -
Check storage path → modelId mapping (ensures
.mnnmodels/modelscope/→ModelScope/MNN/...):dumpapp models filesEntries under container
modelscopeshould haveModel ID: ModelScope/MNN/<name>. If a ModelScope-downloaded model appears under another container or with a differentModel IDprefix, the source tag in the UI will be wrong. -
Single-model tags:
dumpapp models tags "ModelScope/MNN/Qwen2.5-0.5B-MNN"
Interpretation: if Source: is (none) for a ModelScope-downloaded model, the ID likely does not start with ModelScope/ (e.g. wrong path when scanning, or cached with a different id). Use dumpapp models files to confirm the path and container.
API dumpapp and ANR
08_regress_api_dumpapp.sh must run dumpapp llm ensure before starting OpenAIService. If the service starts first, onStartCommand calls coordinator.startServer() which invokes ensureSession() → llmSession.load() on the main thread, blocking it and causing ANR. With session pre-created, startServer uses getActiveSession() and avoids heavy work on the main thread.
dumpapp openai start now auto-enables enable_api_service via the plugin when the pref is false, so the API service can be bootstrapped without UI interaction.
Notes
bundletool-allis required for AAB install.- These scripts are designed for local testing (non-CI) with a connected device.
- UiAutomator thinking-mode regression currently has a disabled phase-2 skeleton test:
ThinkingModeUiAutomatorSkeletonTest.