Skip to main content

Testing

KindCommandNotes
Unitmake test (Go repositories), pnpm test (apps, entrosity-ui)Fast; no Docker.
Integrationmake test-integration (backends)//go:build integration; testcontainers for Postgres, MinIO and Samba AD. The database is migrated once per package; tests run in rolled-back transactions where possible.
LDAPmake test-ldap (entrosity-axis-connector)LDAPS, StartTLS, paging, OU include/exclude, error codes against Samba.
Connector smokemake smoke-connector (entrosity-infra)Real connector + Samba + Entrosity Hub + backend: enroll, test connection, sync, AD-only devices, push reaching the connector.
End-to-endmake e2e (entrosity-infra)Both Playwright suites, Axis's (entrosity-axis.frontend/e2e/) and the Hub's (entrosity-hub.frontend/e2e/), against one throwaway stack of Entrosity Hub and Axis.
WindowsCI (agent and connector ci.yml, entrosity-infra integration.yml)//go:build windows tests, MSI install/uninstall, a real agent deploying 7-Zip.

Access-control tests​

  • Every portal route has an entry in entrosity-axis.backend/internal/http/portal/access.go. TestEveryRouteHasAccessRule fails for a route without one, and unclassified routes are refused at runtime.
  • entrosity-axis.backend/internal/http/rbac_matrix_test.go is a table of every route × caller (anonymous, global admin, tenant admin, technician, viewer, other-tenant admin). Add a row whenever you add a route; the test fails if a route has none.
  • An authorization fuzz test covers 82 cross-tenant cases.
  • The matrix and the fuzz test call Axis with product tokens signed by the test harness's fake Hub, as in production.
  • Entrosity Hub has its own matrix, entrosity-hub.backend/internal/http/rbac_matrix_integration_test.go: every route × anonymous, platform admin, organization admin, member and an admin of another organization (organization routes answer 404 to outsiders). Rules live in entrosity-hub.backend/internal/http/api/access.go.

Integration test helpers​

testutil.NewServer(t, pg) builds the real application (internal/app) with production wiring behind a fake Entrosity Hub, and captures e-mails in srv.Mail:

  • srv.Platform signs product and step-up tokens with a key the server trusts, and srv.PlatformData.Set publishes an access snapshot for srv.App.PlatformSync.Sync. The seeding helpers in seed.go (CreateTenant, CreateUser, AddMembership) write users, tenants and roles as the sync would, and srv.Login(email, …) returns a product token for a seeded user.
  • Options: WithStorage, WithReleaseSigning, WithClock, WithMinAgentVersion, WithRemoteTiming, WithRemoteSweep.
  • The Hub's harness (entrosity-hub.backend/internal/testutil) has the same shape: NewServer, browser-like clients with a cookie jar (srv.NewClient().MustLogin(email)), captured mail, a settable clock, and seeding helpers for users, organizations and memberships.

Without Docker​

Point the tests at an existing PostgreSQL 16 (an owner or superuser URL) and MinIO instead of containers. Each test binary creates and drops its own database; run packages one at a time:

TEST_POSTGRES_URL='postgres://postgres:secret@localhost:5432/postgres?sslmode=disable' \
TEST_MINIO_URL='http://minioadmin:[email protected]:9000' \
go test -p 1 -tags integration ./... # in entrosity-axis.backend or entrosity-hub.backend

Buckets of an external MinIO are emptied once per test binary.

End-to-end specs​

SpecCovers
phase1.spec.tsA platform admin creates organizations with Axis on the Hub; the tenant admin onboarded there is confined to their tenant in Axis.
phase2.spec.tsCreates an enrollment token in the UI, starts rmm-simagent (built from entrosity-axis.backend), follows the devices live.
phase3.spec.tsInstalls a simulated connector, runs the AD wizard, syncs and pushes with live per-target progress.
phase4.spec.tsUploads the fixture MSI, deploys it to simulated agents, follows the progress.
phase5.spec.tsRuns a parameterized script on three devices with live output; a low-disk rule opens alerts that are acknowledged and resolve when the rule is relaxed.

entrosity-infra's scripts/e2e.sh (make e2e) prepares one stack for both suites: Postgres, mailpit and MinIO (bucket rmm-e2e, winget refresh off); throwaway databases platform_e2e and rmm_e2e; the Hub's migrations and first platform admin (E2E_ADMIN_EMAIL, E2E_ADMIN_PASSWORD); the Hub's API on :8092 (internal :8093) and Axis's API on :8082, which syncs from the Hub every 2 s. Each suite starts the two Vite servers itself: Axis on :5177 and the Hub on :5176, which is the browser's origin (the Hub at /, Axis at /axis, as in production). Both suites run even when the first fails; logs are dist/e2e-hub.log and dist/e2e-axis.log. The shared helpers in entrosity-axis.frontend/e2e/hub.ts sign in on the Hub and create tenants as Hub organizations. Arguments are passed to both playwright test runs.

Hub specCovers
entrosity-hub.frontend/e2e/hub.spec.tsA platform admin creates an organization with Axis and invites its admin (and opens Axis's administration); the admin creates an account from the e-mail, opens Axis for the organization from the product list, finds its user pages pointing to the Hub, and signs out in Axis, which ends the Hub session.

Focused suites​

  • Deployment engine: entrosity-axis.backend/internal/deploy/scheduler_integration_test.go simulates a fleet across time zones, windows, retries and reconnects; targets_integration_test.go covers target resolution. MSI metadata tests use entrosity-axis.backend/internal/deploy/testdata/rmm-test.msi.
  • Agent: entrosity-axis-agent/internal/testserver is a fake backend (enroll, WebSocket, HTTP fallbacks) for testing the full agent loop. Windows collector parsers are tested against recorded PowerShell output in entrosity-axis-agent/internal/inventory/testdata/. GOOS=windows go vet ./agent/... checks Windows-only code on any OS.