Skip to content

Commit

Permalink
Provide operator unittest
Browse files Browse the repository at this point in the history
Tests run reconcile loop and verify:
- components creation
- components deletion
- finalizer adding
- finalizer removing
- basic fields verification
  • Loading branch information
Artyom Lukianov committed Jan 2, 2020
1 parent 4daec61 commit fd9054e
Show file tree
Hide file tree
Showing 3 changed files with 252 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package performanceprofile

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/openshift-kni/performance-addon-operators/pkg/apis"
configv1 "github.com/openshift/api/config/v1"
tunedv1 "github.com/openshift/cluster-node-tuning-operator/pkg/apis/tuned/v1"
mcov1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"

"k8s.io/client-go/kubernetes/scheme"
)

func TestFeatureGate(t *testing.T) {
RegisterFailHandler(Fail)

// add resources API to default scheme
apis.AddToScheme(scheme.Scheme)
configv1.AddToScheme(scheme.Scheme)
mcov1.AddToScheme(scheme.Scheme)
tunedv1.AddToScheme(scheme.Scheme)

RunSpecs(t, "Performance Profile Suite")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package performanceprofile

import (
"context"
"time"

"github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components/featuregate"
"github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components/tuned"

"github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components/kubeletconfig"

"github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components/machineconfig"

"github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components/machineconfigpool"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
performancev1alpha1 "github.com/openshift-kni/performance-addon-operators/pkg/apis/performance/v1alpha1"
"github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components"
testutils "github.com/openshift-kni/performance-addon-operators/pkg/utils/testing"
configv1 "github.com/openshift/api/config/v1"
tunedv1 "github.com/openshift/cluster-node-tuning-operator/pkg/apis/tuned/v1"
mcov1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"

"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/scheme"

"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)

const assetsDir = "../../../build/assets"

var _ = Describe("Controller", func() {
var request reconcile.Request
var profile *performancev1alpha1.PerformanceProfile

BeforeEach(func() {
profile = testutils.NewPerformanceProfile("test")
request = reconcile.Request{
NamespacedName: types.NamespacedName{
Namespace: metav1.NamespaceNone,
Name: profile.Name,
},
}
})

It("should add finalizer to the performance profile", func() {
r := newFakeReconciler(profile)

result, err := r.Reconcile(request)
Expect(err).ToNot(HaveOccurred())
Expect(result).To(Equal(reconcile.Result{}))

updatedProfile := &performancev1alpha1.PerformanceProfile{}
key := types.NamespacedName{
Name: profile.Name,
Namespace: metav1.NamespaceNone,
}
Expect(r.client.Get(context.TODO(), key, updatedProfile)).ToNot(HaveOccurred())
Expect(hasFinalizer(updatedProfile, finalizer)).To(Equal(true))
})

It("should verify scripts required parameters", func() {
profile.Finalizers = append(profile.Finalizers, finalizer)
profile.Spec.CPU.Isolated = nil
r := newFakeReconciler(profile)

// we do not return error, because we do not want to reconcile again, and just print error under the log,
// once we will have validation webhook, this test will not be relevant anymore
result, err := r.Reconcile(request)
Expect(err).ToNot(HaveOccurred())
Expect(result).To(Equal(reconcile.Result{}))

// verify that no components created by the controller
mcp := &mcov1.MachineConfigPool{}
key := types.NamespacedName{
Name: components.GetComponentName(profile.Name, components.RoleWorkerPerformance),
Namespace: metav1.NamespaceNone,
}
err = r.client.Get(context.TODO(), key, mcp)
Expect(errors.IsNotFound(err)).To(Equal(true))
})

It("should create all needed components", func() {
profile.Finalizers = append(profile.Finalizers, finalizer)
profile.Spec.NodeSelector = map[string]string{"test": "test"}
r := newFakeReconciler(profile)

result, err := r.Reconcile(request)
Expect(err).ToNot(HaveOccurred())
Expect(result).To(Equal(reconcile.Result{}))

// verify that controller created all components
name := components.GetComponentName(profile.Name, components.RoleWorkerPerformance)
key := types.NamespacedName{
Name: name,
Namespace: metav1.NamespaceNone,
}

// verify MachineConfigPool creation
mcp := &mcov1.MachineConfigPool{}
err = r.client.Get(context.TODO(), key, mcp)
Expect(err).ToNot(HaveOccurred())

// verify MachineConfig creation
mc := &mcov1.MachineConfig{}
err = r.client.Get(context.TODO(), key, mc)
Expect(err).ToNot(HaveOccurred())

// verify KubeletConfig creation
kc := &mcov1.KubeletConfig{}
err = r.client.Get(context.TODO(), key, kc)
Expect(err).ToNot(HaveOccurred())

// verify FeatureGate creation
fg := &configv1.FeatureGate{}
key.Name = components.FeatureGateLatencySensetiveName
err = r.client.Get(context.TODO(), key, fg)
Expect(err).ToNot(HaveOccurred())

// verify tuned LatencySensitive creation
tunedLatency := &tunedv1.Tuned{}
key.Name = components.ProfileNameNetworkLatency
key.Namespace = components.NamespaceNodeTuningOperator
err = r.client.Get(context.TODO(), key, tunedLatency)
Expect(err).ToNot(HaveOccurred())

// verify tuned tuned real-time kernel creation
tunedRTKernel := &tunedv1.Tuned{}
key.Name = components.GetComponentName(profile.Name, components.ProfileNameWorkerRT)
err = r.client.Get(context.TODO(), key, tunedRTKernel)
Expect(err).ToNot(HaveOccurred())
})

Context("with profile with deletion timestamp", func() {
BeforeEach(func() {
profile.DeletionTimestamp = &metav1.Time{
Time: time.Now(),
}
})

It("should remove all components and remove the finalizer", func() {
profile.Finalizers = append(profile.Finalizers, finalizer)
profile.Spec.NodeSelector = map[string]string{"test": "test"}

mcp := machineconfigpool.NewPerformance(profile)

mc, err := machineconfig.NewPerformance(assetsDir, profile)
Expect(err).ToNot(HaveOccurred())

kc := kubeletconfig.NewPerformance(profile)

fg := featuregate.NewLatencySensitive()

tunedLatency, err := tuned.NewNetworkLatency(assetsDir)
Expect(err).ToNot(HaveOccurred())

tunedRTKernel, err := tuned.NewWorkerRealTimeKernel(assetsDir, profile)
Expect(err).ToNot(HaveOccurred())

r := newFakeReconciler(profile, mcp, mc, kc, fg, tunedLatency, tunedRTKernel)
result, err := r.Reconcile(request)
Expect(err).ToNot(HaveOccurred())
Expect(result).To(Equal(reconcile.Result{}))

// verify that controller deleted all components
name := components.GetComponentName(profile.Name, components.RoleWorkerPerformance)
key := types.NamespacedName{
Name: name,
Namespace: metav1.NamespaceNone,
}

// verify MachineConfigPool deletion
err = r.client.Get(context.TODO(), key, mcp)
Expect(errors.IsNotFound(err)).To(Equal(true))

// verify MachineConfig deletion
err = r.client.Get(context.TODO(), key, mc)
Expect(errors.IsNotFound(err)).To(Equal(true))

// verify KubeletConfig deletion
err = r.client.Get(context.TODO(), key, kc)
Expect(errors.IsNotFound(err)).To(Equal(true))

// verify feature gate deletion
key.Name = components.FeatureGateLatencySensetiveName
err = r.client.Get(context.TODO(), key, fg)
Expect(errors.IsNotFound(err)).To(Equal(true))

// verify tuned latency deletion
key.Name = components.ProfileNameNetworkLatency
key.Namespace = components.NamespaceNodeTuningOperator
err = r.client.Get(context.TODO(), key, tunedLatency)
Expect(errors.IsNotFound(err)).To(Equal(true))

// verify tuned real-time kernel deletion
key.Name = components.GetComponentName(profile.Name, components.ProfileNameWorkerRT)
key.Namespace = components.NamespaceNodeTuningOperator
err = r.client.Get(context.TODO(), key, tunedRTKernel)
Expect(errors.IsNotFound(err)).To(Equal(true))

// verify finalizer deletion
key.Name = profile.Name
key.Namespace = metav1.NamespaceNone
updatedProfile := &performancev1alpha1.PerformanceProfile{}
Expect(r.client.Get(context.TODO(), key, updatedProfile)).ToNot(HaveOccurred())
Expect(hasFinalizer(updatedProfile, finalizer)).To(Equal(false))
})
})
})

// newFakeReconciler returns a new reconcile.Reconciler with a fake client
func newFakeReconciler(initObjects ...runtime.Object) *ReconcilePerformanceProfile {
fakeClient := fake.NewFakeClient(initObjects...)
return &ReconcilePerformanceProfile{
client: fakeClient,
scheme: scheme.Scheme,
assetsDir: assetsDir,
}
}
2 changes: 2 additions & 0 deletions pkg/utils/testing/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
performancev1alpha1 "github.com/openshift-kni/performance-addon-operators/pkg/apis/performance/v1alpha1"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/pointer"
)

Expand Down Expand Up @@ -31,6 +32,7 @@ func NewPerformanceProfile(name string) *performancev1alpha1.PerformanceProfile
TypeMeta: metav1.TypeMeta{Kind: "PerformanceProfile"},
ObjectMeta: metav1.ObjectMeta{
Name: name,
UID: types.UID("11111111-1111-1111-1111-1111111111111"),
},
Spec: performancev1alpha1.PerformanceProfileSpec{
CPU: &performancev1alpha1.CPU{
Expand Down

0 comments on commit fd9054e

Please sign in to comment.