cli + daemon: move test seams off package globals onto injected structs
CLI: introduce internal/cli.deps which owns every RPC/SSH/host-command seam the tree used to reach through mutable package vars. Command builders, orchestrators, and the completion helpers become methods on *deps. Tests construct their own deps per case, so fakes no longer leak across cases and tests are free to run in parallel. Daemon: move workspaceInspectRepoFunc + workspaceImportFunc onto the Daemon struct (workspaceInspectRepo / workspaceImport), mirroring the existing guestWaitForSSH / guestDial pattern. Workspace-prepare tests drop t.Parallel() guards now that they no longer mutate process-wide state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d38f580e00
commit
c42fcbe012
19 changed files with 664 additions and 733 deletions
|
|
@ -15,13 +15,25 @@ import (
|
|||
"banger/internal/model"
|
||||
)
|
||||
|
||||
// Test seams. Tests swap these to observe or stall the guest-I/O
|
||||
// phase without needing a real git repo or SSH server. Production
|
||||
// callers see the real implementations from the workspace package.
|
||||
var (
|
||||
workspaceInspectRepoFunc = ws.InspectRepo
|
||||
workspaceImportFunc = ws.ImportRepoToGuest
|
||||
)
|
||||
// workspaceInspectRepoHook + workspaceImportHook dispatch through the
|
||||
// per-instance Daemon seams when set, falling back to the real
|
||||
// workspace package implementations. Keeping the fallbacks here (as
|
||||
// opposed to always requiring callers to populate d.workspaceInspectRepo
|
||||
// in a constructor) lets tests selectively override one hook without
|
||||
// having to wire both.
|
||||
func (d *Daemon) workspaceInspectRepoHook(ctx context.Context, sourcePath, branchName, fromRef string) (ws.RepoSpec, error) {
|
||||
if d != nil && d.workspaceInspectRepo != nil {
|
||||
return d.workspaceInspectRepo(ctx, sourcePath, branchName, fromRef)
|
||||
}
|
||||
return ws.InspectRepo(ctx, sourcePath, branchName, fromRef)
|
||||
}
|
||||
|
||||
func (d *Daemon) workspaceImportHook(ctx context.Context, client ws.GuestClient, spec ws.RepoSpec, guestPath string, mode model.WorkspacePrepareMode) error {
|
||||
if d != nil && d.workspaceImport != nil {
|
||||
return d.workspaceImport(ctx, client, spec, guestPath, mode)
|
||||
}
|
||||
return ws.ImportRepoToGuest(ctx, client, spec, guestPath, mode)
|
||||
}
|
||||
|
||||
func (d *Daemon) ExportVMWorkspace(ctx context.Context, params api.WorkspaceExportParams) (api.WorkspaceExportResult, error) {
|
||||
guestPath := strings.TrimSpace(params.GuestPath)
|
||||
|
|
@ -156,7 +168,7 @@ func (d *Daemon) PrepareVMWorkspace(ctx context.Context, params api.VMWorkspaceP
|
|||
// inspect the local repo, dial SSH, stream the tar, optionally chmod
|
||||
// readonly. It is called without holding the VM mutex.
|
||||
func (d *Daemon) prepareVMWorkspaceGuestIO(ctx context.Context, vm model.VMRecord, sourcePath, guestPath, branchName, fromRef string, mode model.WorkspacePrepareMode, readOnly bool) (model.WorkspacePrepareResult, error) {
|
||||
spec, err := workspaceInspectRepoFunc(ctx, sourcePath, branchName, fromRef)
|
||||
spec, err := d.workspaceInspectRepoHook(ctx, sourcePath, branchName, fromRef)
|
||||
if err != nil {
|
||||
return model.WorkspacePrepareResult{}, err
|
||||
}
|
||||
|
|
@ -172,7 +184,7 @@ func (d *Daemon) prepareVMWorkspaceGuestIO(ctx context.Context, vm model.VMRecor
|
|||
return model.WorkspacePrepareResult{}, fmt.Errorf("dial guest ssh: %w", err)
|
||||
}
|
||||
defer client.Close()
|
||||
if err := workspaceImportFunc(ctx, client, spec, guestPath, mode); err != nil {
|
||||
if err := d.workspaceImportHook(ctx, client, spec, guestPath, mode); err != nil {
|
||||
return model.WorkspacePrepareResult{}, err
|
||||
}
|
||||
if readOnly {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue