Skip to content

Commit ef82816

Browse files
author
Shreyansh Sancheti
committed
controller/vm: add unit tests for VM Controller state machine
Add 42 test cases for the VM Controller covering state transitions, guard checks, idempotency, and method behavior. Change Manager.uvm and Manager.guest to interface types to enable mock injection. Tests: TerminateVM transitions, ExecIntoHost, DumpStacks, StartTime, ExitStatus, StartVM idempotency, State.String(), and guard checks for all state-dependent methods. Generated mocks for LifetimeManager, GuestManager, and GuestDefinedCapabilities using mockgen. Signed-off-by: Shreyansh Sancheti <shreyanshjain7174@gmail.com> Signed-off-by: Shreyansh Sancheti <shsancheti@microsoft.com>
1 parent c70fd9f commit ef82816

10 files changed

Lines changed: 1231 additions & 4 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//go:build windows
2+
3+
package vm
4+
5+
import (
6+
"github.com/Microsoft/hcsshim/internal/vm/vmmanager"
7+
)
8+
9+
// SetManagerForTest configures a Manager with injected dependencies for testing.
10+
// This is only available in test builds.
11+
//
12+
// MUST be called during test setup before any concurrent operations on the Manager.
13+
func (c *Manager) SetManagerForTest(uvm vmmanager.LifetimeManager, guest GuestManager, state State) {
14+
c.uvm = uvm
15+
c.guest = guest
16+
c.vmState = state
17+
}

internal/controller/vm/interface.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
package vm
44

5+
//go:generate go tool mockgen -source=interface.go -build_constraint=windows -package=mockvmcontroller -destination=../../test/mock/vmcontroller/mock_interface.go
6+
57
import (
68
"context"
79
"time"
@@ -15,9 +17,18 @@ import (
1517
"github.com/Microsoft/go-winio/pkg/guid"
1618
)
1719

20+
// GuestManager defines the guest operations required by the VM Controller.
21+
// It combines the core guest manager, security policy, and HvSocket interfaces
22+
// from the guestmanager package into a single interface for dependency injection.
23+
type GuestManager interface {
24+
guestmanager.Manager
25+
guestmanager.SecurityPolicyManager
26+
guestmanager.HVSocketManager
27+
}
28+
1829
type Controller interface {
1930
// Guest returns the guest manager instance for this VM.
20-
Guest() *guestmanager.Guest
31+
Guest() GuestManager
2132

2233
// State returns the current VM state.
2334
State() State
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//go:build windows
2+
3+
package vm_test
4+
5+
import (
6+
"testing"
7+
8+
vm "github.com/Microsoft/hcsshim/internal/controller/vm"
9+
)
10+
11+
func TestStateString(t *testing.T) {
12+
tests := []struct {
13+
state vm.State
14+
want string
15+
}{
16+
{vm.StateNotCreated, "NotCreated"},
17+
{vm.StateCreated, "Created"},
18+
{vm.StateRunning, "Running"},
19+
{vm.StateTerminated, "Terminated"},
20+
{vm.StateInvalid, "Invalid"},
21+
{vm.State(99), "Unknown"},
22+
{vm.State(-1), "Unknown"},
23+
}
24+
25+
for _, tt := range tests {
26+
t.Run(tt.want, func(t *testing.T) {
27+
t.Parallel()
28+
if got := tt.state.String(); got != tt.want {
29+
t.Errorf("State(%d).String() = %q, want %q", tt.state, got, tt.want)
30+
}
31+
})
32+
}
33+
}

internal/controller/vm/vm.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import (
3333
// and its associated resources.
3434
type Manager struct {
3535
vmID string
36-
uvm *vmmanager.UtilityVM
37-
guest *guestmanager.Guest
36+
uvm vmmanager.LifetimeManager
37+
guest GuestManager
3838

3939
// vmState tracks the current state of the VM lifecycle.
4040
// Access must be guarded by mu.
@@ -70,7 +70,7 @@ func NewController() *Manager {
7070

7171
// Guest returns the guest manager instance for this VM.
7272
// The guest manager provides access to guest-host communication.
73-
func (c *Manager) Guest() *guestmanager.Guest {
73+
func (c *Manager) Guest() GuestManager {
7474
return c.guest
7575
}
7676

0 commit comments

Comments
 (0)