Appearance
Test Scripts
The scripts/test/ directory contains cross-platform and integration test suites.
Contract Tests (test/contracts.ts)
Validates that the server API responses match the Dart models in the mobile app.
bash
bun test:contracts
# or directly: bun scripts/test/contracts.tsPhase 1 (Bun):
- Start an in-memory test server
- Seed navigation data (location, floor, nodes, edges, token)
- Hit navigation API endpoints
- Write real JSON responses to
mobile/test/fixtures/*.json
Phase 2 (Dart):
- Run
flutter test test/contract_test.dartin the mobile directory - Dart tests read the fixtures and verify models parse correctly
Binary Smoke Tests (test/binary.sh)
Compiles the server binary for the host architecture, boots it with a minimal config, and verifies key endpoints.
bash
bash scripts/test/binary.sh # compile + test
bash scripts/test/binary.sh --skip-build # test existing binarySteps:
- Compile binary for host architecture
- Create temp working directory with minimal
config/main.config.json(or legacy root path when applicable) - Start the binary on a random port
- Hit endpoints:
/version,/, static assets,/login, authenticated routes - Report pass/fail counts
This runs automatically as part of the server build pipeline (build/server.sh).
VM Integration Tests (test/vm/)
Full lifecycle test designed to run on a clean Linux VM (Ubuntu/Debian). The test suite follows the same embed pattern as the installer: TypeScript test files in scripts/test/vm/ are bundled at build time into a self-contained shell script (releases/test-vm.sh).
Usage
bash
sudo bash test-vm.sh # run all tests
sudo bash test-vm.sh --quick # skip optional service tests
sudo bash test-vm.sh --suite=server # run only the server integration suite
sudo bash test-vm.sh --suite=mqtt,server # run specific suites (comma-separated)
sudo bash test-vm.sh --offline-dir=/path/to/bundle # bootstrap from local offline artifacts
sudo bash test-vm.sh --clean # remove all artifacts and exitArchitecture
scripts/test/vm/*.ts Source TypeScript test files
scripts/build/templates/vm.sh Shell template (preflight + installer bootstrap)
scripts/build/generators/vm-tests.ts Build-time bundler
releases/test-vm.sh Generated self-contained test scriptBuild flow:
generators/vm-tests.tsbundles all TypeScript files intest/vm/into a single script viaBun.build()- The bundle is embedded into
templates/vm.shvia a heredoc placeholder (###vm_tests###) - The final
test-vm.shis written toreleases/and uploaded during the server build
Runtime flow:
- Shell bootstrap: preflight checks (root, curl, systemd), download installer, run Phase 1 + Phase 2 install
- Extract the embedded TypeScript test bundle to
/tmp/safecall-vm-tests.ts - Run tests via the installed binary:
BUN_BE_BUN=1 ./safecall /tmp/safecall-vm-tests.ts [flags] - TypeScript runner handles all post-installation verification, reports results
- Shell handles final cleanup
Test Suites
Tests execute in the following order. Suites marked with (quick-skip) are skipped in --quick mode.
| Suite | File | Description |
|---|---|---|
install | test_install.ts | Verify Phase 1 + Phase 2: files, permissions, config, version, service state |
integrity | test_integrity.ts | Verify checksums.json creation, file hash validation, tamper detection |
doctor | test_doctor.ts | Doctor command: up-to-date check, 4.x migration detection, update prompt, corruption detection |
cli | test_cli.ts | CLI commands: status, help, selftest, config show/set/reset, generate, update, integrations |
service | test_service.ts | Service management: re-setup with custom user, service file validation |
server | test_server.ts | (quick-skip) Server integration: nginx/apache/caddy config, detection paths, sample-config output |
monit | test_monit.ts | (quick-skip) Monit install, config creation, check script, service status |
mqtt | test_mqtt.ts | (quick-skip) Install mosquitto, MQTT connection test, pub/sub round-trip |
grafana | test_grafana.ts | (quick-skip) Grafana JSON datasource API: health, search, query endpoints |
zabbix | test_zabbix.ts | (quick-skip) Bridge LLD endpoints, Zabbix CLI --dry-run validation |
migrate | test_migrate.ts | Simulate 4.x layout, run repair --migrate, verify layout migration preserving data |
repair | test_repair.ts | Simulate breakage, re-install to repair, verify restore, test uninstall |
custom_dir | test_custom_dir.ts | Install to custom directory, verify, one-liner --setup flag test |
Framework (framework.ts)
Shared test utilities used by all suites:
- Formatting:
section(),pass(),fail(),skip() - File assertions:
assert_file_exists(),assert_file_not_exists(),assert_dir_exists(),assert_executable(),assert_symlink() - Service assertions:
assert_service_active(),assert_service_enabled(),assert_service_inactive() - Network assertions:
assert_port_listening(),assert_http_ok() - Content assertions:
assert_contains() - Utilities:
run()(shell command execution),read_http_port(),full_cleanup()
All system interactions use Bun shell ($) for consistent behaviour on Linux VMs.
Adding a New Test Suite
- Create a new file
scripts/test/vm/test_<name>.ts - Export a
TestSuiteobject:
typescript
import { section, pass, fail, type TestSuite, type TestContext } from "./framework";
export const suite_<name>: TestSuite = {
name: "<name>",
skip_in_quick: true, // optional: skip in --quick mode
async run(ctx) {
section("<NAME>: description");
// ... test logic using framework assertions ...
},
};- Import and add it to the
ALL_SUITESarray inscripts/test/vm/main.ts - Rebuild to generate the updated
test-vm.sh:
bash
cd scripts/build && bun generators/vm-tests.tsPrerequisites
- Clean Ubuntu/Debian VM (22.04+ recommended)
- Root access
- Internet connection (unless using
--offline-dirwith extracted bundle artifacts)
For offline bundle preparation and transfer, see Offline Installation.
Other Test Commands
Server unit tests and web type checking are run separately:
bash
# Server unit tests
cd server && bun test
# Mobile tests
cd mobile && flutter test
# Web type checking
cd web && bun run typecheck