...

Source file src/github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/preflight/upgrade_test.go

Documentation: github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/preflight

     1  // Copyright 2022 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package preflight
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"log"
    21  	"testing"
    22  
    23  	"github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/manifest"
    24  	"github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/test/util/asserts"
    25  	corev1 "k8s.io/api/core/v1"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/client-go/kubernetes/scheme"
    28  	"k8s.io/client-go/rest"
    29  	"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/loaders"
    30  	"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative"
    31  	"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/test/mocks"
    32  
    33  	corev1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/apis/core/v1beta1"
    34  	"github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/k8s"
    35  )
    36  
    37  var (
    38  	cfg *rest.Config
    39  )
    40  
    41  func init() {
    42  	s := scheme.Scheme
    43  	if err := corev1beta1.SchemeBuilder.AddToScheme(s); err != nil {
    44  		log.Fatalf("error registering core kcc operator scheme: %v", err)
    45  	}
    46  }
    47  
    48  type FakeRepo struct {
    49  	channel *loaders.Channel
    50  }
    51  
    52  var _ manifest.Repository = &FakeRepo{}
    53  
    54  func (r *FakeRepo) LoadManifest(ctx context.Context, component string, id string, o declarative.DeclarativeObject) (map[string]string, error) {
    55  	panic("implement me")
    56  }
    57  
    58  func (r *FakeRepo) LoadChannel(ctx context.Context, name string) (*loaders.Channel, error) {
    59  	return r.channel, nil
    60  }
    61  
    62  func (r *FakeRepo) LoadNamespacedComponents(ctx context.Context, componentName string, version string) (map[string]string, error) {
    63  	panic("implement me")
    64  }
    65  
    66  func TestUpgradeChecker_Preflight(t *testing.T) {
    67  	t.Parallel()
    68  	curTime := metav1.Now()
    69  	testConfigConnector := &corev1beta1.ConfigConnector{
    70  		ObjectMeta: metav1.ObjectMeta{
    71  			Name: "test-configconnector",
    72  		},
    73  		Spec: corev1beta1.ConfigConnectorSpec{
    74  			GoogleServiceAccount: "foo@bar.iam.gserviceaccount.com",
    75  		},
    76  	}
    77  	tests := []struct {
    78  		name    string
    79  		cc      *corev1beta1.ConfigConnector
    80  		ns      *corev1.Namespace
    81  		channel *loaders.Channel
    82  		err     error
    83  		delete  bool
    84  	}{
    85  		{
    86  			name:    "no existing instance, can upgrade/deploy the new version",
    87  			cc:      testConfigConnector,
    88  			channel: nil,
    89  			ns:      nil,
    90  			err:     nil,
    91  		},
    92  		{
    93  			name: "new version is compatible, can upgrade it",
    94  			cc:   testConfigConnector,
    95  			ns: &corev1.Namespace{
    96  				ObjectMeta: metav1.ObjectMeta{
    97  					Name: k8s.CNRMSystemNamespace,
    98  					Annotations: map[string]string{
    99  						k8s.VersionAnnotation: "1.2.3",
   100  					},
   101  				},
   102  			},
   103  			channel: &loaders.Channel{
   104  				Manifests: []loaders.Version{
   105  					{
   106  						Package: "configconnector",
   107  						Version: "1.4.0",
   108  					},
   109  				},
   110  			},
   111  			err: nil,
   112  		},
   113  		{
   114  			name: "reconcile on the same version",
   115  			cc:   testConfigConnector,
   116  			ns: &corev1.Namespace{
   117  				ObjectMeta: metav1.ObjectMeta{
   118  					Name: k8s.CNRMSystemNamespace,
   119  					Annotations: map[string]string{
   120  						k8s.VersionAnnotation: "1.2.3",
   121  					},
   122  				},
   123  			},
   124  			channel: &loaders.Channel{
   125  				Manifests: []loaders.Version{
   126  					{
   127  						Package: "configconnector",
   128  						Version: "1.2.3",
   129  					},
   130  				},
   131  			},
   132  			err: nil,
   133  		},
   134  		{
   135  			name: "major change, no upgrade",
   136  			cc:   testConfigConnector,
   137  			ns: &corev1.Namespace{
   138  				ObjectMeta: metav1.ObjectMeta{
   139  					Name: k8s.CNRMSystemNamespace,
   140  					Annotations: map[string]string{
   141  						k8s.VersionAnnotation: "1.2.3",
   142  					},
   143  				},
   144  			},
   145  			channel: &loaders.Channel{
   146  				Manifests: []loaders.Version{
   147  					{
   148  						Package: "configconnector",
   149  						Version: "2.0.0",
   150  					},
   151  				},
   152  			},
   153  			err: fmt.Errorf("incompatible version"),
   154  		},
   155  		{
   156  			name: "major change, no downgrade",
   157  			cc:   testConfigConnector,
   158  			ns: &corev1.Namespace{
   159  				ObjectMeta: metav1.ObjectMeta{
   160  					Name: k8s.CNRMSystemNamespace,
   161  					Annotations: map[string]string{
   162  						k8s.VersionAnnotation: "2.0.0",
   163  					},
   164  				},
   165  			},
   166  			channel: &loaders.Channel{
   167  				Manifests: []loaders.Version{
   168  					{
   169  						Package: "configconnector",
   170  						Version: "1.2.0",
   171  					},
   172  				},
   173  			},
   174  			err: fmt.Errorf("incompatible version"),
   175  		},
   176  		{
   177  			name: "delete will always pass preflight check",
   178  			cc: &corev1beta1.ConfigConnector{
   179  				ObjectMeta: metav1.ObjectMeta{
   180  					Name:              "test-configconnector",
   181  					DeletionTimestamp: &curTime,
   182  				},
   183  				Spec: corev1beta1.ConfigConnectorSpec{
   184  					GoogleServiceAccount: "foo@bar.iam.gserviceaccount.com",
   185  				},
   186  			},
   187  			ns: &corev1.Namespace{
   188  				ObjectMeta: metav1.ObjectMeta{
   189  					Name: k8s.CNRMSystemNamespace,
   190  					Annotations: map[string]string{
   191  						k8s.VersionAnnotation: "1.2.3",
   192  					},
   193  				},
   194  			},
   195  			channel: &loaders.Channel{
   196  				Manifests: []loaders.Version{
   197  					{
   198  						Package: "configconnector",
   199  						Version: "2.0.0",
   200  					},
   201  				},
   202  			},
   203  			err: nil,
   204  		},
   205  	}
   206  
   207  	for _, tc := range tests {
   208  		tc := tc
   209  		t.Run(tc.name, func(t *testing.T) {
   210  			t.Parallel()
   211  			mgr := mocks.Manager{}
   212  			ctx := context.Background()
   213  			client := mgr.GetClient()
   214  			if err := client.Create(ctx, tc.cc); err != nil {
   215  				t.Fatalf("error creating %v %v: %v", tc.cc.Kind, tc.cc.Name, err)
   216  			}
   217  			if tc.ns != nil {
   218  				if err := client.Create(ctx, tc.ns); err != nil {
   219  					t.Fatalf("error creating %v %v: %v", tc.ns.Kind, tc.cc.Name, err)
   220  				}
   221  			}
   222  			repo := FakeRepo{
   223  				channel: tc.channel,
   224  			}
   225  			u := NewUpgradeChecker(client, &repo)
   226  			err := u.Preflight(ctx, tc.cc)
   227  			asserts.AssertErrorIsExpected(t, err, tc.err)
   228  		})
   229  	}
   230  }
   231  

View as plain text