Skip to content

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.ts

Phase 1 (Bun):

  1. Start an in-memory test server
  2. Seed navigation data (location, floor, nodes, edges, token)
  3. Hit navigation API endpoints
  4. Write real JSON responses to mobile/test/fixtures/*.json

Phase 2 (Dart):

  1. Run flutter test test/contract_test.dart in the mobile directory
  2. 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 binary

Steps:

  1. Compile binary for host architecture
  2. Create temp working directory with minimal config/main.config.json (or legacy root path when applicable)
  3. Start the binary on a random port
  4. Hit endpoints: /version, /, static assets, /login, authenticated routes
  5. 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 exit

Architecture

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 script

Build flow:

  1. generators/vm-tests.ts bundles all TypeScript files in test/vm/ into a single script via Bun.build()
  2. The bundle is embedded into templates/vm.sh via a heredoc placeholder (###vm_tests###)
  3. The final test-vm.sh is written to releases/ and uploaded during the server build

Runtime flow:

  1. Shell bootstrap: preflight checks (root, curl, systemd), download installer, run Phase 1 + Phase 2 install
  2. Extract the embedded TypeScript test bundle to /tmp/safecall-vm-tests.ts
  3. Run tests via the installed binary: BUN_BE_BUN=1 ./safecall /tmp/safecall-vm-tests.ts [flags]
  4. TypeScript runner handles all post-installation verification, reports results
  5. Shell handles final cleanup

Test Suites

Tests execute in the following order. Suites marked with (quick-skip) are skipped in --quick mode.

SuiteFileDescription
installtest_install.tsVerify Phase 1 + Phase 2: files, permissions, config, version, service state
integritytest_integrity.tsVerify checksums.json creation, file hash validation, tamper detection
doctortest_doctor.tsDoctor command: up-to-date check, 4.x migration detection, update prompt, corruption detection
clitest_cli.tsCLI commands: status, help, selftest, config show/set/reset, generate, update, integrations
servicetest_service.tsService management: re-setup with custom user, service file validation
servertest_server.ts(quick-skip) Server integration: nginx/apache/caddy config, detection paths, sample-config output
monittest_monit.ts(quick-skip) Monit install, config creation, check script, service status
mqtttest_mqtt.ts(quick-skip) Install mosquitto, MQTT connection test, pub/sub round-trip
grafanatest_grafana.ts(quick-skip) Grafana JSON datasource API: health, search, query endpoints
zabbixtest_zabbix.ts(quick-skip) Bridge LLD endpoints, Zabbix CLI --dry-run validation
migratetest_migrate.tsSimulate 4.x layout, run repair --migrate, verify layout migration preserving data
repairtest_repair.tsSimulate breakage, re-install to repair, verify restore, test uninstall
custom_dirtest_custom_dir.tsInstall 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

  1. Create a new file scripts/test/vm/test_<name>.ts
  2. Export a TestSuite object:
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 ...
  },
};
  1. Import and add it to the ALL_SUITES array in scripts/test/vm/main.ts
  2. Rebuild to generate the updated test-vm.sh:
bash
cd scripts/build && bun generators/vm-tests.ts

Prerequisites

  • Clean Ubuntu/Debian VM (22.04+ recommended)
  • Root access
  • Internet connection (unless using --offline-dir with 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