diff --git a/internal/controller/vm/export_test.go b/internal/controller/vm/export_test.go new file mode 100644 index 0000000000..b369b44696 --- /dev/null +++ b/internal/controller/vm/export_test.go @@ -0,0 +1,21 @@ +//go:build windows + +package vm + +import ( + "github.com/Microsoft/hcsshim/internal/vm/vmmanager" +) + +// SetManagerForTest configures a Manager with injected dependencies for testing. +// This is only available in test builds. +// +// MUST be called during test setup before any concurrent operations on the Manager. +// +// Note: logOutputDone is initialized by NewController() and is NOT reset here. +// Tests that exercise Wait() in Running/Terminated state must close the channel +// manually or the Wait call will block on the logOutputDone select. +func (c *Manager) SetManagerForTest(uvm vmmanager.LifetimeManager, guest GuestManager, state State) { + c.uvm = uvm + c.guest = guest + c.vmState = state +} diff --git a/internal/controller/vm/interface.go b/internal/controller/vm/interface.go index 3629e21e33..ce5e618b02 100644 --- a/internal/controller/vm/interface.go +++ b/internal/controller/vm/interface.go @@ -2,6 +2,8 @@ package vm +//go:generate go tool mockgen -source=interface.go -build_constraint=windows -package=mockvmcontroller -destination=../../test/mock/vmcontroller/mock_interface.go + import ( "context" "time" @@ -15,9 +17,18 @@ import ( "github.com/Microsoft/go-winio/pkg/guid" ) +// GuestManager defines the guest operations required by the VM Controller. +// It combines the core guest manager, security policy, and HvSocket interfaces +// from the guestmanager package into a single interface for dependency injection. +type GuestManager interface { + guestmanager.Manager + guestmanager.SecurityPolicyManager + guestmanager.HVSocketManager +} + type Controller interface { // Guest returns the guest manager instance for this VM. - Guest() *guestmanager.Guest + Guest() GuestManager // State returns the current VM state. State() State diff --git a/internal/controller/vm/state_test.go b/internal/controller/vm/state_test.go new file mode 100644 index 0000000000..507b3c3448 --- /dev/null +++ b/internal/controller/vm/state_test.go @@ -0,0 +1,33 @@ +//go:build windows + +package vm_test + +import ( + "testing" + + vm "github.com/Microsoft/hcsshim/internal/controller/vm" +) + +func TestStateString(t *testing.T) { + tests := []struct { + state vm.State + want string + }{ + {vm.StateNotCreated, "NotCreated"}, + {vm.StateCreated, "Created"}, + {vm.StateRunning, "Running"}, + {vm.StateTerminated, "Terminated"}, + {vm.StateInvalid, "Invalid"}, + {vm.State(99), "Unknown"}, + {vm.State(-1), "Unknown"}, + } + + for _, tt := range tests { + t.Run(tt.want, func(t *testing.T) { + t.Parallel() + if got := tt.state.String(); got != tt.want { + t.Errorf("State(%d).String() = %q, want %q", tt.state, got, tt.want) + } + }) + } +} diff --git a/internal/controller/vm/vm.go b/internal/controller/vm/vm.go index e4c8c42736..18e7fdf25a 100644 --- a/internal/controller/vm/vm.go +++ b/internal/controller/vm/vm.go @@ -33,8 +33,8 @@ import ( // and its associated resources. type Manager struct { vmID string - uvm *vmmanager.UtilityVM - guest *guestmanager.Guest + uvm vmmanager.LifetimeManager + guest GuestManager // vmState tracks the current state of the VM lifecycle. // Access must be guarded by mu. @@ -70,7 +70,7 @@ func NewController() *Manager { // Guest returns the guest manager instance for this VM. // The guest manager provides access to guest-host communication. -func (c *Manager) Guest() *guestmanager.Guest { +func (c *Manager) Guest() GuestManager { return c.guest } diff --git a/internal/controller/vm/vm_test.go b/internal/controller/vm/vm_test.go new file mode 100644 index 0000000000..5de493387b --- /dev/null +++ b/internal/controller/vm/vm_test.go @@ -0,0 +1,482 @@ +//go:build windows + +package vm_test + +import ( + "context" + "errors" + "strings" + "testing" + "time" + + "github.com/Microsoft/go-winio/pkg/guid" + + "github.com/Microsoft/hcsshim/internal/cmd" + vm "github.com/Microsoft/hcsshim/internal/controller/vm" + gcsmock "github.com/Microsoft/hcsshim/internal/gcs/mock" + "github.com/Microsoft/hcsshim/internal/shimdiag" + ctrlmock "github.com/Microsoft/hcsshim/internal/test/mock/vmcontroller" + vmmock "github.com/Microsoft/hcsshim/internal/vm/vmmanager/mock" + + "go.uber.org/mock/gomock" +) + +var ( + errTest = errors.New("test error") + testGUID = guid.GUID{Data1: 0x12345678} +) + +// newTestManager creates a Manager in the given state with mocked dependencies. +func newTestManager(t *testing.T, ctrl *gomock.Controller, state vm.State) (*vm.Manager, *vmmock.MockLifetimeManager, *ctrlmock.MockGuestManager) { + t.Helper() + + mockUVM := vmmock.NewMockLifetimeManager(ctrl) + mockGuest := ctrlmock.NewMockGuestManager(ctrl) + + m := vm.NewController() + m.SetManagerForTest(mockUVM, mockGuest, state) + + return m, mockUVM, mockGuest +} + +func TestTerminateVM(t *testing.T) { + tests := []struct { + name string + initialState vm.State + setupMock func(*vmmock.MockLifetimeManager, *ctrlmock.MockGuestManager) + expectError bool + errorContains string + expectState vm.State + }{ + { + name: "idempotent/NotCreated", + initialState: vm.StateNotCreated, + expectState: vm.StateNotCreated, + }, + { + name: "idempotent/Terminated", + initialState: vm.StateTerminated, + expectState: vm.StateTerminated, + }, + { + name: "success/Created_to_Terminated", + initialState: vm.StateCreated, + setupMock: func(uvm *vmmock.MockLifetimeManager, guest *ctrlmock.MockGuestManager) { + gomock.InOrder( + uvm.EXPECT().Terminate(gomock.Any()).Return(nil), + guest.EXPECT().CloseConnection().Return(nil), + uvm.EXPECT().Close(gomock.Any()).Return(nil), + ) + }, + expectState: vm.StateTerminated, + }, + { + name: "success/Running_to_Terminated", + initialState: vm.StateRunning, + setupMock: func(uvm *vmmock.MockLifetimeManager, guest *ctrlmock.MockGuestManager) { + gomock.InOrder( + uvm.EXPECT().Terminate(gomock.Any()).Return(nil), + guest.EXPECT().CloseConnection().Return(nil), + uvm.EXPECT().Close(gomock.Any()).Return(nil), + ) + }, + expectState: vm.StateTerminated, + }, + { + name: "error/Close_fails_transitions_to_Invalid", + initialState: vm.StateRunning, + setupMock: func(uvm *vmmock.MockLifetimeManager, guest *ctrlmock.MockGuestManager) { + gomock.InOrder( + uvm.EXPECT().Terminate(gomock.Any()).Return(nil), + guest.EXPECT().CloseConnection().Return(nil), + uvm.EXPECT().Close(gomock.Any()).Return(errTest), + ) + }, + expectError: true, + errorContains: "failed to close utility VM", + expectState: vm.StateInvalid, + }, + { + name: "recovery/Invalid_to_Terminated", + initialState: vm.StateInvalid, + setupMock: func(uvm *vmmock.MockLifetimeManager, guest *ctrlmock.MockGuestManager) { + gomock.InOrder( + uvm.EXPECT().Terminate(gomock.Any()).Return(nil), + guest.EXPECT().CloseConnection().Return(nil), + uvm.EXPECT().Close(gomock.Any()).Return(nil), + ) + }, + expectState: vm.StateTerminated, + }, + { + // CloseConnection fails but TerminateVM should still proceed to Close + // and reach Terminated state (error is logged, not returned). + name: "success/CloseConnection_fails_still_terminates", + initialState: vm.StateRunning, + setupMock: func(uvm *vmmock.MockLifetimeManager, guest *ctrlmock.MockGuestManager) { + gomock.InOrder( + uvm.EXPECT().Terminate(gomock.Any()).Return(nil), + guest.EXPECT().CloseConnection().Return(errTest), + uvm.EXPECT().Close(gomock.Any()).Return(nil), + ) + }, + expectState: vm.StateTerminated, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m, mockUVM, mockGuest := newTestManager(t, ctrl, tt.initialState) + + if tt.setupMock != nil { + tt.setupMock(mockUVM, mockGuest) + } + + err := m.TerminateVM(context.Background()) + + if tt.expectError { + if err == nil { + t.Fatal("expected error but got nil") + } + if tt.errorContains != "" && !strings.Contains(err.Error(), tt.errorContains) { + t.Errorf("expected error containing %q, got: %v", tt.errorContains, err) + } + } else if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if m.State() != tt.expectState { + t.Errorf("expected state %v, got %v", tt.expectState, m.State()) + } + }) + } +} + +// TestGuardChecks verifies that methods reject calls in invalid states. +// Each case represents a realistic production scenario (e.g. exec after VM exits, +// Wait before Create). Redundant state permutations are omitted — the guard logic +// is a simple state check, not a state-dependent code path. +func TestGuardChecks(t *testing.T) { + tests := []struct { + name string + state vm.State + call func(*vm.Manager) error + errorContains string + }{ + // Exec on a terminated VM — most common real-world guard hit. + {"ExecIntoHost/Terminated", vm.StateTerminated, func(m *vm.Manager) error { + _, err := m.ExecIntoHost(context.Background(), &shimdiag.ExecProcessRequest{Args: []string{"ls"}}) + return err + }, "incorrect state"}, + // Wait before Create — real caller bug in shim service. + {"Wait/NotCreated", vm.StateNotCreated, func(m *vm.Manager) error { + return m.Wait(context.Background()) + }, "incorrect state"}, + // ExitStatus on a running VM — shimdiag asking too early. + {"ExitStatus/Running", vm.StateRunning, func(m *vm.Manager) error { + _, err := m.ExitStatus() + return err + }, "incorrect state"}, + // Stats on a non-existent VM — container metrics before create. + {"Stats/NotCreated", vm.StateNotCreated, func(m *vm.Manager) error { + _, err := m.Stats(context.Background()) + return err + }, "incorrect state"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m, _, _ := newTestManager(t, ctrl, tt.state) + + err := tt.call(m) + if err == nil { + t.Fatal("expected error but got nil") + } + if tt.errorContains != "" && !strings.Contains(err.Error(), tt.errorContains) { + t.Errorf("expected error containing %q, got: %v", tt.errorContains, err) + } + }) + } +} + +func TestExecIntoHost(t *testing.T) { + tests := []struct { + name string + request *shimdiag.ExecProcessRequest + setupMock func(*ctrlmock.MockGuestManager) + expectError bool + expectExitCode int + }{ + { + name: "terminal_with_stderr_rejected", + request: &shimdiag.ExecProcessRequest{ + Args: []string{"ls"}, + Terminal: true, + Stderr: "/some/path", + }, + expectError: true, + }, + { + name: "success", + request: &shimdiag.ExecProcessRequest{ + Args: []string{"ls", "-la"}, + Workdir: "/tmp", + Stdin: "stdin-pipe", + Stdout: "stdout-pipe", + Stderr: "stderr-pipe", + }, + setupMock: func(guest *ctrlmock.MockGuestManager) { + // Verify that ExecIntoHost correctly maps shimdiag fields to CmdProcessRequest. + guest.EXPECT().ExecIntoUVM(gomock.Any(), &cmd.CmdProcessRequest{ + Args: []string{"ls", "-la"}, + Workdir: "/tmp", + Stdin: "stdin-pipe", + Stdout: "stdout-pipe", + Stderr: "stderr-pipe", + }).Return(0, nil) + }, + expectExitCode: 0, + }, + { + name: "error/exec_fails", + request: &shimdiag.ExecProcessRequest{Args: []string{"ls"}}, + setupMock: func(guest *ctrlmock.MockGuestManager) { + guest.EXPECT().ExecIntoUVM(gomock.Any(), gomock.Any()).Return(-1, errTest) + }, + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m, _, mockGuest := newTestManager(t, ctrl, vm.StateRunning) + + if tt.setupMock != nil { + tt.setupMock(mockGuest) + } + + exitCode, err := m.ExecIntoHost(context.Background(), tt.request) + + if tt.expectError { + if err == nil { + t.Fatal("expected error but got nil") + } + return + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if exitCode != tt.expectExitCode { + t.Errorf("expected exit code %d, got %d", tt.expectExitCode, exitCode) + } + }) + } +} + +func TestDumpStacks(t *testing.T) { + tests := []struct { + name string + supported bool + dumpError error + expectResult string + expectError bool + }{ + { + name: "supported", + supported: true, + expectResult: "stack trace", + }, + { + name: "not_supported", + supported: false, + expectResult: "", + // DumpStacks should NOT be called when capabilities report unsupported. + // gomock will fail if an unexpected call is made. + }, + { + name: "error/dump_fails", + supported: true, + dumpError: errTest, + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m, _, mockGuest := newTestManager(t, ctrl, vm.StateRunning) + + mockCaps := gcsmock.NewMockGuestDefinedCapabilities(ctrl) + mockCaps.EXPECT().IsDumpStacksSupported().Return(tt.supported) + mockGuest.EXPECT().Capabilities().Return(mockCaps) + if tt.supported { + mockGuest.EXPECT().DumpStacks(gomock.Any()).Return(tt.expectResult, tt.dumpError) + } + + result, err := m.DumpStacks(context.Background()) + + if tt.expectError { + if err == nil { + t.Fatal("expected error but got nil") + } + return + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if result != tt.expectResult { + t.Errorf("expected %q, got %q", tt.expectResult, result) + } + }) + } +} + +func TestStartTime(t *testing.T) { + tests := []struct { + name string + state vm.State + expectZero bool + }{ + {"NotCreated", vm.StateNotCreated, true}, + {"Running", vm.StateRunning, false}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m, mockUVM, _ := newTestManager(t, ctrl, tt.state) + + if !tt.expectZero { + mockUVM.EXPECT().StartedTime().Return(time.Now()) + } + + st := m.StartTime() + if tt.expectZero && !st.IsZero() { + t.Errorf("expected zero time, got %v", st) + } + if !tt.expectZero && st.IsZero() { + t.Error("expected non-zero time, got zero") + } + }) + } +} + +func TestExitStatus(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m, mockUVM, _ := newTestManager(t, ctrl, vm.StateTerminated) + + now := time.Now() + mockUVM.EXPECT().StoppedTime().Return(now) + mockUVM.EXPECT().ExitError().Return(nil) + + status, err := m.ExitStatus() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if status.StoppedTime != now { + t.Errorf("expected stopped time %v, got %v", now, status.StoppedTime) + } + if status.Err != nil { + t.Errorf("expected nil exit error, got %v", status.Err) + } +} + +func TestStartVM_IdempotentWhenRunning(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m, _, _ := newTestManager(t, ctrl, vm.StateRunning) + + err := m.StartVM(context.Background(), &vm.StartOptions{}) + if err != nil { + t.Fatalf("expected nil for idempotent StartVM, got: %v", err) + } + if m.State() != vm.StateRunning { + t.Errorf("expected state Running, got %v", m.State()) + } +} + +func TestStartVM_ErrorWhenNotCreated(t *testing.T) { + tests := []struct { + name string + state vm.State + }{ + {"NotCreated", vm.StateNotCreated}, + {"Terminated", vm.StateTerminated}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m, _, _ := newTestManager(t, ctrl, tt.state) + + err := m.StartVM(context.Background(), &vm.StartOptions{}) + if err == nil { + t.Errorf("expected error for StartVM in state %v", tt.state) + } + }) + } +} + +// TestCreateVM_DuplicateCallRejected verifies that calling CreateVM on a +// controller that already has a VM (state Created) returns an error. +// This prevents leaking the first VM's HCS handle. +func TestCreateVM_DuplicateCallRejected(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m, _, _ := newTestManager(t, ctrl, vm.StateCreated) + + err := m.CreateVM(context.Background(), &vm.CreateOptions{ + ID: "duplicate-vm", + HCSDocument: nil, + }) + if err == nil { + t.Fatal("expected error for duplicate CreateVM, got nil") + } + if !strings.Contains(err.Error(), "incorrect state") { + t.Errorf("expected error about incorrect state, got: %v", err) + } + if m.State() != vm.StateCreated { + t.Errorf("expected state Created (unchanged), got %v", m.State()) + } +} + +// TestStartVM_StartFails_GoesInvalid verifies that when uvm.Start() fails, +// the VM transitions to Invalid and the error is returned. +func TestStartVM_StartFails_GoesInvalid(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m, mockUVM, _ := newTestManager(t, ctrl, vm.StateCreated) + + mockUVM.EXPECT().RuntimeID().Return(testGUID).AnyTimes() + mockUVM.EXPECT().Start(gomock.Any()).Return(errTest) + + err := m.StartVM(context.Background(), &vm.StartOptions{}) + if err == nil { + t.Fatal("expected error when Start fails, got nil") + } + if !strings.Contains(err.Error(), "failed to start VM") { + t.Errorf("expected start VM error, got: %v", err) + } + if m.State() != vm.StateInvalid { + t.Errorf("expected state Invalid, got %v", m.State()) + } +} diff --git a/internal/gcs/guestcaps.go b/internal/gcs/guestcaps.go index 58b1f8ebb7..308d01e512 100644 --- a/internal/gcs/guestcaps.go +++ b/internal/gcs/guestcaps.go @@ -2,6 +2,8 @@ package gcs +//go:generate go tool mockgen -source=guestcaps.go -build_constraint=windows -package=mock -destination=mock/mock_guestcaps.go + import ( "encoding/json" "fmt" diff --git a/internal/gcs/mock/mock_guestcaps.go b/internal/gcs/mock/mock_guestcaps.go new file mode 100644 index 0000000000..0c8642838a --- /dev/null +++ b/internal/gcs/mock/mock_guestcaps.go @@ -0,0 +1,98 @@ +//go:build windows + +// Code generated by MockGen. DO NOT EDIT. +// Source: guestcaps.go +// +// Generated by this command: +// +// mockgen -source=guestcaps.go -build_constraint=windows -package=mock -destination=mock/mock_guestcaps.go +// + +// Package mock is a generated GoMock package. +package mock + +import ( + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockGuestDefinedCapabilities is a mock of GuestDefinedCapabilities interface. +type MockGuestDefinedCapabilities struct { + ctrl *gomock.Controller + recorder *MockGuestDefinedCapabilitiesMockRecorder + isgomock struct{} +} + +// MockGuestDefinedCapabilitiesMockRecorder is the mock recorder for MockGuestDefinedCapabilities. +type MockGuestDefinedCapabilitiesMockRecorder struct { + mock *MockGuestDefinedCapabilities +} + +// NewMockGuestDefinedCapabilities creates a new mock instance. +func NewMockGuestDefinedCapabilities(ctrl *gomock.Controller) *MockGuestDefinedCapabilities { + mock := &MockGuestDefinedCapabilities{ctrl: ctrl} + mock.recorder = &MockGuestDefinedCapabilitiesMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockGuestDefinedCapabilities) EXPECT() *MockGuestDefinedCapabilitiesMockRecorder { + return m.recorder +} + +// IsDeleteContainerStateSupported mocks base method. +func (m *MockGuestDefinedCapabilities) IsDeleteContainerStateSupported() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsDeleteContainerStateSupported") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsDeleteContainerStateSupported indicates an expected call of IsDeleteContainerStateSupported. +func (mr *MockGuestDefinedCapabilitiesMockRecorder) IsDeleteContainerStateSupported() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsDeleteContainerStateSupported", reflect.TypeOf((*MockGuestDefinedCapabilities)(nil).IsDeleteContainerStateSupported)) +} + +// IsDumpStacksSupported mocks base method. +func (m *MockGuestDefinedCapabilities) IsDumpStacksSupported() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsDumpStacksSupported") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsDumpStacksSupported indicates an expected call of IsDumpStacksSupported. +func (mr *MockGuestDefinedCapabilitiesMockRecorder) IsDumpStacksSupported() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsDumpStacksSupported", reflect.TypeOf((*MockGuestDefinedCapabilities)(nil).IsDumpStacksSupported)) +} + +// IsNamespaceAddRequestSupported mocks base method. +func (m *MockGuestDefinedCapabilities) IsNamespaceAddRequestSupported() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsNamespaceAddRequestSupported") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsNamespaceAddRequestSupported indicates an expected call of IsNamespaceAddRequestSupported. +func (mr *MockGuestDefinedCapabilitiesMockRecorder) IsNamespaceAddRequestSupported() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsNamespaceAddRequestSupported", reflect.TypeOf((*MockGuestDefinedCapabilities)(nil).IsNamespaceAddRequestSupported)) +} + +// IsSignalProcessSupported mocks base method. +func (m *MockGuestDefinedCapabilities) IsSignalProcessSupported() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsSignalProcessSupported") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsSignalProcessSupported indicates an expected call of IsSignalProcessSupported. +func (mr *MockGuestDefinedCapabilitiesMockRecorder) IsSignalProcessSupported() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSignalProcessSupported", reflect.TypeOf((*MockGuestDefinedCapabilities)(nil).IsSignalProcessSupported)) +} diff --git a/internal/test/mock/vmcontroller/mock_interface.go b/internal/test/mock/vmcontroller/mock_interface.go new file mode 100644 index 0000000000..294f888ee9 --- /dev/null +++ b/internal/test/mock/vmcontroller/mock_interface.go @@ -0,0 +1,399 @@ +//go:build windows + +// Code generated by MockGen. DO NOT EDIT. +// Source: interface.go +// +// Generated by this command: +// +// mockgen -source=interface.go -build_constraint=windows -package=mockvmcontroller -destination=../../test/mock/vmcontroller/mock_interface.go +// + +// Package mockvmcontroller is a generated GoMock package. +package mockvmcontroller + +import ( + context "context" + reflect "reflect" + time "time" + + guid "github.com/Microsoft/go-winio/pkg/guid" + stats "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats" + cmd "github.com/Microsoft/hcsshim/internal/cmd" + vm "github.com/Microsoft/hcsshim/internal/controller/vm" + cow "github.com/Microsoft/hcsshim/internal/cow" + gcs "github.com/Microsoft/hcsshim/internal/gcs" + hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" + guestresource "github.com/Microsoft/hcsshim/internal/protocol/guestresource" + shimdiag "github.com/Microsoft/hcsshim/internal/shimdiag" + guestmanager "github.com/Microsoft/hcsshim/internal/vm/guestmanager" + gomock "go.uber.org/mock/gomock" +) + +// MockGuestManager is a mock of GuestManager interface. +type MockGuestManager struct { + ctrl *gomock.Controller + recorder *MockGuestManagerMockRecorder + isgomock struct{} +} + +// MockGuestManagerMockRecorder is the mock recorder for MockGuestManager. +type MockGuestManagerMockRecorder struct { + mock *MockGuestManager +} + +// NewMockGuestManager creates a new mock instance. +func NewMockGuestManager(ctrl *gomock.Controller) *MockGuestManager { + mock := &MockGuestManager{ctrl: ctrl} + mock.recorder = &MockGuestManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockGuestManager) EXPECT() *MockGuestManagerMockRecorder { + return m.recorder +} + +// AddSecurityPolicy mocks base method. +func (m *MockGuestManager) AddSecurityPolicy(ctx context.Context, settings guestresource.ConfidentialOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddSecurityPolicy", ctx, settings) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddSecurityPolicy indicates an expected call of AddSecurityPolicy. +func (mr *MockGuestManagerMockRecorder) AddSecurityPolicy(ctx, settings any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSecurityPolicy", reflect.TypeOf((*MockGuestManager)(nil).AddSecurityPolicy), ctx, settings) +} + +// Capabilities mocks base method. +func (m *MockGuestManager) Capabilities() gcs.GuestDefinedCapabilities { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Capabilities") + ret0, _ := ret[0].(gcs.GuestDefinedCapabilities) + return ret0 +} + +// Capabilities indicates an expected call of Capabilities. +func (mr *MockGuestManagerMockRecorder) Capabilities() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Capabilities", reflect.TypeOf((*MockGuestManager)(nil).Capabilities)) +} + +// CloseConnection mocks base method. +func (m *MockGuestManager) CloseConnection() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CloseConnection") + ret0, _ := ret[0].(error) + return ret0 +} + +// CloseConnection indicates an expected call of CloseConnection. +func (mr *MockGuestManagerMockRecorder) CloseConnection() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseConnection", reflect.TypeOf((*MockGuestManager)(nil).CloseConnection)) +} + +// CreateConnection mocks base method. +func (m *MockGuestManager) CreateConnection(ctx context.Context, GCSServiceID guid.GUID, opts ...guestmanager.ConfigOption) error { + m.ctrl.T.Helper() + varargs := []any{ctx, GCSServiceID} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateConnection", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateConnection indicates an expected call of CreateConnection. +func (mr *MockGuestManagerMockRecorder) CreateConnection(ctx, GCSServiceID any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, GCSServiceID}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateConnection", reflect.TypeOf((*MockGuestManager)(nil).CreateConnection), varargs...) +} + +// CreateContainer mocks base method. +func (m *MockGuestManager) CreateContainer(ctx context.Context, cid string, config any) (*gcs.Container, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateContainer", ctx, cid, config) + ret0, _ := ret[0].(*gcs.Container) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateContainer indicates an expected call of CreateContainer. +func (mr *MockGuestManagerMockRecorder) CreateContainer(ctx, cid, config any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateContainer", reflect.TypeOf((*MockGuestManager)(nil).CreateContainer), ctx, cid, config) +} + +// CreateProcess mocks base method. +func (m *MockGuestManager) CreateProcess(ctx context.Context, settings any) (cow.Process, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateProcess", ctx, settings) + ret0, _ := ret[0].(cow.Process) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateProcess indicates an expected call of CreateProcess. +func (mr *MockGuestManagerMockRecorder) CreateProcess(ctx, settings any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateProcess", reflect.TypeOf((*MockGuestManager)(nil).CreateProcess), ctx, settings) +} + +// DeleteContainerState mocks base method. +func (m *MockGuestManager) DeleteContainerState(ctx context.Context, cid string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteContainerState", ctx, cid) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteContainerState indicates an expected call of DeleteContainerState. +func (mr *MockGuestManagerMockRecorder) DeleteContainerState(ctx, cid any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteContainerState", reflect.TypeOf((*MockGuestManager)(nil).DeleteContainerState), ctx, cid) +} + +// DumpStacks mocks base method. +func (m *MockGuestManager) DumpStacks(ctx context.Context) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DumpStacks", ctx) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DumpStacks indicates an expected call of DumpStacks. +func (mr *MockGuestManagerMockRecorder) DumpStacks(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DumpStacks", reflect.TypeOf((*MockGuestManager)(nil).DumpStacks), ctx) +} + +// ExecIntoUVM mocks base method. +func (m *MockGuestManager) ExecIntoUVM(ctx context.Context, request *cmd.CmdProcessRequest) (int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExecIntoUVM", ctx, request) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExecIntoUVM indicates an expected call of ExecIntoUVM. +func (mr *MockGuestManagerMockRecorder) ExecIntoUVM(ctx, request any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecIntoUVM", reflect.TypeOf((*MockGuestManager)(nil).ExecIntoUVM), ctx, request) +} + +// InjectPolicyFragment mocks base method. +func (m *MockGuestManager) InjectPolicyFragment(ctx context.Context, settings guestresource.SecurityPolicyFragment) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InjectPolicyFragment", ctx, settings) + ret0, _ := ret[0].(error) + return ret0 +} + +// InjectPolicyFragment indicates an expected call of InjectPolicyFragment. +func (mr *MockGuestManagerMockRecorder) InjectPolicyFragment(ctx, settings any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InjectPolicyFragment", reflect.TypeOf((*MockGuestManager)(nil).InjectPolicyFragment), ctx, settings) +} + +// UpdateHvSocketAddress mocks base method. +func (m *MockGuestManager) UpdateHvSocketAddress(ctx context.Context, settings *hcsschema.HvSocketAddress) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateHvSocketAddress", ctx, settings) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateHvSocketAddress indicates an expected call of UpdateHvSocketAddress. +func (mr *MockGuestManagerMockRecorder) UpdateHvSocketAddress(ctx, settings any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateHvSocketAddress", reflect.TypeOf((*MockGuestManager)(nil).UpdateHvSocketAddress), ctx, settings) +} + +// MockController is a mock of Controller interface. +type MockController struct { + ctrl *gomock.Controller + recorder *MockControllerMockRecorder + isgomock struct{} +} + +// MockControllerMockRecorder is the mock recorder for MockController. +type MockControllerMockRecorder struct { + mock *MockController +} + +// NewMockController creates a new mock instance. +func NewMockController(ctrl *gomock.Controller) *MockController { + mock := &MockController{ctrl: ctrl} + mock.recorder = &MockControllerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockController) EXPECT() *MockControllerMockRecorder { + return m.recorder +} + +// CreateVM mocks base method. +func (m *MockController) CreateVM(ctx context.Context, opts *vm.CreateOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateVM", ctx, opts) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateVM indicates an expected call of CreateVM. +func (mr *MockControllerMockRecorder) CreateVM(ctx, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateVM", reflect.TypeOf((*MockController)(nil).CreateVM), ctx, opts) +} + +// DumpStacks mocks base method. +func (m *MockController) DumpStacks(ctx context.Context) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DumpStacks", ctx) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DumpStacks indicates an expected call of DumpStacks. +func (mr *MockControllerMockRecorder) DumpStacks(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DumpStacks", reflect.TypeOf((*MockController)(nil).DumpStacks), ctx) +} + +// ExecIntoHost mocks base method. +func (m *MockController) ExecIntoHost(ctx context.Context, request *shimdiag.ExecProcessRequest) (int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExecIntoHost", ctx, request) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExecIntoHost indicates an expected call of ExecIntoHost. +func (mr *MockControllerMockRecorder) ExecIntoHost(ctx, request any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecIntoHost", reflect.TypeOf((*MockController)(nil).ExecIntoHost), ctx, request) +} + +// ExitStatus mocks base method. +func (m *MockController) ExitStatus() (*vm.ExitStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExitStatus") + ret0, _ := ret[0].(*vm.ExitStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExitStatus indicates an expected call of ExitStatus. +func (mr *MockControllerMockRecorder) ExitStatus() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExitStatus", reflect.TypeOf((*MockController)(nil).ExitStatus)) +} + +// Guest mocks base method. +func (m *MockController) Guest() vm.GuestManager { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Guest") + ret0, _ := ret[0].(vm.GuestManager) + return ret0 +} + +// Guest indicates an expected call of Guest. +func (mr *MockControllerMockRecorder) Guest() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Guest", reflect.TypeOf((*MockController)(nil).Guest)) +} + +// StartTime mocks base method. +func (m *MockController) StartTime() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StartTime") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// StartTime indicates an expected call of StartTime. +func (mr *MockControllerMockRecorder) StartTime() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartTime", reflect.TypeOf((*MockController)(nil).StartTime)) +} + +// StartVM mocks base method. +func (m *MockController) StartVM(arg0 context.Context, arg1 *vm.StartOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StartVM", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// StartVM indicates an expected call of StartVM. +func (mr *MockControllerMockRecorder) StartVM(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartVM", reflect.TypeOf((*MockController)(nil).StartVM), arg0, arg1) +} + +// State mocks base method. +func (m *MockController) State() vm.State { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "State") + ret0, _ := ret[0].(vm.State) + return ret0 +} + +// State indicates an expected call of State. +func (mr *MockControllerMockRecorder) State() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "State", reflect.TypeOf((*MockController)(nil).State)) +} + +// Stats mocks base method. +func (m *MockController) Stats(ctx context.Context) (*stats.VirtualMachineStatistics, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Stats", ctx) + ret0, _ := ret[0].(*stats.VirtualMachineStatistics) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Stats indicates an expected call of Stats. +func (mr *MockControllerMockRecorder) Stats(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stats", reflect.TypeOf((*MockController)(nil).Stats), ctx) +} + +// TerminateVM mocks base method. +func (m *MockController) TerminateVM(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TerminateVM", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// TerminateVM indicates an expected call of TerminateVM. +func (mr *MockControllerMockRecorder) TerminateVM(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TerminateVM", reflect.TypeOf((*MockController)(nil).TerminateVM), arg0) +} + +// Wait mocks base method. +func (m *MockController) Wait(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Wait", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Wait indicates an expected call of Wait. +func (mr *MockControllerMockRecorder) Wait(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Wait", reflect.TypeOf((*MockController)(nil).Wait), ctx) +} diff --git a/internal/vm/vmmanager/lifetime.go b/internal/vm/vmmanager/lifetime.go index b2cc737b53..0c7ae6d6b1 100644 --- a/internal/vm/vmmanager/lifetime.go +++ b/internal/vm/vmmanager/lifetime.go @@ -2,6 +2,8 @@ package vmmanager +//go:generate go tool mockgen -source=lifetime.go -build_constraint=windows -package=mock -destination=mock/mock_lifetime.go + import ( "context" "fmt" diff --git a/internal/vm/vmmanager/mock/mock_lifetime.go b/internal/vm/vmmanager/mock/mock_lifetime.go new file mode 100644 index 0000000000..f6c2d15b32 --- /dev/null +++ b/internal/vm/vmmanager/mock/mock_lifetime.go @@ -0,0 +1,234 @@ +//go:build windows + +// Code generated by MockGen. DO NOT EDIT. +// Source: lifetime.go +// +// Generated by this command: +// +// mockgen -source=lifetime.go -build_constraint=windows -package=mock -destination=mock/mock_lifetime.go +// + +// Package mock is a generated GoMock package. +package mock + +import ( + context "context" + reflect "reflect" + time "time" + + guid "github.com/Microsoft/go-winio/pkg/guid" + hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" + gomock "go.uber.org/mock/gomock" +) + +// MockLifetimeManager is a mock of LifetimeManager interface. +type MockLifetimeManager struct { + ctrl *gomock.Controller + recorder *MockLifetimeManagerMockRecorder + isgomock struct{} +} + +// MockLifetimeManagerMockRecorder is the mock recorder for MockLifetimeManager. +type MockLifetimeManagerMockRecorder struct { + mock *MockLifetimeManager +} + +// NewMockLifetimeManager creates a new mock instance. +func NewMockLifetimeManager(ctrl *gomock.Controller) *MockLifetimeManager { + mock := &MockLifetimeManager{ctrl: ctrl} + mock.recorder = &MockLifetimeManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockLifetimeManager) EXPECT() *MockLifetimeManagerMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockLifetimeManager) Close(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockLifetimeManagerMockRecorder) Close(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockLifetimeManager)(nil).Close), ctx) +} + +// ExitError mocks base method. +func (m *MockLifetimeManager) ExitError() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExitError") + ret0, _ := ret[0].(error) + return ret0 +} + +// ExitError indicates an expected call of ExitError. +func (mr *MockLifetimeManagerMockRecorder) ExitError() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExitError", reflect.TypeOf((*MockLifetimeManager)(nil).ExitError)) +} + +// ID mocks base method. +func (m *MockLifetimeManager) ID() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ID") + ret0, _ := ret[0].(string) + return ret0 +} + +// ID indicates an expected call of ID. +func (mr *MockLifetimeManagerMockRecorder) ID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockLifetimeManager)(nil).ID)) +} + +// Pause mocks base method. +func (m *MockLifetimeManager) Pause(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Pause", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Pause indicates an expected call of Pause. +func (mr *MockLifetimeManagerMockRecorder) Pause(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pause", reflect.TypeOf((*MockLifetimeManager)(nil).Pause), ctx) +} + +// PropertiesV2 mocks base method. +func (m *MockLifetimeManager) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (*hcsschema.Properties, error) { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range types { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PropertiesV2", varargs...) + ret0, _ := ret[0].(*hcsschema.Properties) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PropertiesV2 indicates an expected call of PropertiesV2. +func (mr *MockLifetimeManagerMockRecorder) PropertiesV2(ctx any, types ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, types...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PropertiesV2", reflect.TypeOf((*MockLifetimeManager)(nil).PropertiesV2), varargs...) +} + +// Resume mocks base method. +func (m *MockLifetimeManager) Resume(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Resume", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Resume indicates an expected call of Resume. +func (mr *MockLifetimeManagerMockRecorder) Resume(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Resume", reflect.TypeOf((*MockLifetimeManager)(nil).Resume), ctx) +} + +// RuntimeID mocks base method. +func (m *MockLifetimeManager) RuntimeID() guid.GUID { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RuntimeID") + ret0, _ := ret[0].(guid.GUID) + return ret0 +} + +// RuntimeID indicates an expected call of RuntimeID. +func (mr *MockLifetimeManagerMockRecorder) RuntimeID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RuntimeID", reflect.TypeOf((*MockLifetimeManager)(nil).RuntimeID)) +} + +// Save mocks base method. +func (m *MockLifetimeManager) Save(ctx context.Context, options hcsschema.SaveOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Save", ctx, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// Save indicates an expected call of Save. +func (mr *MockLifetimeManagerMockRecorder) Save(ctx, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Save", reflect.TypeOf((*MockLifetimeManager)(nil).Save), ctx, options) +} + +// Start mocks base method. +func (m *MockLifetimeManager) Start(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Start", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Start indicates an expected call of Start. +func (mr *MockLifetimeManagerMockRecorder) Start(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockLifetimeManager)(nil).Start), ctx) +} + +// StartedTime mocks base method. +func (m *MockLifetimeManager) StartedTime() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StartedTime") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// StartedTime indicates an expected call of StartedTime. +func (mr *MockLifetimeManagerMockRecorder) StartedTime() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartedTime", reflect.TypeOf((*MockLifetimeManager)(nil).StartedTime)) +} + +// StoppedTime mocks base method. +func (m *MockLifetimeManager) StoppedTime() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StoppedTime") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// StoppedTime indicates an expected call of StoppedTime. +func (mr *MockLifetimeManagerMockRecorder) StoppedTime() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoppedTime", reflect.TypeOf((*MockLifetimeManager)(nil).StoppedTime)) +} + +// Terminate mocks base method. +func (m *MockLifetimeManager) Terminate(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Terminate", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Terminate indicates an expected call of Terminate. +func (mr *MockLifetimeManagerMockRecorder) Terminate(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Terminate", reflect.TypeOf((*MockLifetimeManager)(nil).Terminate), ctx) +} + +// Wait mocks base method. +func (m *MockLifetimeManager) Wait(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Wait", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Wait indicates an expected call of Wait. +func (mr *MockLifetimeManagerMockRecorder) Wait(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Wait", reflect.TypeOf((*MockLifetimeManager)(nil).Wait), ctx) +}