Skip to content

Commit

Permalink
enhance(executor tests): Call k8s SetupMock method after CreateBuild …
Browse files Browse the repository at this point in the history
…in tests (#425)

* enhance: extract kubernetes runtime mock setup

In order to run the PodTracker mock setup in executor tests,
we need to export something

* Call k8s SetupMock in executor Build test

* test: Add kubernetes SetupMock to executor StreamBuild test

* mark exported k8s Mock functions as test-only functions
  • Loading branch information
cognifloyd authored Feb 24, 2023
1 parent ce7e8fe commit e49cd1a
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 6 deletions.
26 changes: 25 additions & 1 deletion executor/linux/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,14 @@ func TestLinux_ExecBuild(t *testing.T) {
// go-vela/server has logic to set it to an expected state.
_engine.build.SetStatus("running")

// Kubernetes runtime needs to set up the Mock after CreateBuild is called
if test.runtime == constants.DriverKubernetes {
err = _runtime.(kubernetes.MockKubernetesRuntime).SetupMock()
if err != nil {
t.Errorf("Kubernetes runtime SetupMock returned err: %v", err)
}
}

err = _engine.ExecBuild(context.Background())

if test.failure {
Expand Down Expand Up @@ -1882,8 +1890,16 @@ func TestLinux_StreamBuild(t *testing.T) {
t.Errorf("%s unable to create build: %v", test.name, err)
}

// simulate ExecBuild() which runs concurrently with StreamBuild()
// simulate AssembleBuild()/ExecBuild() which run concurrently with StreamBuild()
go func() {
// This Kubernetes setup would normally be called within AssembleBuild()
if test.runtime == constants.DriverKubernetes {
err = _runtime.(kubernetes.MockKubernetesRuntime).SetupMock()
if err != nil {
t.Errorf("Kubernetes runtime SetupMock returned err: %v", err)
}
}

if test.earlyBuildDone {
// imitate build getting canceled or otherwise finishing before ExecBuild gets called.
done()
Expand Down Expand Up @@ -2092,6 +2108,14 @@ func TestLinux_DestroyBuild(t *testing.T) {
t.Errorf("%s unable to create build: %v", test.name, err)
}

// Kubernetes runtime needs to set up the Mock after CreateBuild is called
if test.runtime == constants.DriverKubernetes {
err = _runtime.(kubernetes.MockKubernetesRuntime).SetupMock()
if err != nil {
t.Errorf("Kubernetes runtime SetupMock returned err: %v", err)
}
}

err = _engine.DestroyBuild(context.Background())

if test.failure {
Expand Down
24 changes: 24 additions & 0 deletions executor/linux/secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,14 @@ func TestLinux_Secret_delete(t *testing.T) {
// add init container info to client
_ = _engine.CreateBuild(context.Background())

// Kubernetes runtime needs to set up the Mock after CreateBuild is called
if test.runtime.Driver() == constants.DriverKubernetes {
err = _engine.Runtime.(kubernetes.MockKubernetesRuntime).SetupMock()
if err != nil {
t.Errorf("Kubernetes runtime SetupMock returned err: %v", err)
}
}

_engine.steps.Store(test.container.ID, test.step)

err = _engine.secret.destroy(context.Background(), test.container)
Expand Down Expand Up @@ -349,6 +357,14 @@ func TestLinux_Secret_exec(t *testing.T) {
// add init container info to client
_ = _engine.CreateBuild(context.Background())

// Kubernetes runtime needs to set up the Mock after CreateBuild is called
if test.runtime == constants.DriverKubernetes {
err = _runtime.(kubernetes.MockKubernetesRuntime).SetupMock()
if err != nil {
t.Errorf("Kubernetes runtime SetupMock returned err: %v", err)
}
}

err = _engine.secret.exec(context.Background(), &p.Secrets)

if test.failure {
Expand Down Expand Up @@ -623,6 +639,14 @@ func TestLinux_Secret_stream(t *testing.T) {
// add init container info to client
_ = _engine.CreateBuild(context.Background())

// Kubernetes runtime needs to set up the Mock after CreateBuild is called
if test.runtime.Driver() == constants.DriverKubernetes {
err = _engine.Runtime.(kubernetes.MockKubernetesRuntime).SetupMock()
if err != nil {
t.Errorf("Kubernetes runtime SetupMock returned err: %v", err)
}
}

err = _engine.secret.stream(context.Background(), test.container)

if test.failure {
Expand Down
15 changes: 14 additions & 1 deletion runtime/kubernetes/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@

package kubernetes

// Everything in this file should only be used in test code.
// It is exported for use in tests of other packages.

import (
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"

velav1alpha1 "github.com/go-vela/worker/runtime/kubernetes/apis/vela/v1alpha1"
fakeVelaK8sClient "github.com/go-vela/worker/runtime/kubernetes/generated/clientset/versioned/fake"
"github.com/sirupsen/logrus"
)

// NewMock returns an Engine implementation that
Expand Down Expand Up @@ -90,10 +93,20 @@ func NewMock(_pod *v1.Pod, opts ...ClientOpt) (*client, error) {
//
// This interface is intended for running tests only.
type MockKubernetesRuntime interface {
SetupMock() error
MarkPodTrackerReady()
SimulateResync(*v1.Pod)
}

// SetupMock allows the Kubernetes runtime to perform additional Mock-related config.
// Many tests should call this right after they call runtime.SetupBuild (or executor.CreateBuild).
//
// This function is intended for running tests only.
func (c *client) SetupMock() error {
// This assumes that c.Pod.ObjectMeta.Namespace and c.Pod.ObjectMeta.Name are filled in.
return c.PodTracker.setupMockFor(c.Pod)
}

// MarkPodTrackerReady signals that PodTracker has been setup with ContainerTrackers.
//
// This function is intended for running tests only.
Expand Down
18 changes: 14 additions & 4 deletions runtime/kubernetes/pod_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,24 @@ func mockPodTracker(log *logrus.Entry, clientset kubernetes.Interface, pod *v1.P
return nil, err
}

err = tracker.setupMockFor(pod)
if err != nil {
return nil, err
}

return tracker, err
}

// setupMockFor initializes the podTracker's internal caches with the given pod.
func (p *podTracker) setupMockFor(pod *v1.Pod) error {
// init containerTrackers as well
tracker.TrackContainers(pod.Spec.Containers)
p.TrackContainers(pod.Spec.Containers)

// pre-populate the podInformer cache
err = tracker.podInformer.Informer().GetIndexer().Add(pod)
err := p.podInformer.Informer().GetIndexer().Add(pod)
if err != nil {
return nil, err
return err
}

return tracker, err
return nil
}

0 comments on commit e49cd1a

Please sign in to comment.