mirror of
https://github.com/k3s-io/k3s.git
synced 2026-02-03 20:39:49 -05:00
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: Brad Davidson <brad.davidson@rancher.com>
This commit is contained in:
parent
441a42e8ce
commit
0eeac6a622
4 changed files with 275 additions and 54 deletions
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/k3s-io/k3s/pkg/daemons/config"
|
||||
"github.com/k3s-io/k3s/pkg/etcd/s3"
|
||||
testutil "github.com/k3s-io/k3s/tests"
|
||||
"github.com/k3s-io/k3s/tests/mock"
|
||||
"github.com/robfig/cron/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
|
|
@ -137,7 +138,9 @@ func Test_UnitETCD_IsInitialized(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mock.NewExecutorWithEmbeddedETCD(t)
|
||||
e := NewETCD()
|
||||
|
||||
defer tt.teardown(tt.args.config)
|
||||
if err := tt.setup(tt.args.config); err != nil {
|
||||
t.Errorf("Prep for ETCD.IsInitialized() failed = %v", err)
|
||||
|
|
@ -215,6 +218,7 @@ func Test_UnitETCD_Register(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mock.NewExecutorWithEmbeddedETCD(t)
|
||||
e := NewETCD()
|
||||
|
||||
defer tt.teardown(tt.args.config)
|
||||
|
|
@ -389,6 +393,7 @@ func Test_UnitETCD_Start(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mock.NewExecutorWithEmbeddedETCD(t)
|
||||
e := &ETCD{
|
||||
client: tt.fields.client,
|
||||
config: tt.fields.config,
|
||||
|
|
@ -628,6 +633,7 @@ func Test_UnitETCD_Test(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mock.NewExecutorWithEmbeddedETCD(t)
|
||||
e := &ETCD{
|
||||
client: tt.fields.client,
|
||||
config: tt.fields.config,
|
||||
|
|
|
|||
|
|
@ -1,86 +1,273 @@
|
|||
// 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
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
context "context"
|
||||
http "net/http"
|
||||
reflect "reflect"
|
||||
|
||||
"github.com/k3s-io/k3s/pkg/cli/cmds"
|
||||
"github.com/k3s-io/k3s/pkg/daemons/config"
|
||||
"github.com/k3s-io/k3s/pkg/daemons/executor"
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
cmds "github.com/k3s-io/k3s/pkg/cli/cmds"
|
||||
config "github.com/k3s-io/k3s/pkg/daemons/config"
|
||||
executor "github.com/k3s-io/k3s/pkg/daemons/executor"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
authenticator "k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
)
|
||||
|
||||
// mock executor that does not actually start anything
|
||||
type Executor struct{}
|
||||
|
||||
func (e *Executor) Bootstrap(ctx context.Context, nodeConfig *config.Node, cfg cmds.Agent) error {
|
||||
return errors.New("not implemented")
|
||||
// Executor is a mock of Executor interface.
|
||||
type Executor struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *ExecutorMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
func (e *Executor) Kubelet(ctx context.Context, args []string) error {
|
||||
return errors.New("not implemented")
|
||||
// ExecutorMockRecorder is the mock recorder for Executor.
|
||||
type ExecutorMockRecorder struct {
|
||||
mock *Executor
|
||||
}
|
||||
|
||||
func (e *Executor) KubeProxy(ctx context.Context, args []string) error {
|
||||
return errors.New("not implemented")
|
||||
// NewExecutor creates a new mock instance.
|
||||
func NewExecutor(ctrl *gomock.Controller) *Executor {
|
||||
mock := &Executor{ctrl: ctrl}
|
||||
mock.recorder = &ExecutorMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
func (e *Executor) APIServerHandlers(ctx context.Context) (authenticator.Request, http.Handler, error) {
|
||||
return nil, nil, errors.New("not implemented")
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *Executor) EXPECT() *ExecutorMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
func (e *Executor) APIServer(ctx context.Context, args []string) error {
|
||||
return errors.New("not implemented")
|
||||
// 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
|
||||
}
|
||||
|
||||
func (e *Executor) Scheduler(ctx context.Context, nodeReady <-chan struct{}, args []string) error {
|
||||
return errors.New("not implemented")
|
||||
// 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)
|
||||
}
|
||||
|
||||
func (e *Executor) ControllerManager(ctx context.Context, args []string) error {
|
||||
return errors.New("not implemented")
|
||||
// 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
|
||||
}
|
||||
|
||||
func (e *Executor) CurrentETCDOptions() (executor.InitialOptions, error) {
|
||||
return executor.InitialOptions{}, nil
|
||||
// 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)
|
||||
}
|
||||
|
||||
func (e *Executor) ETCD(ctx context.Context, args *executor.ETCDConfig, extraArgs []string, test executor.TestFunc) error {
|
||||
embed := &executor.Embedded{}
|
||||
return embed.ETCD(ctx, args, extraArgs, test)
|
||||
// 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
|
||||
}
|
||||
|
||||
func (e *Executor) CloudControllerManager(ctx context.Context, ccmRBACReady <-chan struct{}, args []string) error {
|
||||
return errors.New("not implemented")
|
||||
// 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))
|
||||
}
|
||||
|
||||
func (e *Executor) Containerd(ctx context.Context, node *config.Node) error {
|
||||
return errors.New("not implemented")
|
||||
// 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
|
||||
}
|
||||
|
||||
func (e *Executor) Docker(ctx context.Context, node *config.Node) error {
|
||||
return errors.New("not implemented")
|
||||
// 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)
|
||||
}
|
||||
|
||||
func (e *Executor) CRI(ctx context.Context, node *config.Node) error {
|
||||
return errors.New("not implemented")
|
||||
// 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
|
||||
}
|
||||
|
||||
func (e *Executor) APIServerReadyChan() <-chan struct{} {
|
||||
c := make(chan struct{})
|
||||
close(c)
|
||||
return c
|
||||
// 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)
|
||||
}
|
||||
|
||||
func (e *Executor) ETCDReadyChan() <-chan struct{} {
|
||||
c := make(chan struct{})
|
||||
close(c)
|
||||
return c
|
||||
// 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
|
||||
}
|
||||
|
||||
func (e *Executor) CRIReadyChan() <-chan struct{} {
|
||||
c := make(chan struct{})
|
||||
close(c)
|
||||
return c
|
||||
// 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)
|
||||
}
|
||||
|
||||
// ControllerManager mocks base method.
|
||||
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
|
||||
}
|
||||
|
||||
// ControllerManager indicates an expected call of ControllerManager.
|
||||
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)
|
||||
}
|
||||
|
||||
// CurrentETCDOptions mocks base method.
|
||||
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
|
||||
}
|
||||
|
||||
// CurrentETCDOptions indicates an expected call of CurrentETCDOptions.
|
||||
func (mr *ExecutorMockRecorder) CurrentETCDOptions() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentETCDOptions", reflect.TypeOf((*Executor)(nil).CurrentETCDOptions))
|
||||
}
|
||||
|
||||
// Docker mocks base method.
|
||||
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
|
||||
}
|
||||
|
||||
// Docker indicates an expected call of Docker.
|
||||
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)
|
||||
}
|
||||
|
||||
// ETCD mocks base method.
|
||||
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
|
||||
}
|
||||
|
||||
// ETCD indicates an expected call of ETCD.
|
||||
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)
|
||||
}
|
||||
|
||||
// ETCDReadyChan mocks base method.
|
||||
func (m *Executor) ETCDReadyChan() <-chan struct{} {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ETCDReadyChan")
|
||||
ret0, _ := ret[0].(<-chan struct{})
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ETCDReadyChan indicates an expected call of ETCDReadyChan.
|
||||
func (mr *ExecutorMockRecorder) ETCDReadyChan() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ETCDReadyChan", reflect.TypeOf((*Executor)(nil).ETCDReadyChan))
|
||||
}
|
||||
|
||||
// KubeProxy mocks base method.
|
||||
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
|
||||
}
|
||||
|
||||
// KubeProxy indicates an expected call of KubeProxy.
|
||||
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)
|
||||
}
|
||||
|
||||
// Kubelet mocks base method.
|
||||
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
|
||||
}
|
||||
|
||||
// Kubelet indicates an expected call of Kubelet.
|
||||
func (mr *ExecutorMockRecorder) Kubelet(ctx, args any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Kubelet", reflect.TypeOf((*Executor)(nil).Kubelet), ctx, args)
|
||||
}
|
||||
|
||||
// Scheduler mocks base method.
|
||||
func (m *Executor) Scheduler(ctx context.Context, nodeReady <-chan struct{}, args []string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Scheduler", ctx, nodeReady, args)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Scheduler indicates an expected call of Scheduler.
|
||||
func (mr *ExecutorMockRecorder) Scheduler(ctx, nodeReady, args any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Scheduler", reflect.TypeOf((*Executor)(nil).Scheduler), ctx, nodeReady, args)
|
||||
}
|
||||
|
|
|
|||
33
tests/mock/executor_helpers.go
Normal file
33
tests/mock/executor_helpers.go
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
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 (
|
|||
|
||||
"github.com/k3s-io/k3s/pkg/daemons/config"
|
||||
"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>/".
|
||||
|
|
@ -45,9 +43,6 @@ func CleanupDataDir(cnf *config.Control) {
|
|||
// GenerateRuntime creates a temporary data dir and configures
|
||||
// config.ControlRuntime with all the appropriate certificate keys.
|
||||
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
|
||||
cnf.Runtime = config.NewRuntime()
|
||||
if err := GenerateDataDir(cnf); err != nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue