Skip to content

Commit

Permalink
add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
anik120 committed Aug 19, 2024
1 parent db34956 commit 26a24c7
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 104 deletions.
51 changes: 47 additions & 4 deletions pkg/controller/operators/catalog/operator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1929,11 +1929,36 @@ func TestValidateV1CRDCompatibility(t *testing.T) {
func TestSyncRegistryServer(t *testing.T) {
namespace := "ns"

configmapCatalog := &v1alpha1.CatalogSource{
ObjectMeta: metav1.ObjectMeta{
Name: "cool-catalog",
Namespace: "cool-namespace",
UID: types.UID("catalog-uid"),
},
Spec: v1alpha1.CatalogSourceSpec{
ConfigMap: "cool-configmap",
SourceType: v1alpha1.SourceTypeInternal,
},
}
grpcCatalog := &v1alpha1.CatalogSource{
ObjectMeta: metav1.ObjectMeta{
Name: "cool-catalog",
Namespace: "cool-namespace",
UID: types.UID("catalog-uid"),
Labels: map[string]string{"olm.catalogSource": "cool-catalog"},
},
Spec: v1alpha1.CatalogSourceSpec{
Image: "catalog-image",
SourceType: v1alpha1.SourceTypeGrpc,
},
}

tests := []struct {
testName string
err error
catSrc *v1alpha1.CatalogSource
clientObjs []runtime.Object
testName string
err error
catSrc *v1alpha1.CatalogSource
clientObjs []runtime.Object
cleanRegistryServerError bool
}{
{
testName: "EmptyRegistryPoll",
Expand All @@ -1946,6 +1971,18 @@ func TestSyncRegistryServer(t *testing.T) {
},
},
},
{
testName: "CleanRegistryServerGetsCalledGrpc",
err: fmt.Errorf("could not clean stale resources: message to ensure function is getting called"),
catSrc: grpcCatalog,
cleanRegistryServerError: true,
},
{
testName: "CleanRegistryServerGetsCalledConfigMap",
err: fmt.Errorf("could not clean stale resources: message to ensure function is getting called"),
catSrc: configmapCatalog,
cleanRegistryServerError: true,
},
}

for _, tt := range tests {
Expand All @@ -1963,6 +2000,12 @@ func TestSyncRegistryServer(t *testing.T) {
EnsureRegistryServerStub: func(logger *logrus.Entry, source *v1alpha1.CatalogSource) error {
return nil
},
CleanRegistryServerStub: func(e *logrus.Entry, cs *v1alpha1.CatalogSource) error {
if tt.cleanRegistryServerError {
return fmt.Errorf("message to ensure function is getting called")
}
return nil
},
}
},
}
Expand Down
128 changes: 46 additions & 82 deletions pkg/controller/registry/reconciler/configmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"time"

"github.com/ghodss/yaml"
k8slabels "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/util/labels"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
Expand All @@ -29,12 +28,6 @@ import (
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
)

const (
registryImageName = "test:image"
runAsUser = 1001
testNamespace = "testns"
)

type fakeReconcilerConfig struct {
now nowFunc
k8sObjs []runtime.Object
Expand Down Expand Up @@ -185,66 +178,6 @@ func validConfigMapCatalogSource(configMap *corev1.ConfigMap) *v1alpha1.CatalogS
}
}

func objectsForCatalogSource(t *testing.T, catsrc *v1alpha1.CatalogSource) []runtime.Object {
// the registry pod security context is derived from the defaultNamespace by default
// therefore a namespace resource must always be present
var objs = []runtime.Object{
defaultNamespace(),
}

switch catsrc.Spec.SourceType {
case v1alpha1.SourceTypeInternal, v1alpha1.SourceTypeConfigmap:
decorated := configMapCatalogSourceDecorator{catsrc, runAsUser}
service, err := decorated.Service()
if err != nil {
t.Fatal(err)
}
serviceAccount := decorated.ServiceAccount()
pod, err := decorated.Pod(registryImageName, defaultPodSecurityConfig)
if err != nil {
t.Fatal(err)
}
objs = append(objs,
pod,
service,
serviceAccount,
)
case v1alpha1.SourceTypeGrpc:
if catsrc.Spec.Image != "" {
decorated := grpcCatalogSourceDecorator{CatalogSource: catsrc, createPodAsUser: runAsUser, opmImage: ""}
serviceAccount := decorated.ServiceAccount()
service, err := decorated.Service()
if err != nil {
t.Fatal(err)
}
pod, err := decorated.Pod(serviceAccount, defaultPodSecurityConfig)
if err != nil {
t.Fatal(err)
}
objs = append(objs,
pod,
service,
serviceAccount,
)
}
}

blockOwnerDeletion := false
isController := false
for _, o := range objs {
mo := o.(metav1.Object)
mo.SetOwnerReferences([]metav1.OwnerReference{{
APIVersion: "operators.coreos.com/v1alpha1",
Kind: "CatalogSource",
Name: catsrc.GetName(),
UID: catsrc.GetUID(),
BlockOwnerDeletion: &blockOwnerDeletion,
Controller: &isController,
}})
}
return objs
}

func modifyObjName(objs []runtime.Object, kind runtime.Object, newName string) []runtime.Object {
var out []runtime.Object
t := reflect.TypeOf(kind)
Expand All @@ -260,21 +193,6 @@ func modifyObjName(objs []runtime.Object, kind runtime.Object, newName string) [
return out
}

func setLabel(objs []runtime.Object, kind runtime.Object, label, value string) []runtime.Object {
var out []runtime.Object
t := reflect.TypeOf(kind)
for _, obj := range objs {
o := obj.DeepCopyObject()
if reflect.TypeOf(o) == t {
if accessor, err := meta.Accessor(o); err == nil {
k8slabels.AddLabel(accessor.GetLabels(), label, value)
}
}
out = append(out, o)
}
return out
}

func TestConfigMapRegistryReconciler(t *testing.T) {
now := func() metav1.Time { return metav1.Date(2018, time.January, 26, 20, 40, 0, 0, time.UTC) }

Expand Down Expand Up @@ -527,3 +445,49 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
})
}
}

func TestConfigMapRegistryCleaner(t *testing.T) {
validConfigMap := validConfigMap()
validCatalogSource := validConfigMapCatalogSource(validConfigMap)
type cluster struct {
k8sObjs []runtime.Object
}
type in struct {
cluster cluster
catsrc *v1alpha1.CatalogSource
}
type out struct {
err error
}
tests := []struct {
testName string
in in
out out
}{
{
testName: "ConfigMap/ExistingRegistry/DeletedPod",
in: in{
cluster: cluster{
k8sObjs: withPodDeletedButNotRemoved(objectsForCatalogSource(t, validCatalogSource)),
},
catsrc: validCatalogSource,
},
},
}
for _, tt := range tests {
t.Run(tt.testName, func(t *testing.T) {
stopc := make(chan struct{})
defer close(stopc)

factory, _ := fakeReconcilerFactory(t, stopc, withK8sObjs(tt.in.cluster.k8sObjs...))
rec := factory.ReconcilerForSource(tt.in.catsrc)

err := rec.CleanRegistryServer(logrus.NewEntry(logrus.New()), tt.in.catsrc)

require.Equal(t, tt.out.err, err)
if tt.out.err != nil {
return
}
})
}
}
44 changes: 44 additions & 0 deletions pkg/controller/registry/reconciler/grpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,50 @@ func TestGrpcRegistryChecker(t *testing.T) {
}
}

func TestGrpcRegistryCleaner(t *testing.T) {
type cluster struct {
k8sObjs []runtime.Object
}
type in struct {
cluster cluster
catsrc *v1alpha1.CatalogSource
}
type out struct {
err error
}
tests := []struct {
testName string
in in
out out
}{
{
testName: "Grpc/ExistingRegistry/DeletedPod",
in: in{
cluster: cluster{
k8sObjs: withPodDeletedButNotRemoved(objectsForCatalogSource(t, validGrpcCatalogSource("old-img", ""))),
},
catsrc: validGrpcCatalogSource("new-img", ""),
},
},
}
for _, tt := range tests {
t.Run(tt.testName, func(t *testing.T) {
stopc := make(chan struct{})
defer close(stopc)

factory, _ := fakeReconcilerFactory(t, stopc, withK8sObjs(tt.in.cluster.k8sObjs...))
rec := factory.ReconcilerForSource(tt.in.catsrc)

err := rec.CleanRegistryServer(logrus.NewEntry(logrus.New()), tt.in.catsrc)

require.Equal(t, tt.out.err, err)
if tt.out.err != nil {
return
}
})
}
}

func TestGetPodImageID(t *testing.T) {
var table = []struct {
description string
Expand Down
18 changes: 0 additions & 18 deletions pkg/controller/registry/reconciler/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ import (
"github.com/operator-framework/api/pkg/operators/v1alpha1"
)

const workloadUserID = 1001
const defaultPodSecurityConfig = v1alpha1.Restricted

func TestPodMemoryTarget(t *testing.T) {
q := resource.MustParse("5Mi")
var testCases = []struct {
Expand Down Expand Up @@ -1125,18 +1122,3 @@ func baseClusterState() []runtime.Object {
defaultNamespace(),
}
}

// defaultNamespace returns a kubernetes namespace with the assumes default settings,
// e.g. Pod Security Admission security policy label
func defaultNamespace() *corev1.Namespace {
return &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: testNamespace,
Labels: map[string]string{
// catalogsource pod security configuration depends on the defaultNamespace psa configuration
// adding restricted PSA label as this is the default
"pod-security.kubernetes.io/enforce": "restricted",
},
},
}
}
Loading

0 comments on commit 26a24c7

Please sign in to comment.