Skip to content

Commit f9e2432

Browse files
YCShen1010YuChen
andauthored
Implement test cases for ODLM no olm controller (#1166)
Signed-off-by: YuChen <yuchen.shen@mail.utoronto.ca> Co-authored-by: YuChen <yuchen.shen@mail.utoronto.ca>
1 parent 38b9eee commit f9e2432

File tree

2 files changed

+354
-0
lines changed

2 files changed

+354
-0
lines changed
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
//
2+
// Copyright 2022 IBM Corporation
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
package operandrequestnoolm
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"sync"
23+
24+
. "github.com/onsi/ginkgo"
25+
. "github.com/onsi/gomega"
26+
corev1 "k8s.io/api/core/v1"
27+
"k8s.io/apimachinery/pkg/api/errors"
28+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29+
"k8s.io/apimachinery/pkg/types"
30+
"sigs.k8s.io/controller-runtime/pkg/client/fake"
31+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
32+
33+
operatorv1alpha1 "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1"
34+
"github.com/IBM/operand-deployment-lifecycle-manager/v4/controllers/constant"
35+
deploy "github.com/IBM/operand-deployment-lifecycle-manager/v4/controllers/operator"
36+
"github.com/IBM/operand-deployment-lifecycle-manager/v4/controllers/testutil"
37+
)
38+
39+
var _ = Describe("OperandRequestNoOLM controller", func() {
40+
const (
41+
name1 = "ibm-cloudpak-name"
42+
namespace = "ibm-cloudpak"
43+
registryName = "common-service"
44+
registryNamespace = "data-ns"
45+
)
46+
47+
var (
48+
ctx context.Context
49+
50+
namespaceName string
51+
registryNamespaceName string
52+
registry *operatorv1alpha1.OperandRegistry
53+
config *operatorv1alpha1.OperandConfig
54+
request *operatorv1alpha1.OperandRequest
55+
requestKey types.NamespacedName
56+
)
57+
58+
BeforeEach(func() {
59+
ctx = context.Background()
60+
namespaceName = testutil.CreateNSName(namespace)
61+
registryNamespaceName = testutil.CreateNSName(registryNamespace)
62+
registry = testutil.OperandRegistryObj(registryName, registryNamespaceName, registryNamespaceName)
63+
config = testutil.OperandConfigObj(registryName, registryNamespaceName)
64+
request = testutil.OperandRequestObj(registryName, registryNamespaceName, name1, namespaceName)
65+
requestKey = types.NamespacedName{Name: name1, Namespace: namespaceName}
66+
67+
By("Creating the Namespace")
68+
Expect(k8sClient.Create(ctx, testutil.NamespaceObj(namespaceName))).Should(Succeed())
69+
Expect(k8sClient.Create(ctx, testutil.NamespaceObj(registryNamespaceName))).Should(Succeed())
70+
})
71+
72+
Context("Reconciling OperandRequest without OLM", func() {
73+
It("Should add finalizer to OperandRequest", func() {
74+
By("Creating the OperandRegistry")
75+
Expect(k8sClient.Create(ctx, registry)).Should(Succeed())
76+
By("Creating the OperandConfig")
77+
Expect(k8sClient.Create(ctx, config)).Should(Succeed())
78+
By("Creating the OperandRequest")
79+
Expect(k8sClient.Create(ctx, request)).Should(Succeed())
80+
81+
By("Checking finalizer is added to the OperandRequest")
82+
Eventually(func() bool {
83+
instance := &operatorv1alpha1.OperandRequest{}
84+
Expect(k8sClient.Get(ctx, requestKey, instance)).Should(Succeed())
85+
return len(instance.GetFinalizers()) > 0
86+
}, testutil.Timeout, testutil.Interval).Should(BeTrue())
87+
})
88+
89+
It("Should handle permissions check correctly", func() {
90+
// Create a mock reconciler with a fake client
91+
fakeClient := fake.NewClientBuilder().Build()
92+
reconciler := &Reconciler{
93+
ODLMOperator: &deploy.ODLMOperator{
94+
Client: fakeClient,
95+
},
96+
Mutex: sync.Mutex{},
97+
}
98+
99+
// Test permission check
100+
By("Verifying no-permission case")
101+
hasPermission := reconciler.checkPermission(ctx, reconcile.Request{
102+
NamespacedName: types.NamespacedName{
103+
Name: "test-request",
104+
Namespace: "test-namespace",
105+
},
106+
})
107+
Expect(hasPermission).To(BeFalse())
108+
})
109+
110+
It("Should initialize request status", func() {
111+
By("Creating the OperandRegistry")
112+
Expect(k8sClient.Create(ctx, registry)).Should(Succeed())
113+
By("Creating the OperandConfig")
114+
Expect(k8sClient.Create(ctx, config)).Should(Succeed())
115+
By("Creating the OperandRequest")
116+
Expect(k8sClient.Create(ctx, request)).Should(Succeed())
117+
118+
By("Checking status is initialized")
119+
Eventually(func() bool {
120+
instance := &operatorv1alpha1.OperandRequest{}
121+
Expect(k8sClient.Get(ctx, requestKey, instance)).Should(Succeed())
122+
return instance.Status.Phase != ""
123+
}, testutil.Timeout, testutil.Interval).Should(BeTrue())
124+
})
125+
126+
It("Should handle deletion correctly", func() {
127+
By("Creating the OperandRegistry")
128+
Expect(k8sClient.Create(ctx, registry)).Should(Succeed())
129+
By("Creating the OperandConfig")
130+
Expect(k8sClient.Create(ctx, config)).Should(Succeed())
131+
By("Creating the OperandRequest")
132+
Expect(k8sClient.Create(ctx, request)).Should(Succeed())
133+
134+
By("Deleting the OperandRequest")
135+
Expect(k8sClient.Delete(ctx, request)).Should(Succeed())
136+
137+
By("Verifying finalizer is removed")
138+
Eventually(func() bool {
139+
instance := &operatorv1alpha1.OperandRequest{}
140+
err := k8sClient.Get(ctx, requestKey, instance)
141+
return errors.IsNotFound(err)
142+
}, testutil.Timeout, testutil.Interval).Should(BeTrue())
143+
})
144+
})
145+
146+
Context("Testing mapper functions", func() {
147+
It("Should map OperandRegistry to OperandRequests", func() {
148+
By("Creating the OperandRegistry")
149+
Expect(k8sClient.Create(ctx, registry)).Should(Succeed())
150+
By("Creating the OperandConfig")
151+
Expect(k8sClient.Create(ctx, config)).Should(Succeed())
152+
By("Creating the OperandRequest")
153+
Expect(k8sClient.Create(ctx, request)).Should(Succeed())
154+
155+
reconciler := &Reconciler{
156+
ODLMOperator: &deploy.ODLMOperator{
157+
Client: k8sClient,
158+
},
159+
}
160+
161+
By("Verifying getRegistryToRequestMapper works")
162+
mapper := reconciler.getRegistryToRequestMapper()
163+
requests := mapper(registry)
164+
Expect(len(requests)).To(BeNumerically(">", 0))
165+
})
166+
167+
It("Should map OperandConfig to OperandRequests", func() {
168+
By("Creating the OperandRegistry")
169+
Expect(k8sClient.Create(ctx, registry)).Should(Succeed())
170+
By("Creating the OperandConfig")
171+
Expect(k8sClient.Create(ctx, config)).Should(Succeed())
172+
By("Creating the OperandRequest")
173+
Expect(k8sClient.Create(ctx, request)).Should(Succeed())
174+
175+
reconciler := &Reconciler{
176+
ODLMOperator: &deploy.ODLMOperator{
177+
Client: k8sClient,
178+
},
179+
}
180+
181+
By("Verifying getConfigToRequestMapper works")
182+
mapper := reconciler.getConfigToRequestMapper()
183+
requests := mapper(config)
184+
Expect(len(requests)).To(BeNumerically(">", 0))
185+
})
186+
187+
It("Should map references to OperandRequests", func() {
188+
By("Creating the OperandRegistry")
189+
Expect(k8sClient.Create(ctx, registry)).Should(Succeed())
190+
By("Creating the OperandConfig")
191+
Expect(k8sClient.Create(ctx, config)).Should(Succeed())
192+
By("Creating the OperandRequest")
193+
Expect(k8sClient.Create(ctx, request)).Should(Succeed())
194+
195+
By("Creating a ConfigMap with reference annotation")
196+
cm := &corev1.ConfigMap{
197+
ObjectMeta: metav1.ObjectMeta{
198+
Name: "test-configmap",
199+
Namespace: registryNamespaceName,
200+
Annotations: map[string]string{
201+
constant.ODLMReferenceAnnotation: fmt.Sprintf("OperandRegistry.%s.%s", registryNamespaceName, registryName),
202+
},
203+
},
204+
Data: map[string]string{
205+
"test-key": "test-value",
206+
},
207+
}
208+
Expect(k8sClient.Create(ctx, cm)).Should(Succeed())
209+
210+
reconciler := &Reconciler{
211+
ODLMOperator: &deploy.ODLMOperator{
212+
Client: k8sClient,
213+
},
214+
}
215+
216+
By("Verifying getReferenceToRequestMapper works")
217+
mapper := reconciler.getReferenceToRequestMapper()
218+
requests := mapper(cm)
219+
Expect(len(requests)).To(BeNumerically(">", 0))
220+
})
221+
})
222+
})
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//
2+
// Copyright 2022 IBM Corporation
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
package operandrequestnoolm
18+
19+
import (
20+
"os"
21+
"path/filepath"
22+
"testing"
23+
"time"
24+
25+
jaegerv1 "github.com/jaegertracing/jaeger-operator/apis/v1"
26+
. "github.com/onsi/ginkgo"
27+
. "github.com/onsi/gomega"
28+
"github.com/onsi/gomega/gexec"
29+
olmv1 "github.com/operator-framework/api/pkg/operators/v1"
30+
olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
31+
operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1"
32+
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
33+
"k8s.io/client-go/rest"
34+
ctrl "sigs.k8s.io/controller-runtime"
35+
"sigs.k8s.io/controller-runtime/pkg/client"
36+
"sigs.k8s.io/controller-runtime/pkg/envtest"
37+
logf "sigs.k8s.io/controller-runtime/pkg/log"
38+
"sigs.k8s.io/controller-runtime/pkg/log/zap"
39+
40+
nssv1 "github.com/IBM/ibm-namespace-scope-operator/api/v1"
41+
apiv1alpha1 "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1"
42+
deploy "github.com/IBM/operand-deployment-lifecycle-manager/v4/controllers/operator"
43+
// +kubebuilder:scaffold:imports
44+
)
45+
46+
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
47+
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
48+
49+
const useExistingCluster = "USE_EXISTING_CLUSTER"
50+
51+
var (
52+
cfg *rest.Config
53+
k8sClient client.Client
54+
testEnv *envtest.Environment
55+
)
56+
57+
func TestOperanRequestNoOLM(t *testing.T) {
58+
RegisterFailHandler(Fail)
59+
60+
RunSpecs(t,
61+
"OperandRequest NoOLM Controller Suite")
62+
}
63+
64+
var _ = BeforeSuite(func(done Done) {
65+
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
66+
67+
By("bootstrapping test environment")
68+
testEnv = &envtest.Environment{
69+
UseExistingCluster: UseExistingCluster(),
70+
CRDDirectoryPaths: []string{filepath.Join("../..", "config", "crd", "bases"), filepath.Join("../..", "testcrds")},
71+
}
72+
73+
var err error
74+
cfg, err = testEnv.Start()
75+
Expect(err).ToNot(HaveOccurred())
76+
Expect(cfg).ToNot(BeNil())
77+
78+
err = apiv1alpha1.AddToScheme(clientgoscheme.Scheme)
79+
Expect(err).NotTo(HaveOccurred())
80+
// +kubebuilder:scaffold:scheme
81+
82+
err = nssv1.AddToScheme(clientgoscheme.Scheme)
83+
Expect(err).NotTo(HaveOccurred())
84+
err = olmv1alpha1.AddToScheme(clientgoscheme.Scheme)
85+
Expect(err).NotTo(HaveOccurred())
86+
err = olmv1.AddToScheme(clientgoscheme.Scheme)
87+
Expect(err).NotTo(HaveOccurred())
88+
err = jaegerv1.AddToScheme(clientgoscheme.Scheme)
89+
Expect(err).NotTo(HaveOccurred())
90+
err = operatorsv1.AddToScheme(clientgoscheme.Scheme)
91+
Expect(err).NotTo(HaveOccurred())
92+
93+
k8sClient, err = client.New(cfg, client.Options{Scheme: clientgoscheme.Scheme})
94+
Expect(err).ToNot(HaveOccurred())
95+
Expect(k8sClient).ToNot(BeNil())
96+
97+
// Start your controllers test logic
98+
k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{
99+
Scheme: clientgoscheme.Scheme,
100+
MetricsBindAddress: "0",
101+
})
102+
Expect(err).ToNot(HaveOccurred())
103+
104+
// Setup Manager with OperandRequestNoOLM Controller
105+
err = (&Reconciler{
106+
ODLMOperator: deploy.NewODLMOperator(k8sManager, "OperandRequestNoOLM"),
107+
StepSize: 3,
108+
}).SetupWithManager(k8sManager)
109+
Expect(err).ToNot(HaveOccurred())
110+
111+
go func() {
112+
err = k8sManager.Start(ctrl.SetupSignalHandler())
113+
Expect(err).ToNot(HaveOccurred())
114+
}()
115+
116+
close(done)
117+
}, 600)
118+
119+
var _ = AfterSuite(func() {
120+
By("tearing down the test environment")
121+
gexec.KillAndWait(5 * time.Second)
122+
err := testEnv.Stop()
123+
Expect(err).ToNot(HaveOccurred())
124+
})
125+
126+
func UseExistingCluster() *bool {
127+
use := false
128+
if os.Getenv(useExistingCluster) != "" && os.Getenv(useExistingCluster) == "true" {
129+
use = true
130+
}
131+
return &use
132+
}

0 commit comments

Comments
 (0)