Commit 0eeac6a6 authored by Brad Davidson's avatar Brad Davidson Committed by Brad Davidson

Rework mock executor using gomock for call validation

Generate the mock executor with mockgen and convert existing uses of the mock executor to set it up properly. Signed-off-by: 's avatarBrad Davidson <brad.davidson@rancher.com>
parent 441a42e8
...@@ -19,6 +19,7 @@ import ( ...@@ -19,6 +19,7 @@ import (
"github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/daemons/config"
"github.com/k3s-io/k3s/pkg/etcd/s3" "github.com/k3s-io/k3s/pkg/etcd/s3"
testutil "github.com/k3s-io/k3s/tests" testutil "github.com/k3s-io/k3s/tests"
"github.com/k3s-io/k3s/tests/mock"
"github.com/robfig/cron/v3" "github.com/robfig/cron/v3"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"go.etcd.io/etcd/api/v3/etcdserverpb" "go.etcd.io/etcd/api/v3/etcdserverpb"
...@@ -137,7 +138,9 @@ func Test_UnitETCD_IsInitialized(t *testing.T) { ...@@ -137,7 +138,9 @@ func Test_UnitETCD_IsInitialized(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
mock.NewExecutorWithEmbeddedETCD(t)
e := NewETCD() e := NewETCD()
defer tt.teardown(tt.args.config) defer tt.teardown(tt.args.config)
if err := tt.setup(tt.args.config); err != nil { if err := tt.setup(tt.args.config); err != nil {
t.Errorf("Prep for ETCD.IsInitialized() failed = %v", err) t.Errorf("Prep for ETCD.IsInitialized() failed = %v", err)
...@@ -215,6 +218,7 @@ func Test_UnitETCD_Register(t *testing.T) { ...@@ -215,6 +218,7 @@ func Test_UnitETCD_Register(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
mock.NewExecutorWithEmbeddedETCD(t)
e := NewETCD() e := NewETCD()
defer tt.teardown(tt.args.config) defer tt.teardown(tt.args.config)
...@@ -389,6 +393,7 @@ func Test_UnitETCD_Start(t *testing.T) { ...@@ -389,6 +393,7 @@ func Test_UnitETCD_Start(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
mock.NewExecutorWithEmbeddedETCD(t)
e := &ETCD{ e := &ETCD{
client: tt.fields.client, client: tt.fields.client,
config: tt.fields.config, config: tt.fields.config,
...@@ -628,6 +633,7 @@ func Test_UnitETCD_Test(t *testing.T) { ...@@ -628,6 +633,7 @@ func Test_UnitETCD_Test(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
mock.NewExecutorWithEmbeddedETCD(t)
e := &ETCD{ e := &ETCD{
client: tt.fields.client, client: tt.fields.client,
config: tt.fields.config, config: tt.fields.config,
......
// Code generated by MockGen. DO NOT EDIT.
// Source: pkg/daemons/executor/executor.go
//
// Generated by this command:
//
// mockgen --source pkg/daemons/executor/executor.go -self_package github.com/k3s-io/k3s/tests/mock -package mock -mock_names Executor=Executor
//
// Package mock is a generated GoMock package.
package mock package mock
import ( import (
"context" context "context"
"errors" http "net/http"
"net/http" reflect "reflect"
"github.com/k3s-io/k3s/pkg/cli/cmds" cmds "github.com/k3s-io/k3s/pkg/cli/cmds"
"github.com/k3s-io/k3s/pkg/daemons/config" config "github.com/k3s-io/k3s/pkg/daemons/config"
"github.com/k3s-io/k3s/pkg/daemons/executor" executor "github.com/k3s-io/k3s/pkg/daemons/executor"
"k8s.io/apiserver/pkg/authentication/authenticator" gomock "go.uber.org/mock/gomock"
authenticator "k8s.io/apiserver/pkg/authentication/authenticator"
) )
// mock executor that does not actually start anything // Executor is a mock of Executor interface.
type Executor struct{} type Executor struct {
ctrl *gomock.Controller
recorder *ExecutorMockRecorder
isgomock struct{}
}
// ExecutorMockRecorder is the mock recorder for Executor.
type ExecutorMockRecorder struct {
mock *Executor
}
// NewExecutor creates a new mock instance.
func NewExecutor(ctrl *gomock.Controller) *Executor {
mock := &Executor{ctrl: ctrl}
mock.recorder = &ExecutorMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *Executor) EXPECT() *ExecutorMockRecorder {
return m.recorder
}
// APIServer mocks base method.
func (m *Executor) APIServer(ctx context.Context, args []string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "APIServer", ctx, args)
ret0, _ := ret[0].(error)
return ret0
}
// APIServer indicates an expected call of APIServer.
func (mr *ExecutorMockRecorder) APIServer(ctx, args any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "APIServer", reflect.TypeOf((*Executor)(nil).APIServer), ctx, args)
}
// APIServerHandlers mocks base method.
func (m *Executor) APIServerHandlers(ctx context.Context) (authenticator.Request, http.Handler, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "APIServerHandlers", ctx)
ret0, _ := ret[0].(authenticator.Request)
ret1, _ := ret[1].(http.Handler)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// APIServerHandlers indicates an expected call of APIServerHandlers.
func (mr *ExecutorMockRecorder) APIServerHandlers(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "APIServerHandlers", reflect.TypeOf((*Executor)(nil).APIServerHandlers), ctx)
}
// APIServerReadyChan mocks base method.
func (m *Executor) APIServerReadyChan() <-chan struct{} {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "APIServerReadyChan")
ret0, _ := ret[0].(<-chan struct{})
return ret0
}
// APIServerReadyChan indicates an expected call of APIServerReadyChan.
func (mr *ExecutorMockRecorder) APIServerReadyChan() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "APIServerReadyChan", reflect.TypeOf((*Executor)(nil).APIServerReadyChan))
}
// Bootstrap mocks base method.
func (m *Executor) Bootstrap(ctx context.Context, nodeConfig *config.Node, cfg cmds.Agent) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Bootstrap", ctx, nodeConfig, cfg)
ret0, _ := ret[0].(error)
return ret0
}
// Bootstrap indicates an expected call of Bootstrap.
func (mr *ExecutorMockRecorder) Bootstrap(ctx, nodeConfig, cfg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Bootstrap", reflect.TypeOf((*Executor)(nil).Bootstrap), ctx, nodeConfig, cfg)
}
// CRI mocks base method.
func (m *Executor) CRI(ctx context.Context, node *config.Node) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CRI", ctx, node)
ret0, _ := ret[0].(error)
return ret0
}
// CRI indicates an expected call of CRI.
func (mr *ExecutorMockRecorder) CRI(ctx, node any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CRI", reflect.TypeOf((*Executor)(nil).CRI), ctx, node)
}
// CRIReadyChan mocks base method.
func (m *Executor) CRIReadyChan() <-chan struct{} {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CRIReadyChan")
ret0, _ := ret[0].(<-chan struct{})
return ret0
}
// CRIReadyChan indicates an expected call of CRIReadyChan.
func (mr *ExecutorMockRecorder) CRIReadyChan() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CRIReadyChan", reflect.TypeOf((*Executor)(nil).CRIReadyChan))
}
// CloudControllerManager mocks base method.
func (m *Executor) CloudControllerManager(ctx context.Context, ccmRBACReady <-chan struct{}, args []string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CloudControllerManager", ctx, ccmRBACReady, args)
ret0, _ := ret[0].(error)
return ret0
}
// CloudControllerManager indicates an expected call of CloudControllerManager.
func (mr *ExecutorMockRecorder) CloudControllerManager(ctx, ccmRBACReady, args any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloudControllerManager", reflect.TypeOf((*Executor)(nil).CloudControllerManager), ctx, ccmRBACReady, args)
}
// Containerd mocks base method.
func (m *Executor) Containerd(ctx context.Context, node *config.Node) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Containerd", ctx, node)
ret0, _ := ret[0].(error)
return ret0
}
// Containerd indicates an expected call of Containerd.
func (mr *ExecutorMockRecorder) Containerd(ctx, node any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Containerd", reflect.TypeOf((*Executor)(nil).Containerd), ctx, node)
}
func (e *Executor) Bootstrap(ctx context.Context, nodeConfig *config.Node, cfg cmds.Agent) error { // ControllerManager mocks base method.
return errors.New("not implemented") func (m *Executor) ControllerManager(ctx context.Context, args []string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ControllerManager", ctx, args)
ret0, _ := ret[0].(error)
return ret0
} }
func (e *Executor) Kubelet(ctx context.Context, args []string) error { // ControllerManager indicates an expected call of ControllerManager.
return errors.New("not implemented") func (mr *ExecutorMockRecorder) ControllerManager(ctx, args any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ControllerManager", reflect.TypeOf((*Executor)(nil).ControllerManager), ctx, args)
} }
func (e *Executor) KubeProxy(ctx context.Context, args []string) error { // CurrentETCDOptions mocks base method.
return errors.New("not implemented") func (m *Executor) CurrentETCDOptions() (executor.InitialOptions, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CurrentETCDOptions")
ret0, _ := ret[0].(executor.InitialOptions)
ret1, _ := ret[1].(error)
return ret0, ret1
} }
func (e *Executor) APIServerHandlers(ctx context.Context) (authenticator.Request, http.Handler, error) { // CurrentETCDOptions indicates an expected call of CurrentETCDOptions.
return nil, nil, errors.New("not implemented") func (mr *ExecutorMockRecorder) CurrentETCDOptions() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentETCDOptions", reflect.TypeOf((*Executor)(nil).CurrentETCDOptions))
} }
func (e *Executor) APIServer(ctx context.Context, args []string) error { // Docker mocks base method.
return errors.New("not implemented") func (m *Executor) Docker(ctx context.Context, node *config.Node) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Docker", ctx, node)
ret0, _ := ret[0].(error)
return ret0
} }
func (e *Executor) Scheduler(ctx context.Context, nodeReady <-chan struct{}, args []string) error { // Docker indicates an expected call of Docker.
return errors.New("not implemented") func (mr *ExecutorMockRecorder) Docker(ctx, node any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Docker", reflect.TypeOf((*Executor)(nil).Docker), ctx, node)
} }
func (e *Executor) ControllerManager(ctx context.Context, args []string) error { // ETCD mocks base method.
return errors.New("not implemented") func (m *Executor) ETCD(ctx context.Context, args *executor.ETCDConfig, extraArgs []string, test executor.TestFunc) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ETCD", ctx, args, extraArgs, test)
ret0, _ := ret[0].(error)
return ret0
} }
func (e *Executor) CurrentETCDOptions() (executor.InitialOptions, error) { // ETCD indicates an expected call of ETCD.
return executor.InitialOptions{}, nil func (mr *ExecutorMockRecorder) ETCD(ctx, args, extraArgs, test any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ETCD", reflect.TypeOf((*Executor)(nil).ETCD), ctx, args, extraArgs, test)
} }
func (e *Executor) ETCD(ctx context.Context, args *executor.ETCDConfig, extraArgs []string, test executor.TestFunc) error { // ETCDReadyChan mocks base method.
embed := &executor.Embedded{} func (m *Executor) ETCDReadyChan() <-chan struct{} {
return embed.ETCD(ctx, args, extraArgs, test) m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ETCDReadyChan")
ret0, _ := ret[0].(<-chan struct{})
return ret0
} }
func (e *Executor) CloudControllerManager(ctx context.Context, ccmRBACReady <-chan struct{}, args []string) error { // ETCDReadyChan indicates an expected call of ETCDReadyChan.
return errors.New("not implemented") func (mr *ExecutorMockRecorder) ETCDReadyChan() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ETCDReadyChan", reflect.TypeOf((*Executor)(nil).ETCDReadyChan))
} }
func (e *Executor) Containerd(ctx context.Context, node *config.Node) error { // KubeProxy mocks base method.
return errors.New("not implemented") func (m *Executor) KubeProxy(ctx context.Context, args []string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "KubeProxy", ctx, args)
ret0, _ := ret[0].(error)
return ret0
} }
func (e *Executor) Docker(ctx context.Context, node *config.Node) error { // KubeProxy indicates an expected call of KubeProxy.
return errors.New("not implemented") func (mr *ExecutorMockRecorder) KubeProxy(ctx, args any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KubeProxy", reflect.TypeOf((*Executor)(nil).KubeProxy), ctx, args)
} }
func (e *Executor) CRI(ctx context.Context, node *config.Node) error { // Kubelet mocks base method.
return errors.New("not implemented") func (m *Executor) Kubelet(ctx context.Context, args []string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Kubelet", ctx, args)
ret0, _ := ret[0].(error)
return ret0
} }
func (e *Executor) APIServerReadyChan() <-chan struct{} { // Kubelet indicates an expected call of Kubelet.
c := make(chan struct{}) func (mr *ExecutorMockRecorder) Kubelet(ctx, args any) *gomock.Call {
close(c) mr.mock.ctrl.T.Helper()
return c return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Kubelet", reflect.TypeOf((*Executor)(nil).Kubelet), ctx, args)
} }
func (e *Executor) ETCDReadyChan() <-chan struct{} { // Scheduler mocks base method.
c := make(chan struct{}) func (m *Executor) Scheduler(ctx context.Context, nodeReady <-chan struct{}, args []string) error {
close(c) m.ctrl.T.Helper()
return c ret := m.ctrl.Call(m, "Scheduler", ctx, nodeReady, args)
ret0, _ := ret[0].(error)
return ret0
} }
func (e *Executor) CRIReadyChan() <-chan struct{} { // Scheduler indicates an expected call of Scheduler.
c := make(chan struct{}) func (mr *ExecutorMockRecorder) Scheduler(ctx, nodeReady, args any) *gomock.Call {
close(c) mr.mock.ctrl.T.Helper()
return c return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Scheduler", reflect.TypeOf((*Executor)(nil).Scheduler), ctx, nodeReady, args)
} }
package mock
import (
"testing"
executor "github.com/k3s-io/k3s/pkg/daemons/executor"
"go.uber.org/mock/gomock"
)
// NewExecutorWithEmbeddedETCD creates a new mock executor, and sets it as the current executor.
// The executor exepects calls to ETCD(), and wraps the embedded executor method of the same name.
// The various ready channels are also mocked with immediate channel closure.
func NewExecutorWithEmbeddedETCD(t *testing.T) {
mockController := gomock.NewController(t)
mockExecutor := NewExecutor(mockController)
embed := &executor.Embedded{}
initialOptions := func() (executor.InitialOptions, error) {
return executor.InitialOptions{}, nil
}
closedChannel := func() <-chan struct{} {
c := make(chan struct{})
close(c)
return c
}
mockExecutor.EXPECT().ETCD(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(embed.ETCD)
mockExecutor.EXPECT().CurrentETCDOptions().AnyTimes().DoAndReturn(initialOptions)
mockExecutor.EXPECT().CRIReadyChan().AnyTimes().DoAndReturn(closedChannel)
mockExecutor.EXPECT().ETCDReadyChan().AnyTimes().DoAndReturn(closedChannel)
executor.Set(mockExecutor)
}
...@@ -7,8 +7,6 @@ import ( ...@@ -7,8 +7,6 @@ import (
"github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/daemons/config"
"github.com/k3s-io/k3s/pkg/daemons/control/deps" "github.com/k3s-io/k3s/pkg/daemons/control/deps"
"github.com/k3s-io/k3s/pkg/daemons/executor"
"github.com/k3s-io/k3s/tests/mock"
) )
// GenerateDataDir creates a temporary directory at "/tmp/k3s/<RANDOM_STRING>/". // GenerateDataDir creates a temporary directory at "/tmp/k3s/<RANDOM_STRING>/".
...@@ -45,9 +43,6 @@ func CleanupDataDir(cnf *config.Control) { ...@@ -45,9 +43,6 @@ func CleanupDataDir(cnf *config.Control) {
// GenerateRuntime creates a temporary data dir and configures // GenerateRuntime creates a temporary data dir and configures
// config.ControlRuntime with all the appropriate certificate keys. // config.ControlRuntime with all the appropriate certificate keys.
func GenerateRuntime(cnf *config.Control) error { func GenerateRuntime(cnf *config.Control) error {
// use mock executor that does not actually start things
executor.Set(&mock.Executor{})
// reuse ready channel from existing runtime if set // reuse ready channel from existing runtime if set
cnf.Runtime = config.NewRuntime() cnf.Runtime = config.NewRuntime()
if err := GenerateDataDir(cnf); err != nil { if err := GenerateDataDir(cnf); err != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment