@@ -18,8 +18,10 @@ package controller
1818
1919import (
2020 "testing"
21+ "time"
2122
2223 . "github.com/onsi/gomega"
24+ appsv1 "k8s.io/api/apps/v1"
2325 corev1 "k8s.io/api/core/v1"
2426 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2527 "k8s.io/apimachinery/pkg/runtime"
@@ -39,7 +41,7 @@ apiVersion: clusterctl.cluster.x-k8s.io/v1alpha3
3941releaseSeries:
4042 - major: 0
4143 minor: 4
42- contract: v1alpha4
44+ contract: v1beta1
4345`
4446 testComponents = `
4547apiVersion: apps/v1
@@ -215,22 +217,47 @@ func TestReconcilerPreflightConditions(t *testing.T) {
215217 }
216218}
217219
218- func TestUpgradeDowngradeProvider (t * testing.T ) {
220+ func TestAirGappedUpgradeDowngradeProvider (t * testing.T ) {
221+ currentVersion := "v999.9.2"
222+ futureMetadata := `
223+ apiVersion: clusterctl.cluster.x-k8s.io/v1alpha3
224+ releaseSeries:
225+ - major: 999
226+ minor: 9
227+ contract: v1beta1
228+ `
229+
230+ dummyFutureConfigMap := func (ns , name string ) * corev1.ConfigMap {
231+ return & corev1.ConfigMap {
232+ ObjectMeta : metav1.ObjectMeta {
233+ Name : name ,
234+ Namespace : ns ,
235+ Labels : map [string ]string {
236+ "test" : "dummy-config" ,
237+ },
238+ },
239+ Data : map [string ]string {
240+ "metadata" : futureMetadata ,
241+ "components" : testComponents ,
242+ },
243+ }
244+ }
245+
219246 testCases := []struct {
220247 name string
221248 newVersion string
222249 }{
223250 {
224251 name : "same provider version" ,
225- newVersion : "v0.4 .2" ,
252+ newVersion : "v999.9 .2" ,
226253 },
227254 {
228255 name : "upgrade provider version" ,
229- newVersion : "v0.4 .3" ,
256+ newVersion : "v999.9 .3" ,
230257 },
231258 {
232259 name : "downgrade provider version" ,
233- newVersion : "v0.4 .1" ,
260+ newVersion : "v999.9 .1" ,
234261 },
235262 }
236263
@@ -244,7 +271,7 @@ func TestUpgradeDowngradeProvider(t *testing.T) {
244271 },
245272 Spec : operatorv1.CoreProviderSpec {
246273 ProviderSpec : operatorv1.ProviderSpec {
247- Version : testCurrentVersion ,
274+ Version : currentVersion ,
248275 },
249276 },
250277 }
@@ -254,7 +281,7 @@ func TestUpgradeDowngradeProvider(t *testing.T) {
254281 t .Log ("Ensure namespace exists" , namespace )
255282 g .Expect (env .EnsureNamespaceExists (ctx , namespace )).To (Succeed ())
256283
257- g .Expect (env .CreateAndWait (ctx , dummyConfigMap (namespace , testCurrentVersion ))).To (Succeed ())
284+ g .Expect (env .CreateAndWait (ctx , dummyFutureConfigMap (namespace , currentVersion ))).To (Succeed ())
258285
259286 insertDummyConfig (provider )
260287 provider .SetNamespace (namespace )
@@ -266,7 +293,7 @@ func TestUpgradeDowngradeProvider(t *testing.T) {
266293 return false
267294 }
268295
269- if provider .GetStatus ().InstalledVersion == nil || * provider .GetStatus ().InstalledVersion != testCurrentVersion {
296+ if provider .GetStatus ().InstalledVersion == nil || * provider .GetStatus ().InstalledVersion != currentVersion {
270297 return false
271298 }
272299
@@ -283,13 +310,16 @@ func TestUpgradeDowngradeProvider(t *testing.T) {
283310 }, timeout ).Should (BeEquivalentTo (true ))
284311
285312 // creating another configmap with another version
286- if tc .newVersion != testCurrentVersion {
287- g .Expect (env .CreateAndWait (ctx , dummyConfigMap (namespace , tc .newVersion ))).To (Succeed ())
313+ if tc .newVersion != currentVersion {
314+ g .Expect (env .CreateAndWait (ctx , dummyFutureConfigMap (namespace , tc .newVersion ))).To (Succeed ())
288315 }
289316
290317 // Change provider version
291318 providerSpec := provider .GetSpec ()
292319 providerSpec .Version = tc .newVersion
320+ providerSpec .Deployment = & operatorv1.DeploymentSpec {
321+ Replicas : pointer .Int (2 ),
322+ }
293323 provider .SetSpec (providerSpec )
294324
295325 // Set label (needed to start a reconciliation of the provider)
@@ -315,23 +345,68 @@ func TestUpgradeDowngradeProvider(t *testing.T) {
315345 return false
316346 }
317347
348+ allFound := false
318349 for _ , cond := range provider .GetStatus ().Conditions {
319350 if cond .Type == operatorv1 .PreflightCheckCondition {
320351 t .Log (t .Name (), provider .GetName (), cond )
321352 if cond .Status == corev1 .ConditionTrue {
322- return true
353+ allFound = true
354+ break
323355 }
324356 }
325357 }
326358
327- return false
359+ if ! allFound {
360+ return false
361+ }
362+
363+ allFound = tc .newVersion == currentVersion
364+ for _ , cond := range provider .GetStatus ().Conditions {
365+ if cond .Type == operatorv1 .ProviderUpgradedCondition {
366+ t .Log (t .Name (), provider .GetName (), cond )
367+ if cond .Status == corev1 .ConditionTrue {
368+ allFound = tc .newVersion != currentVersion
369+ break
370+ }
371+ }
372+ }
373+
374+ if ! allFound {
375+ return false
376+ }
377+
378+ // Ensure customization occurred
379+ dep := & appsv1.Deployment {ObjectMeta : metav1.ObjectMeta {
380+ Namespace : provider .Namespace ,
381+ Name : "capd-controller-manager" ,
382+ }}
383+ if err := env .Get (ctx , client .ObjectKeyFromObject (dep ), dep ); err != nil {
384+ return false
385+ }
386+
387+ return dep .Spec .Replicas != nil && * dep .Spec .Replicas == 2
328388 }, timeout ).Should (BeEquivalentTo (true ))
329389
390+ g .Consistently (func () bool {
391+ allSet := tc .newVersion == currentVersion
392+ for _ , cond := range provider .GetStatus ().Conditions {
393+ if cond .Type == operatorv1 .ProviderUpgradedCondition {
394+ t .Log (t .Name (), provider .GetName (), cond )
395+ if cond .Status == corev1 .ConditionTrue {
396+ allSet = tc .newVersion != currentVersion
397+ break
398+ }
399+ }
400+ }
401+
402+ return allSet
403+ }, 2 * time .Second ).Should (BeTrue ())
404+
330405 // Clean up
331406 objs := []client.Object {provider }
332407 objs = append (objs , & corev1.ConfigMap {
333408 ObjectMeta : metav1.ObjectMeta {
334- Name : testCurrentVersion ,
409+ Name : currentVersion ,
335410 Namespace : namespace ,
336411 },
337412 })
0 commit comments