@@ -2,108 +2,44 @@ package operator
22
33import (
44 "context"
5+ "reflect"
56 "testing"
67
78 appsv1alpha1 "github.com/3scale/3scale-operator/apis/apps/v1alpha1"
89 "github.com/3scale/3scale-operator/pkg/3scale/amp/component"
9- "github.com/3scale/3scale-operator/pkg/reconcilers"
10+ "github.com/google/go-cmp/cmp"
11+ k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
1012
11- grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1"
12- configv1 "github.com/openshift/api/config/v1"
13- imagev1 "github.com/openshift/api/image/v1"
14- routev1 "github.com/openshift/api/route/v1"
15- monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
1613 k8sappsv1 "k8s.io/api/apps/v1"
1714 batchv1 "k8s.io/api/batch/v1"
1815 v1 "k8s.io/api/core/v1"
1916 policyv1 "k8s.io/api/policy/v1"
2017 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2118 "k8s.io/apimachinery/pkg/runtime"
2219 "k8s.io/apimachinery/pkg/types"
23- fakeclientset "k8s.io/client-go/kubernetes/fake"
2420 "k8s.io/client-go/kubernetes/scheme"
25- "k8s.io/client-go/tools/record"
26- k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
27- "sigs.k8s.io/controller-runtime/pkg/client/fake"
28- logf "sigs.k8s.io/controller-runtime/pkg/log"
2921)
3022
3123func TestSystemReconcilerCreate (t * testing.T ) {
32- log := logf .Log .WithName ("operator_test" )
33-
34- ctx := context .TODO ()
3524 apimanager := basicApimanagerSpecTestSystemOptions ()
36- appPreHookJob := & batchv1.Job {
37- ObjectMeta : metav1.ObjectMeta {Name : component .SystemAppPreHookJobName , Namespace : apimanager .Namespace },
38- Spec : batchv1.JobSpec {
39- Template : v1.PodTemplateSpec {
40- Spec : v1.PodSpec {
41- Containers : []v1.Container {
42- {
43- Image : SystemImageURL (),
44- },
45- },
46- },
47- },
48- },
49- Status : batchv1.JobStatus {
50- Conditions : []batchv1.JobCondition {
51- {
52- Type : batchv1 .JobComplete ,
53- Status : v1 .ConditionTrue ,
54- },
55- },
56- },
57- }
5825 systemDatabaseSecret := createSystemDBSecret (apimanager .Namespace )
5926 systemRedisSecret := createSystemRedisSecret (apimanager .Namespace )
27+ appPreHookJob := createAppPreHookJob (apimanager .Namespace )
6028
6129 // Objects to track in the fake client.
6230 objs := []runtime.Object {appPreHookJob , apimanager , systemDatabaseSecret , systemRedisSecret }
6331
6432 s := scheme .Scheme
65- s .AddKnownTypes (appsv1alpha1 .GroupVersion , & appsv1alpha1.APIManager {})
66- s .AddKnownTypes (v1 .SchemeGroupVersion , & v1.Secret {}, & v1.SecretList {})
67- err := v1 .AddToScheme (s )
33+ err := appsv1alpha1 .AddToScheme (s )
6834 if err != nil {
6935 t .Fatal (err )
7036 }
7137 err = k8sappsv1 .AddToScheme (s )
7238 if err != nil {
7339 t .Fatal (err )
7440 }
75- err = imagev1 .Install (s )
76- if err != nil {
77- t .Fatal (err )
78- }
79- err = routev1 .Install (s )
80- if err != nil {
81- t .Fatal (err )
82- }
83- if err := monitoringv1 .AddToScheme (s ); err != nil {
84- t .Fatal (err )
85- }
86- if err := grafanav1alpha1 .AddToScheme (s ); err != nil {
87- t .Fatal (err )
88- }
89- if err := configv1 .Install (s ); err != nil {
90- t .Fatal (err )
91- }
9241
93- // Create a fake client to mock API calls.
94- cl := fake .NewClientBuilder ().
95- WithScheme (s ).
96- WithRuntimeObjects (objs ... ).
97- Build ()
98- clientAPIReader := fake .NewClientBuilder ().
99- WithScheme (s ).
100- WithRuntimeObjects (objs ... ).
101- Build ()
102- clientset := fakeclientset .NewSimpleClientset ()
103- recorder := record .NewFakeRecorder (10000 )
104-
105- baseReconciler := reconcilers .NewBaseReconciler (ctx , cl , s , clientAPIReader , log , clientset .Discovery (), recorder )
106- baseAPIManagerLogicReconciler := NewBaseAPIManagerLogicReconciler (baseReconciler , apimanager )
42+ baseAPIManagerLogicReconciler , cl := setupTestBaseReconciler (s , apimanager , objs )
10743
10844 reconciler := NewSystemReconciler (baseAPIManagerLogicReconciler )
10945 _ , err = reconciler .Reconcile ()
@@ -157,36 +93,13 @@ func TestSystemReconcilerCreate(t *testing.T) {
15793func TestReplicaSystemReconciler (t * testing.T ) {
15894 var (
15995 namespace = "operator-unittest"
160- log = logf .Log .WithName ("operator_test" )
16196 oneValue int32 = 1
16297 oneValue64 int64 = 1
16398 twoValue int32 = 2
16499 )
165100
166- appPreHookJob := & batchv1.Job {
167- ObjectMeta : metav1.ObjectMeta {Name : component .SystemAppPreHookJobName , Namespace : namespace },
168- Spec : batchv1.JobSpec {
169- Template : v1.PodTemplateSpec {
170- Spec : v1.PodSpec {
171- Containers : []v1.Container {
172- {
173- Image : SystemImageURL (),
174- },
175- },
176- },
177- },
178- },
179- Status : batchv1.JobStatus {
180- Conditions : []batchv1.JobCondition {
181- {
182- Type : batchv1 .JobComplete ,
183- Status : v1 .ConditionTrue ,
184- },
185- },
186- },
187- }
101+ appPreHookJob := createAppPreHookJob (namespace )
188102
189- ctx := context .TODO ()
190103 s := scheme .Scheme
191104
192105 err := appsv1alpha1 .AddToScheme (s )
@@ -197,9 +110,6 @@ func TestReplicaSystemReconciler(t *testing.T) {
197110 if err != nil {
198111 t .Fatal (err )
199112 }
200- if err := configv1 .Install (s ); err != nil {
201- t .Fatal (err )
202- }
203113
204114 cases := []struct {
205115 testName string
@@ -220,13 +130,7 @@ func TestReplicaSystemReconciler(t *testing.T) {
220130 systemRedisSecret := createSystemRedisSecret (tc .apimanager .Namespace )
221131 objs := []runtime.Object {tc .apimanager , appPreHookJob , systemDatabaseSecret , systemRedisSecret }
222132
223- // Create a fake client to mock API calls.
224- cl := fake .NewFakeClient (objs ... )
225- clientAPIReader := fake .NewFakeClient (objs ... )
226- clientset := fakeclientset .NewSimpleClientset ()
227- recorder := record .NewFakeRecorder (10000 )
228- baseReconciler := reconcilers .NewBaseReconciler (ctx , cl , s , clientAPIReader , log , clientset .Discovery (), recorder )
229- baseAPIManagerLogicReconciler := NewBaseAPIManagerLogicReconciler (baseReconciler , tc .apimanager )
133+ baseAPIManagerLogicReconciler , cl := setupTestBaseReconciler (s , tc .apimanager , objs )
230134
231135 reconciler := NewSystemReconciler (baseAPIManagerLogicReconciler )
232136 _ , err = reconciler .Reconcile ()
@@ -271,6 +175,86 @@ func TestReplicaSystemReconciler(t *testing.T) {
271175 }
272176}
273177
178+ func TestSystemReconcilerUpdate (t * testing.T ) {
179+ apimanager := basicApimanagerSpecTestSystemOptions ()
180+ appPreHookJob := createAppPreHookJob (namespace )
181+
182+ s := scheme .Scheme
183+
184+ err := appsv1alpha1 .AddToScheme (s )
185+ if err != nil {
186+ t .Fatal (err )
187+ }
188+ err = k8sappsv1 .AddToScheme (s )
189+ if err != nil {
190+ t .Fatal (err )
191+ }
192+
193+ systemDatabaseSecret := createSystemDBSecret (apimanager .Namespace )
194+ systemRedisSecret := createSystemRedisSecret (apimanager .Namespace )
195+ objs := []runtime.Object {apimanager , appPreHookJob , systemDatabaseSecret , systemRedisSecret }
196+
197+ baseAPIManagerLogicReconciler , cl := setupTestBaseReconciler (s , apimanager , objs )
198+ reconciler := NewSystemReconciler (baseAPIManagerLogicReconciler )
199+
200+ system , err := System (reconciler .apiManager , reconciler .Client ())
201+ if err != nil {
202+ t .Fatal (err )
203+ }
204+
205+ oldImage := "old-system-image:v1"
206+ oldArgs := []string {"foo" , "bar" }
207+
208+ oldDeployment , err := system .AppDeployment (context .Background (), cl , oldImage )
209+ if err != nil {
210+ t .Fatal (err )
211+ }
212+
213+ oldDeployment .Spec .Template .Spec .Containers [0 ].Args = oldArgs
214+
215+ // Create an system-app Deployment with old image and args
216+ err = cl .Create (context .TODO (), oldDeployment )
217+ if err != nil {
218+ t .Errorf ("error creating deployment of %s: %v" , "system-app" , err )
219+ }
220+
221+ _ , err = reconciler .Reconcile ()
222+ if err != nil {
223+ t .Fatal (err )
224+ }
225+
226+ reconciledDeployment := & k8sappsv1.Deployment {}
227+ namespacedName := types.NamespacedName {
228+ Name : "system-app" ,
229+ Namespace : namespace ,
230+ }
231+
232+ err = cl .Get (context .TODO (), namespacedName , reconciledDeployment )
233+ if err != nil {
234+ t .Errorf ("error fetching object %s: %v" , "system-app" , err )
235+ }
236+
237+ expectedDeployment , err := system .AppDeployment (context .Background (), cl , SystemImageURL ())
238+ if err != nil {
239+ t .Fatal (err )
240+ }
241+
242+ // Verify image was updated
243+ actualImage := reconciledDeployment .Spec .Template .Spec .Containers [0 ].Image
244+ expectedImage := expectedDeployment .Spec .Template .Spec .Containers [0 ].Image
245+ if actualImage != expectedImage {
246+ t .Errorf ("image was not updated: expected %s, got %s" , expectedImage , actualImage )
247+ }
248+
249+ // Verify args were updated
250+ actualArgs := reconciledDeployment .Spec .Template .Spec .Containers [0 ].Args
251+ expectedArgs := expectedDeployment .Spec .Template .Spec .Containers [0 ].Args
252+ if ! reflect .DeepEqual (actualArgs , expectedArgs ) {
253+ t .Errorf ("args were not updated:\n expected: %v\n got: %v\n diff: %s" ,
254+ expectedArgs , actualArgs , cmp .Diff (expectedArgs , actualArgs ))
255+ }
256+ }
257+
274258func testSystemAPIManagerCreator (appReplicas , sidekiqReplicas * int64 ) * appsv1alpha1.APIManager {
275259 var (
276260 name = "example-apimanager"
@@ -329,3 +313,28 @@ func createSystemDBSecret(namespace string) *v1.Secret {
329313 Data : map [string ][]byte {},
330314 }
331315}
316+
317+ func createAppPreHookJob (namespace string ) * batchv1.Job {
318+ return & batchv1.Job {
319+ ObjectMeta : metav1.ObjectMeta {Name : component .SystemAppPreHookJobName , Namespace : namespace },
320+ Spec : batchv1.JobSpec {
321+ Template : v1.PodTemplateSpec {
322+ Spec : v1.PodSpec {
323+ Containers : []v1.Container {
324+ {
325+ Image : SystemImageURL (),
326+ },
327+ },
328+ },
329+ },
330+ },
331+ Status : batchv1.JobStatus {
332+ Conditions : []batchv1.JobCondition {
333+ {
334+ Type : batchv1 .JobComplete ,
335+ Status : v1 .ConditionTrue ,
336+ },
337+ },
338+ },
339+ }
340+ }
0 commit comments