Skip to content

Merge HgResume.HttpTests and HgResume.SendReceiveTests into HgResume.IntegrationTests - #25

Open
hahn-kev-bot wants to merge 4 commits into
feature/manage-apisfrom
refactor/merge-integration-test-projects
Open

Merge HgResume.HttpTests and HgResume.SendReceiveTests into HgResume.IntegrationTests#25
hahn-kev-bot wants to merge 4 commits into
feature/manage-apisfrom
refactor/merge-integration-test-projects

Conversation

@hahn-kev-bot

@hahn-kev-bot hahn-kev-bot commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

AI summary

Stacked on #feature/manage-apis (which added /api/manage and wired the integration tests to seed/teardown through it). This PR removes the fixture duplication that surfaced once both test projects went through the same manage-API/container-lifecycle code paths.

  • Merged HgResume.HttpTests and HgResume.SendReceiveTests into a single project, HgResume.IntegrationTests.
  • One ServerFixture/one [Collection("server")] now backs both test styles: the HTTP-level wire-protocol tests (ApiClient) and the end-to-end Chorus send/receive tests (InitServerRepo, GetServerTip, HostPort). Previously each project ran its own container end-to-end; now they share one, cutting a full container build/run/stop cycle out of CI.
  • .csproj combines both dependency sets (adds SIL.Chorus.LibChorus/Mercurial + the Mercurial-staging MSBuild target to what was previously a light xUnit-only project).
  • Updated CI (single test step/port), run-tests.sh/run-tests.ps1, HgResume.slnx, .gitignore, and README to the merged project.

Test plan

  • dotnet build (full solution)
  • Rebuilt the Docker image and ran the merged suite against a live container (HGRESUME_PODMAN=docker): all 52 tests pass (48 HTTP-level + 4 Chorus send/receive) in ~3.2 minutes, one container for the whole run.

This change is Reviewable

hahn-kev and others added 4 commits September 3, 2026 11:13
…er cp

Wiring test fixtures to the manage API (rather than extracting zips on the
host and docker-cp'ing them in) sidesteps the Windows/Docker Desktop overlay
visibility problem, and turned up two real bugs it exercises for the first
time over real HTTP:

- FinishReset handed the raw request body to ZipArchive, which needs to
  seek and can't do sync IO on a Kestrel request stream; buffer it into a
  MemoryStream first.
- HgResumeApi.GetRepoPath only checked the flat {root}/{code} layout, so a
  repo created via /api/manage (nested {root}/{first-letter}/{code}, per
  RepoManageService's LexBox layout) was unreachable over the wire
  protocol. GetRepoPath now falls back to the nested layout.

HttpTests fixture repo IDs were camelCase (sampleHgRepo, manyRevsHgRepo,
...), which ProjectCode's validation (lowercase/digits/hyphens only)
rejects, so they're renamed to kebab-case across the fixture zips and the
test files that reference them. The one case the manage API can't express
(a repo id containing "/", used to test path-traversal rejection) still
falls back to the old podman exec/cp path, as does AddAndCommit (content
mutation, not repo management) and the maintenance-file helpers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…IntegrationTests

Both projects drove the same container via near-identical fixtures (build/run/
stop the image, wait-for-ready polling, manage-API HTTP calls, process-run
helpers) with only cosmetic differences. Merging them into one project with
one ServerFixture removes that duplication and means the two test styles
(HTTP wire-protocol tests and the real-Chorus-client send/receive tests) now
share a single running container instead of each starting/stopping their own,
cutting a full container lifecycle out of each test run.

ServerFixture gains the send/receive-specific members (InitServerRepo,
GetServerRevisions/GetServerTip, HostPort, ContainerLogs); everything else is
unchanged. CI, run-tests.sh/ps1, the slnx, and .gitignore are updated to the
single project/path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…dman/docker

Replaces the hand-rolled ProcessStartInfo wrapper around the podman/docker
CLI (build, run, exec, cp, logs, rm) with Testcontainers: ImageFromDockerfileBuilder
for the build step, ContainerBuilder + a Wait.ForUnixContainer()
UntilHttpRequestIsSucceeded strategy in place of the manual isAvailable
polling loop, and IContainer.ExecAsync/CopyAsync for the exec/filesystem
fallback paths (AddAndCommit, maintenance-file helpers, and the SubDir
path-traversal test's non-manage-API seeding).

Host ports are now assigned randomly by Testcontainers (GetMappedPublicPort)
rather than fixed via HGRESUME_PORT, so that env var and CI's per-step port
are gone; HGRESUME_PODMAN goes too, since Testcontainers talks to the Docker
Engine API directly rather than a CLI (this does change what "just works"
for podman-only setups -- podman needs its API socket exposed and DOCKER_HOST
pointed at it, same as any other Docker-API client).

Verified against a live Docker daemon: all 52 tests pass, and the container
is cleaned up automatically on teardown (confirmed via `docker ps -a`).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Repo zips can be large, so a MemoryStream is a needless allocation of the
whole upload. Write to a unique file under the temp dir and delete it in a
finally block.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants