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
|
|
@ -370,9 +370,7 @@ func TestExportVMWorkspace_MultipleChangedFiles(t *testing.T) {
|
|||
// inside the import step and then asserts the VM mutex is acquirable
|
||||
// while the prepare is mid-flight.
|
||||
func TestPrepareVMWorkspace_ReleasesVMLockDuringGuestIO(t *testing.T) {
|
||||
// Not parallel: mutates package-level workspaceInspectRepoFunc /
|
||||
// workspaceImportFunc seams, which the other prepare-concurrency
|
||||
// test also swaps.
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
apiSock := filepath.Join(t.TempDir(), "fc.sock")
|
||||
|
|
@ -395,21 +393,15 @@ func TestPrepareVMWorkspace_ReleasesVMLockDuringGuestIO(t *testing.T) {
|
|||
upsertDaemonVM(t, ctx, d.store, vm)
|
||||
d.setVMHandlesInMemory(vm.ID, model.VMHandles{PID: firecracker.Process.Pid})
|
||||
|
||||
// Replace the seams. InspectRepo returns a trivial spec so the
|
||||
// real filesystem isn't touched; Import blocks until we say go.
|
||||
origInspect := workspaceInspectRepoFunc
|
||||
origImport := workspaceImportFunc
|
||||
t.Cleanup(func() {
|
||||
workspaceInspectRepoFunc = origInspect
|
||||
workspaceImportFunc = origImport
|
||||
})
|
||||
|
||||
// Install the workspace seams on this daemon instance. InspectRepo
|
||||
// returns a trivial spec so the real filesystem isn't touched;
|
||||
// Import blocks until we say go.
|
||||
importStarted := make(chan struct{})
|
||||
releaseImport := make(chan struct{})
|
||||
workspaceInspectRepoFunc = func(context.Context, string, string, string) (workspace.RepoSpec, error) {
|
||||
d.workspaceInspectRepo = func(context.Context, string, string, string) (workspace.RepoSpec, error) {
|
||||
return workspace.RepoSpec{RepoName: "fake", RepoRoot: "/tmp/fake"}, nil
|
||||
}
|
||||
workspaceImportFunc = func(context.Context, workspace.GuestClient, workspace.RepoSpec, string, model.WorkspacePrepareMode) error {
|
||||
d.workspaceImport = func(context.Context, workspace.GuestClient, workspace.RepoSpec, string, model.WorkspacePrepareMode) error {
|
||||
close(importStarted)
|
||||
<-releaseImport
|
||||
return nil
|
||||
|
|
@ -465,7 +457,7 @@ func TestPrepareVMWorkspace_ReleasesVMLockDuringGuestIO(t *testing.T) {
|
|||
// the workspaceLocks scope: two concurrent prepares on the same VM do
|
||||
// NOT interleave, even though they no longer take the core VM mutex.
|
||||
func TestPrepareVMWorkspace_SerialisesConcurrentPreparesOnSameVM(t *testing.T) {
|
||||
// Not parallel: see note on ReleasesVMLockDuringGuestIO.
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
apiSock := filepath.Join(t.TempDir(), "fc.sock")
|
||||
|
|
@ -488,14 +480,7 @@ func TestPrepareVMWorkspace_SerialisesConcurrentPreparesOnSameVM(t *testing.T) {
|
|||
upsertDaemonVM(t, ctx, d.store, vm)
|
||||
d.setVMHandlesInMemory(vm.ID, model.VMHandles{PID: firecracker.Process.Pid})
|
||||
|
||||
origInspect := workspaceInspectRepoFunc
|
||||
origImport := workspaceImportFunc
|
||||
t.Cleanup(func() {
|
||||
workspaceInspectRepoFunc = origInspect
|
||||
workspaceImportFunc = origImport
|
||||
})
|
||||
|
||||
workspaceInspectRepoFunc = func(context.Context, string, string, string) (workspace.RepoSpec, error) {
|
||||
d.workspaceInspectRepo = func(context.Context, string, string, string) (workspace.RepoSpec, error) {
|
||||
return workspace.RepoSpec{RepoName: "fake", RepoRoot: "/tmp/fake"}, nil
|
||||
}
|
||||
|
||||
|
|
@ -503,7 +488,7 @@ func TestPrepareVMWorkspace_SerialisesConcurrentPreparesOnSameVM(t *testing.T) {
|
|||
var active int32
|
||||
var maxObserved int32
|
||||
release := make(chan struct{})
|
||||
workspaceImportFunc = func(context.Context, workspace.GuestClient, workspace.RepoSpec, string, model.WorkspacePrepareMode) error {
|
||||
d.workspaceImport = func(context.Context, workspace.GuestClient, workspace.RepoSpec, string, model.WorkspacePrepareMode) error {
|
||||
n := atomic.AddInt32(&active, 1)
|
||||
for {
|
||||
prev := atomic.LoadInt32(&maxObserved)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue