4.9 KiB
4.9 KiB
Testing
Test stack
| Piece | Tool |
|---|---|
| Runner | brittle via brittle-node |
| Location | test/*.test.js |
| Command | npm test |
Suite map
| File | Coverage |
|---|---|
test/acl.test.js |
Role hierarchy, assertAllowed |
test/crypto-auth.test.js |
MAC key, capabilities, admin proof, invites, classify input |
test/protocol.test.js |
Constants, monitoring MethodRoles, schema validators |
test/store.test.js |
Metric ring buffer ingest + query |
test/weights.test.js |
Metric Correlations engine (volume / ks2 / windows / errors) |
test/logs.test.js |
Log query engine (roles, filters, journal argv, audit file) |
test/retention.test.js |
Retention presets, store trim, warm prune delete, Data Manager RPC roles |
test/format.test.js |
KPI unit scaling (formatMib, formatKilobitsPerSec, formatBytes) |
test/container-names.test.js |
Docker/Compose display names, cgroup resolve, card subtitles |
test/docker-collector.test.js |
Docker chart helpers + socket resolve |
test/hyperdb.test.js |
HyperDB model (node, links, warm points, alerts) |
test/rest.test.js |
agent-style /api/v3 routes |
test/integration.test.js |
Live HyperDHT agent + handshake + metrics query |
npm test
npm run test:integration
# Skip live DHT (CI runners without UDP, offline laptops)
SKIP_INTEGRATION=1 npm test
Integration test behavior
- Starts metrics pipeline + ephemeral HyperDHT agent in-process
- Sets
PEARDATA_INSECURE_OPEN_ADMIN=1for the process (restored in teardown) - Dials as a client, handshakes, lists charts, queries
system.cpu - Tears down collector / sockets / DHT
Requires outbound/inbound UDP for HyperDHT. If the test hangs or fails on a locked-down network, use SKIP_INTEGRATION=1.
Writing tests
Unit (preferred for pure logic)
- Put pure helpers in
shared/or thinserver/coremodules - Assert without networking
- Cover: validation failures, role denials, crypto tampering, expiry
Example pattern:
import test from 'brittle'
import { roleAllows, Roles } from '../shared/protocol.js'
test('operator cannot admin-only methods', (t) => {
t.ok(roleAllows(Roles.operator, Roles.viewer))
t.absent(roleAllows(Roles.operator, Roles.admin))
})
Integration (critical paths)
- Boot real
PeerSessionstack or full server when AuthZ + wire encoding matter - Always clean up DHT / sockets in
t.teardown - Prefer one happy-path + one auth-failure path over many flaky cases
Schema / protocol
When adding an RPC method:
MethodRolesentryvalidateMethodArgscase (if args matter)- Unit test for validator
- Optional integration call for the happy path
Manual checks
| Check | How |
|---|---|
| Server boots | npm run start:server — prints public key |
| Invite mint | npm run mint-invite -- operator |
| Desktop chrome | npm start — drag titlebar, resize edges, min/max/close |
| Admin connect | Paste key + SERVER_SEED in UI |
| Invite connect | Paste pd1.… without seed |
| Viewer denial | Public key only → runJob / mintInvite fail with permission error |
| Health | With server up: SERVER_PUBLIC_KEY=… npm run healthcheck |
| Soak | SERVER_PUBLIC_KEY=… SERVER_SEED=… npm run soak |
| Metric Correlations | Charts → Correlate → brush ≥15s → Find Correlations → wall filters; Clear restores; Related ⇢ still works |
| Charts Filters | Filters closed → full-width wall; / opens search; chip when filter active; Esc closes panel |
| Weights REST | curl -sG 'http://127.0.0.1:18888/api/v3/weights' --data-urlencode 'method=volume' --data-urlencode 'after=-60' --data-urlencode 'before=0' |
| Logs | Journal default (admin); Follow / Refresh / search highlight; Anomalies for viewers; Audit admin-only |
| Logs REST | curl -sG 'http://127.0.0.1:18888/api/v3/logs' --data-urlencode 'source=journal' --data-urlencode 'limit=20' |
| Data Manager | Settings → Data (admin): usage cards, 3m warm + 1 GiB budget default, Save, dry-run prune |
| Settings REST | curl -s http://127.0.0.1:18888/api/v3/settings | jq '.retention,.storage' |
| Docker names | With PEARDATA_DOCKER=1 + socket access: Charts → Containers shows dozzle · CPU (not bare hashes) |
Soak test
# default 60s
SERVER_PUBLIC_KEY=<hex> SERVER_SEED=<hex> npm run soak
SOAK_DURATION_MS=300000 SOAK_INTERVAL_MS=250 npm run soak
Reports sent / received / errors. Use before release when changing session or room code.
CI
GitHub CI runs npm test on Node 20 and 22. Gitea CI runs npm test on Node 22 plus a liveness healthcheck.
See CI.md.
Coverage philosophy
This template prioritizes critical pure paths + one live DHT smoke test over heavy mock frameworks. When productizing:
- Add domain unit tests next to new services
- Keep integration tests few and deterministic
- Gate flaky network tests behind
SKIP_INTEGRATION