Skip to content

Start the UniFi OS test controller from the tests with Testcontainers - #26

Open
ChrisonSimtian wants to merge 8 commits into
mainfrom
feat/testcontainers-unifi
Open

ChrisonSimtian wants to merge 8 commits into
mainfrom
feat/testcontainers-unifi

Conversation

@ChrisonSimtian

Copy link
Copy Markdown
Collaborator

dotnet test now starts its own UniFi OS controller, runs the legacy write tests against it, and removes it afterwards. Stacked on #24 (raw network JSON).

What changed

  • UnifiContainerFixture: one shared container per run on a random port, same settings as .containers/unifi/compose.yml, image pinned by tag and digest; first-run admin setup and readiness wait
  • Legacy write tests (including the byte-identical DNS test from Read and replace a network as raw JSON #24) use the fixture and read no environment variables, so they cannot reach another controller
  • Refuses to run unless the container daemon is local; skips with a reason when no runtime is available; UNIFISHARP_SKIP_CONTAINER_TESTS (1/true/yes) opts out
  • Logs in once and backs off on the controller's 429 login limit
  • README: local use. On a machine with a stale ~/.testcontainers.properties, set DOCKER_HOST

Verification

Full suite against OrbStack: 115 passed, 7 skipped (env-gated read-only live tests), 0 failed; about 75 s to boot. No test container or Ryuk container left afterwards. CI is untested: the first boot downloads Ubiquiti's installer.

Closes #25

UnifiNetwork models about 12 of a live network's ~63 fields and
rest/networkconf/{id} is a full replacement, so a typed update would reset
the rest. Add ListNetworksRawAsync, GetNetworkRawAsync (exactly one row or
throw) and ReplaceNetworkRawAsync (body sent verbatim) over JsonObject, and
NetworkDhcpDns to read or change only dhcpd_dns_enabled and dhcpd_dns_1..4.
There is deliberately no UpdateNetworkAsync(UnifiNetwork).

UnifiLegacySession gains an internal handler seam so unit tests can assert
the bytes on the wire.
Creates a scratch network, writes DHCP DNS through NetworkDhcpDns.With, asserts only the DNS keys moved, restores the saved object and asserts every key matches its JSON text, and checks no other network changed. Skips without UNIFI_LEGACY_BASE_URL + UNIFI_USERNAME + UNIFI_PASSWORD and refuses any host but localhost / 127.0.0.1 / ::1.
The legacy write tests now share one container per run, started from the
compose.yml image and settings, set up through /api/setup and removed at
the end. They read no UNIFI_* variable, so they cannot reach a real
console. They skip when no container runtime is reachable, or with
UNIFISHARP_SKIP_CONTAINER_TESTS=1.

Refs #25
…l daemon only

The readiness probe now logs in once and reuses the session, re-logging in
only on 401 and backing off on 429; the shared session's logins (initial and
401 re-login) go through the same backoff. The image is pinned to 5.0.8 by
digest. A remote Docker endpoint or non-loopback host override fails the run
instead of starting a SYS_ADMIN container elsewhere. A refused first-run setup
is surfaced, and cancellation during start reports the last probe status.
UNIFISHARP_SKIP_CONTAINER_TESTS accepts 1/true/yes and rejects typos.
@ChrisonSimtian ChrisonSimtian added the enhancement New feature or request label Oct 23, 2026
Base automatically changed from feat/network-raw-json to main October 23, 2026 23:34

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant