Skip to main content
← Back to list
01Issue
FeatureOpenUAT
AssigneesNone

Relationships

#614 UAT: Release channel CLI and adversarial tests

Opened by stack72 · 6/10/2026

Context

PR swamp-club/swamp#1552 adds release channel support (beta, rc, stable) to the extension system. This issue specifies the CLI UAT and adversarial tests needed to cover the new feature in swamp-club/swamp-uat.

Test file locations

  • CLI tests: tests/cli/extension/ (new files)
  • Adversarial tests: tests/cli/adversarial/ (new file)

CLI UAT Tests

tests/cli/extension/lifecycle/channel_push_test.ts

Tests for pushing extensions with release channels.

TEST-001: push --channel beta stores version as beta

  • Push a test extension with --channel beta
  • Verify via extension info --json that latestBeta is populated with the pushed version
  • Verify that latestVersion (stable) is unchanged

TEST-002: push --channel rc stores version as rc

  • Push a test extension with --channel rc
  • Verify via extension info --json that latestRc is populated

TEST-003: push without --channel stores as stable

  • Push a test extension with no --channel flag
  • Verify latestVersion reflects the new version
  • Verify latestRc and latestBeta are unaffected

TEST-004: push --channel rejects invalid values

  • Run push with --channel nightly
  • Assert exit code is non-zero
  • Assert error message contains "Invalid release channel"
  • Verify the version was NOT published (extension info unchanged)

TEST-005: push --channel beta then --channel rc stores both

  • Push v1 with --channel beta, push v2 with --channel rc
  • Verify latestBeta = v1, latestRc = v2, latestVersion unchanged

tests/cli/extension/lifecycle/channel_pull_test.ts

Tests for pulling extensions from specific channels.

TEST-006: pull without --channel gets latest stable

  • Push v1 as stable, v2 as beta, v3 as rc
  • Pull without --channel flag
  • Verify upstream_extensions.json records v1 (stable), not v2 or v3
  • Verify no channel field in lockfile entry (or channel = undefined)

TEST-007: pull --channel beta gets latest beta

  • Push v1 as stable, v2 as beta
  • Pull with --channel beta
  • Verify upstream_extensions.json records v2
  • Verify lockfile entry has channel: "beta"

TEST-008: pull --channel rc gets latest rc

  • Push v1 as stable, v2 as rc
  • Pull with --channel rc
  • Verify upstream_extensions.json records v2
  • Verify lockfile entry has channel: "rc"

TEST-009: pull --channel beta fails when no beta versions exist

  • Push only a stable version
  • Pull with --channel beta
  • Assert exit code is non-zero
  • Assert error contains "has no published beta versions"

TEST-010: pull with explicit version ignores channel

  • Push v1 as beta
  • Pull @name@v1 without --channel flag
  • Verify it installs v1 (the explicit version works regardless of channel)

TEST-011: pull --channel rejects invalid values

  • Run pull with --channel nightly
  • Assert exit code is non-zero
  • Assert error contains "Invalid release channel"

TEST-012: lockfile records channel on pull

  • Pull with --channel rc
  • Parse upstream_extensions.json
  • Assert the entry has "channel": "rc"

TEST-013: lockfile defaults missing channel to stable behavior

  • Manually write an upstream_extensions.json entry without a channel field
  • Run extension list --json
  • Verify the extension is treated as stable (no channel shown or channel: undefined)

tests/cli/extension/registry/channel_search_test.ts

Tests for searching with channel filters.

TEST-014: search without --channel shows stable-only results

  • Push stable + beta versions
  • Run search without --channel
  • Verify results show the stable latest version

TEST-015: search --channel rc shows rc results

  • Push rc version
  • Run search --channel rc
  • Verify results include the extension with rc version

TEST-016: search --channel rc --channel beta shows both

  • Push beta + rc versions
  • Run search --channel rc --channel beta
  • Verify results include extensions from both channels

TEST-017: search --channel rejects invalid values

  • Run search --channel nightly
  • Assert exit code is non-zero
  • Assert error contains "Invalid channel"

tests/cli/extension/registry/channel_info_test.ts

Tests for extension info with channel data.

TEST-018: info shows per-channel latest versions

  • Push stable, beta, and rc versions
  • Run extension info --json
  • Verify latestVersion is the stable version
  • Verify latestBeta is the beta version
  • Verify latestRc is the rc version

TEST-019: info omits channel fields when no prerelease versions exist

  • Push only stable versions
  • Run extension info --json
  • Verify latestRc is null and latestBeta is null

tests/cli/extension/lifecycle/channel_promote_test.ts

Tests for the promote command.

TEST-020: promote beta to rc succeeds

  • Push v1 as beta
  • Run promote v1 --channel rc
  • Verify output contains "promoted from beta to rc"
  • Verify versions endpoint shows v1 as rc (not beta)

TEST-021: promote beta to stable succeeds (skip rc)

  • Push v1 as beta
  • Run promote v1 --channel stable
  • Verify output contains "promoted from beta to stable"
  • Verify latestVersion includes v1

TEST-022: promote rc to stable succeeds

  • Push v1 as rc
  • Run promote v1 --channel stable
  • Verify output contains "promoted from rc to stable"

TEST-023: promote rejects backward transition (stable to rc)

  • Push v1 as stable
  • Run promote v1 --channel rc
  • Assert exit code is non-zero
  • Assert error contains "Cannot demote" or "Cannot promote"

TEST-024: promote rejects same channel

  • Push v1 as rc
  • Run promote v1 --channel rc
  • Assert exit code is non-zero

TEST-025: promote rejects invalid target channel

  • Run promote with --channel beta
  • Assert exit code is non-zero
  • Assert error contains "Invalid target channel"

TEST-026: promote requires authentication

  • Run promote without SWAMP_API_KEY
  • Assert exit code is non-zero
  • Assert error contains "Not authenticated"

TEST-027: promote --json returns structured output

  • Push v1 as beta, promote to rc with --json
  • Parse JSON output
  • Verify fields: name, version, previousChannel, channel, message

tests/cli/extension/lifecycle/channel_update_test.ts

Tests for update behavior with channels.

TEST-028: update checks within installed channel

  • Pull v1 as beta, then push v2 as beta
  • Run extension update --json or extension outdated --json
  • Verify it detects v2 as an available update (within beta channel)
  • Verify it does NOT suggest the stable latest

TEST-029: outdated shows channel in output

  • Pull beta extension, push newer beta
  • Run extension outdated
  • Verify output indicates the extension's channel

tests/cli/extension/lifecycle/channel_list_test.ts

TEST-030: extension list shows channel for non-stable installs

  • Pull with --channel beta
  • Run extension list --json
  • Verify the entry has channel: "beta"

TEST-031: extension list omits channel for stable installs

  • Pull without --channel
  • Run extension list --json
  • Verify channel is absent or undefined in the entry

Adversarial Tests

tests/cli/adversarial/channel_adversarial_test.ts

TEST-ADV-001: push same version to two different channels fails

  • Push v1 as beta
  • Attempt to push v1 again as rc (same version, different channel)
  • Assert 409 Conflict / version already exists error
  • Verify version remains as beta

TEST-ADV-002: promote after yank fails gracefully

  • Push v1 as beta, then yank v1
  • Attempt to promote v1 --channel rc
  • Assert error (yanked version cannot be promoted)

TEST-ADV-003: pull --channel with explicit version ignores channel mismatch

  • Push v1 as beta
  • Pull @name@v1 --channel rc (explicit version + mismatched channel)
  • Verify it installs v1 (explicit version takes precedence)

TEST-ADV-004: concurrent push to different channels

  • Simultaneously push v1 as beta and v2 as rc
  • Verify both succeed
  • Verify versions endpoint shows v1 as beta and v2 as rc

TEST-ADV-005: promote during concurrent pull

  • Push v1 as beta
  • Start pulling --channel beta, concurrently promote v1 to rc
  • Verify pull completes (either gets beta v1 or errors gracefully)
  • Verify no corrupted state

TEST-ADV-006: lockfile without channel field is backward compatible

  • Manually create upstream_extensions.json with entries that have no channel field (simulating pre-channel lockfiles)
  • Run extension list, extension update, extension install
  • Verify all commands treat the entries as stable
  • Verify no crashes or parse errors

TEST-ADV-007: rapid promote chain (beta to rc to stable in quick succession)

  • Push v1 as beta
  • Promote to rc, immediately promote to stable
  • Verify final state: v1 is stable
  • Verify latestVersion reflects v1
  • Verify latestRc and latestBeta are cleared

TEST-ADV-008: auto-resolve never installs prerelease

  • Set up a trusted collective with both stable and beta versions
  • Reference an unknown type that exists in a beta extension
  • Verify auto-resolve installs the stable version, NOT the beta
  • If no stable version exists, verify auto-resolve fails (does not fall back to beta)

TEST-ADV-009: promote with invalid version number

  • Run promote with a version that does not exist
  • Assert 404 or clear error message
  • Verify extension state unchanged

TEST-ADV-010: promote without auth returns clear error

  • Run promote without SWAMP_API_KEY set and without swamp auth login
  • Assert exit code non-zero
  • Assert error mentions authentication

Test infrastructure notes

  • All channel tests need a registry (dev server or mocked). Use the existing registry_helpers.ts pattern from the UAT repo.
  • Extension fixtures: create a minimal model extension fixture under tests/cli/fixtures/extensions/models/test/ that passes catalog validation (must have a method with a description field).
  • Push tests need SWAMP_API_KEY and a collective with push permissions. Use the same env var pattern as existing registry tests.
  • Promote tests are new — no existing pattern. Follow the runExpectingFailure / runJsonCommand pattern.
  • The --channel flag tests should use runExpectingFailure for failure paths and runJsonCommand for success paths with structured output validation.
  • Consider adding Zod schemas for promote output and channel fields on extension info/list to schemas.ts.
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

6/10/2026, 7:14:29 PM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.