github.com/verrazzano/verrazzano@v1.7.0/application-operator/controllers/clusters/multiclusterconfigmap/controller_test.go (about)

     1  // Copyright (c) 2021, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package multiclusterconfigmap
     5  
     6  import (
     7  	"context"
     8  	"encoding/json"
     9  	"path/filepath"
    10  	"testing"
    11  
    12  	"github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
    13  	"github.com/go-logr/logr"
    14  	"github.com/verrazzano/verrazzano/application-operator/constants"
    15  	vzconst "github.com/verrazzano/verrazzano/pkg/constants"
    16  
    17  	"github.com/golang/mock/gomock"
    18  	asserts "github.com/stretchr/testify/assert"
    19  	clustersv1alpha1 "github.com/verrazzano/verrazzano/application-operator/apis/clusters/v1alpha1"
    20  	"github.com/verrazzano/verrazzano/application-operator/controllers/clusters"
    21  	clusterstest "github.com/verrazzano/verrazzano/application-operator/controllers/clusters/test"
    22  	"github.com/verrazzano/verrazzano/application-operator/mocks"
    23  	"go.uber.org/zap"
    24  	v1 "k8s.io/api/core/v1"
    25  	"k8s.io/apimachinery/pkg/api/errors"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/runtime"
    28  	"k8s.io/apimachinery/pkg/runtime/schema"
    29  	"k8s.io/apimachinery/pkg/types"
    30  	"sigs.k8s.io/controller-runtime/pkg/client"
    31  )
    32  
    33  const namespace = "unit-mccm-namespace"
    34  const crName = "unit-mccm"
    35  const sampleMCConfigMapFile = "testdata/sample-mcconfigmap.yaml"
    36  
    37  // TestConfigMapReconcilerSetupWithManager test the creation of the MultiClusterConfigMapReconciler.
    38  // GIVEN a controller implementation
    39  // WHEN the controller is created
    40  // THEN verify no error is returned
    41  func TestConfigMapReconcilerSetupWithManager(t *testing.T) {
    42  	assert := asserts.New(t)
    43  
    44  	var mocker *gomock.Controller
    45  	var mgr *mocks.MockManager
    46  	var cli *mocks.MockClient
    47  	var scheme *runtime.Scheme
    48  	var reconciler Reconciler
    49  	var err error
    50  
    51  	mocker = gomock.NewController(t)
    52  	mgr = mocks.NewMockManager(mocker)
    53  	cli = mocks.NewMockClient(mocker)
    54  	scheme = runtime.NewScheme()
    55  	_ = clustersv1alpha1.AddToScheme(scheme)
    56  	reconciler = Reconciler{Client: cli, Scheme: scheme}
    57  	mgr.EXPECT().GetControllerOptions().AnyTimes()
    58  	mgr.EXPECT().GetScheme().Return(scheme)
    59  	mgr.EXPECT().GetLogger().Return(logr.Discard())
    60  	mgr.EXPECT().SetFields(gomock.Any()).Return(nil).AnyTimes()
    61  	mgr.EXPECT().Add(gomock.Any()).Return(nil).AnyTimes()
    62  	err = reconciler.SetupWithManager(mgr)
    63  	mocker.Finish()
    64  	assert.NoError(err)
    65  }
    66  
    67  // TestReconcileCreateConfigMap tests the basic happy path of reconciling a MultiClusterConfigMap. We
    68  // expect to write out a K8S ConfigMap
    69  // GIVEN a MultiClusterConfigMap resource is created
    70  // WHEN the controller Reconcile function is called
    71  // THEN expect a K8S ConfigMap to be created
    72  func TestReconcileCreateConfigMap(t *testing.T) {
    73  	assert := asserts.New(t)
    74  
    75  	mocker := gomock.NewController(t)
    76  	cli := mocks.NewMockClient(mocker)
    77  	mockStatusWriter := mocks.NewMockStatusWriter(mocker)
    78  
    79  	mcConfigMap, err := getMCConfigMap(sampleMCConfigMapFile)
    80  
    81  	if err != nil {
    82  		t.Fatalf(err.Error())
    83  	}
    84  
    85  	// expect a call to fetch the MultiClusterConfigMap
    86  	doExpectGetMultiClusterConfigMap(cli, mcConfigMap, false)
    87  
    88  	// expect a call to fetch the MCRegistration secret
    89  	clusterstest.DoExpectGetMCRegistrationSecret(cli)
    90  
    91  	// expect a call to fetch existing K8S ConfigMap, and return not found error, to test create case
    92  	cli.EXPECT().
    93  		Get(gomock.Any(), types.NamespacedName{Namespace: namespace, Name: crName}, gomock.Not(gomock.Nil()), gomock.Any()).
    94  		Return(errors.NewNotFound(schema.GroupResource{Group: "", Resource: "ConfigMap"}, crName))
    95  
    96  	// expect a call to create the K8S ConfigMap
    97  	cli.EXPECT().
    98  		Create(gomock.Any(), gomock.Any(), gomock.Any()).
    99  		DoAndReturn(func(ctx context.Context, c *v1.ConfigMap, opts ...client.CreateOption) error {
   100  			assertConfigMapValid(assert, c, mcConfigMap)
   101  			return nil
   102  		})
   103  
   104  	// expect a call to update the resource with a finalizer
   105  	cli.EXPECT().
   106  		Update(gomock.Any(), gomock.Any(), gomock.Any()).
   107  		DoAndReturn(func(ctx context.Context, configMap *clustersv1alpha1.MultiClusterConfigMap, opts ...client.UpdateOption) error {
   108  			assert.True(len(configMap.ObjectMeta.Finalizers) == 1, "Wrong number of finalizers")
   109  			assert.Equal(finalizerName, configMap.ObjectMeta.Finalizers[0], "wrong finalizer")
   110  			return nil
   111  		})
   112  
   113  	// expect a call to update the status of the MultiClusterConfigMap
   114  	doExpectStatusUpdateSucceeded(cli, mockStatusWriter, assert)
   115  
   116  	// create a request and reconcile it
   117  	request := clusterstest.NewRequest(namespace, crName)
   118  	reconciler := newReconciler(cli)
   119  	result, err := reconciler.Reconcile(context.TODO(), request)
   120  
   121  	mocker.Finish()
   122  	assert.NoError(err)
   123  	assert.Equal(false, result.Requeue)
   124  }
   125  
   126  // TestReconcileUpdateConfigMap tests the path of reconciling a MultiClusterConfigMap when the
   127  // underlying K8S ConfigMap already exists i.e. update case
   128  // GIVEN a MultiClusterConfigMap resource is created
   129  // WHEN the controller Reconcile function is called
   130  // THEN expect a K8S ConfigMap to be updated
   131  func TestReconcileUpdateConfigMap(t *testing.T) {
   132  	assert := asserts.New(t)
   133  
   134  	mocker := gomock.NewController(t)
   135  	cli := mocks.NewMockClient(mocker)
   136  	mockStatusWriter := mocks.NewMockStatusWriter(mocker)
   137  
   138  	mcConfigMap, err := getMCConfigMap(sampleMCConfigMapFile)
   139  	if err != nil {
   140  		t.Fatalf(err.Error())
   141  	}
   142  
   143  	// expect a call to fetch the MultiClusterConfigMap
   144  	doExpectGetMultiClusterConfigMap(cli, mcConfigMap, true)
   145  
   146  	// expect a call to fetch the MCRegistration secret
   147  	clusterstest.DoExpectGetMCRegistrationSecret(cli)
   148  
   149  	// expect a call to fetch underlying K8S ConfigMap, and return an existing ConfigMap
   150  	doExpectGetConfigMapExists(cli, mcConfigMap.ObjectMeta)
   151  
   152  	// expect a call to update the K8S ConfigMap with the new ConfigMap data
   153  	cli.EXPECT().
   154  		Update(gomock.Any(), gomock.Any(), gomock.Any()).
   155  		DoAndReturn(func(ctx context.Context, c *v1.ConfigMap, opts ...client.UpdateOption) error {
   156  			assertConfigMapValid(assert, c, mcConfigMap)
   157  			return nil
   158  		})
   159  
   160  	// expect a call to update the status of the multicluster ConfigMap\
   161  	doExpectStatusUpdateSucceeded(cli, mockStatusWriter, assert)
   162  
   163  	// create a request and reconcile it
   164  	request := clusterstest.NewRequest(namespace, crName)
   165  	reconciler := newReconciler(cli)
   166  	result, err := reconciler.Reconcile(context.TODO(), request)
   167  
   168  	mocker.Finish()
   169  	assert.NoError(err)
   170  	assert.Equal(false, result.Requeue)
   171  }
   172  
   173  // TestReconcileCreateConfigMapFailed tests the path of reconciling a MultiClusterConfigMap
   174  // when the underlying K8S ConfigMap does not exist and fails to be created due to some error condition
   175  // GIVEN a MultiClusterConfigMap resource is created
   176  // WHEN the controller Reconcile function is called and create underlying ConfigMap fails
   177  // THEN expect the status of the MultiClusterConfigMap to be updated with failure information
   178  func TestReconcileCreateConfigMapFailed(t *testing.T) {
   179  	assert := asserts.New(t)
   180  
   181  	mocker := gomock.NewController(t)
   182  	cli := mocks.NewMockClient(mocker)
   183  	mockStatusWriter := mocks.NewMockStatusWriter(mocker)
   184  
   185  	mcConfigMap, err := getMCConfigMap(sampleMCConfigMapFile)
   186  	if err != nil {
   187  		t.Fatalf(err.Error())
   188  	}
   189  
   190  	// expect a call to fetch the MultiClusterConfigMap
   191  	doExpectGetMultiClusterConfigMap(cli, mcConfigMap, false)
   192  
   193  	// expect a call to fetch the MCRegistration secret
   194  	clusterstest.DoExpectGetMCRegistrationSecret(cli)
   195  
   196  	// expect a call to fetch existing K8S ConfigMap and return not found error, to simulate create case
   197  	cli.EXPECT().
   198  		Get(gomock.Any(), types.NamespacedName{Namespace: namespace, Name: crName}, gomock.Not(gomock.Nil()), gomock.Any()).
   199  		Return(errors.NewNotFound(schema.GroupResource{Group: "", Resource: "ConfigMap"}, crName))
   200  
   201  	// expect a call to create the K8S ConfigMap and fail the call
   202  	cli.EXPECT().
   203  		Create(gomock.Any(), gomock.Any(), gomock.Any()).
   204  		DoAndReturn(func(ctx context.Context, c *v1.ConfigMap, opts ...client.CreateOption) error {
   205  			return errors.NewBadRequest("will not create it")
   206  		})
   207  
   208  	// expect that the status of MultiClusterConfigMap is updated to failed because we
   209  	// failed the underlying K8S ConfigMap's creation
   210  	doExpectStatusUpdateFailed(cli, mockStatusWriter, assert)
   211  
   212  	// create a request and reconcile it
   213  	request := clusterstest.NewRequest(namespace, crName)
   214  	reconciler := newReconciler(cli)
   215  	result, err := reconciler.Reconcile(context.TODO(), request)
   216  
   217  	mocker.Finish()
   218  	assert.Nil(err)
   219  	assert.Equal(true, result.Requeue)
   220  }
   221  
   222  // TestReconcileCreateConfigMapFailed tests the path of reconciling a MultiClusterConfigMap
   223  // when the underlying K8S ConfigMap exists and fails to be updated due to some error condition
   224  // GIVEN a MultiClusterConfigMap resource is created
   225  // WHEN the controller Reconcile function is called and update underlying ConfigMap fails
   226  // THEN expect the status of the MultiClusterConfigMap to be updated with failure information
   227  func TestReconcileUpdateConfigMapFailed(t *testing.T) {
   228  	assert := asserts.New(t)
   229  
   230  	mocker := gomock.NewController(t)
   231  	cli := mocks.NewMockClient(mocker)
   232  	mockStatusWriter := mocks.NewMockStatusWriter(mocker)
   233  
   234  	mcConfigMap, err := getMCConfigMap(sampleMCConfigMapFile)
   235  	if err != nil {
   236  		t.Fatalf(err.Error())
   237  	}
   238  
   239  	// expect a call to fetch the MultiClusterConfigMap
   240  	doExpectGetMultiClusterConfigMap(cli, mcConfigMap, true)
   241  
   242  	// expect a call to fetch the MCRegistration secret
   243  	clusterstest.DoExpectGetMCRegistrationSecret(cli)
   244  
   245  	// expect a call to fetch existing K8S ConfigMap (simulate update case)
   246  	doExpectGetConfigMapExists(cli, mcConfigMap.ObjectMeta)
   247  
   248  	// expect a call to update the K8S ConfigMap and fail the call
   249  	cli.EXPECT().
   250  		Update(gomock.Any(), gomock.Any(), gomock.Any()).
   251  		DoAndReturn(func(ctx context.Context, c *v1.ConfigMap, opts ...client.UpdateOption) error {
   252  			return errors.NewBadRequest("will not update it")
   253  		})
   254  
   255  	// expect that the status of MultiClusterConfigMap is updated to failed because we
   256  	// failed the underlying K8S ConfigMap's creation
   257  	doExpectStatusUpdateFailed(cli, mockStatusWriter, assert)
   258  
   259  	// create a request and reconcile it
   260  	request := clusterstest.NewRequest(namespace, crName)
   261  	reconciler := newReconciler(cli)
   262  	result, err := reconciler.Reconcile(context.TODO(), request)
   263  
   264  	mocker.Finish()
   265  	assert.Nil(err)
   266  	assert.Equal(true, result.Requeue)
   267  }
   268  
   269  // TestReconcilePlacementInDifferentCluster tests the path of reconciling a MultiClusterConfigMap which
   270  // is placed on a cluster other than the current cluster. We expect this MultiClusterConfigMap to
   271  // be ignored, and no K8S ConfigMap to be created
   272  // GIVEN a MultiClusterConfigMap resource is created with a placement in different cluster
   273  // WHEN the controller Reconcile function is called
   274  // THEN expect that no K8S ConfigMap is created
   275  func TestReconcilePlacementInDifferentCluster(t *testing.T) {
   276  	assert := asserts.New(t)
   277  
   278  	mocker := gomock.NewController(t)
   279  	cli := mocks.NewMockClient(mocker)
   280  	statusWriter := mocks.NewMockStatusWriter(mocker)
   281  
   282  	mcConfigMap, err := getMCConfigMap(sampleMCConfigMapFile)
   283  	if err != nil {
   284  		t.Fatalf(err.Error())
   285  	}
   286  
   287  	mcConfigMap.Spec.Placement.Clusters[0].Name = "not-my-cluster"
   288  
   289  	// expect a call to fetch the MultiClusterConfigMap
   290  	doExpectGetMultiClusterConfigMap(cli, mcConfigMap, true)
   291  
   292  	// expect a call to fetch the MCRegistration secret
   293  	clusterstest.DoExpectGetMCRegistrationSecret(cli)
   294  
   295  	// The effective state of the object will get updated even if it is note locally placed,
   296  	// since it would have changed
   297  	clusterstest.DoExpectUpdateState(t, cli, statusWriter, &mcConfigMap, clustersv1alpha1.Pending)
   298  
   299  	clusterstest.ExpectDeleteAssociatedResource(cli, &v1alpha2.Component{
   300  		ObjectMeta: metav1.ObjectMeta{
   301  			Name:      mcConfigMap.Name,
   302  			Namespace: mcConfigMap.Namespace,
   303  		},
   304  	}, types.NamespacedName{
   305  		Namespace: mcConfigMap.Namespace,
   306  		Name:      mcConfigMap.Name,
   307  	})
   308  
   309  	// expect a call to update the resource with no finalizers
   310  	cli.EXPECT().
   311  		Update(gomock.Any(), gomock.Any(), gomock.Any()).
   312  		DoAndReturn(func(ctx context.Context, mcConfigMap *clustersv1alpha1.MultiClusterConfigMap, opts ...client.UpdateOption) error {
   313  			assert.True(len(mcConfigMap.Finalizers) == 0, "Wrong number of finalizers")
   314  			return nil
   315  		})
   316  
   317  	// Expect no further action
   318  
   319  	// create a request and reconcile it
   320  	request := clusterstest.NewRequest(namespace, crName)
   321  	reconciler := newReconciler(cli)
   322  	result, err := reconciler.Reconcile(context.TODO(), request)
   323  
   324  	mocker.Finish()
   325  	assert.NoError(err)
   326  	assert.Equal(false, result.Requeue)
   327  }
   328  
   329  // TestReconcileResourceNotFound tests the path of reconciling a
   330  // MultiClusterConfigMap resource which is non-existent when reconcile is called,
   331  // possibly because it has been deleted.
   332  // GIVEN a MultiClusterConfigMap resource has been deleted
   333  // WHEN the controller Reconcile function is called
   334  // THEN expect that no action is taken
   335  func TestReconcileResourceNotFound(t *testing.T) {
   336  	assert := asserts.New(t)
   337  
   338  	mocker := gomock.NewController(t)
   339  	cli := mocks.NewMockClient(mocker)
   340  
   341  	// expect a call to fetch the MultiClusterConfigMap
   342  	// and return a not found error
   343  	cli.EXPECT().
   344  		Get(gomock.Any(), types.NamespacedName{Namespace: namespace, Name: crName}, gomock.Not(gomock.Nil()), gomock.Any()).
   345  		Return(errors.NewNotFound(schema.GroupResource{Group: clustersv1alpha1.SchemeGroupVersion.Group, Resource: clustersv1alpha1.MultiClusterConfigMapResource}, crName))
   346  
   347  	// expect no further action to be taken
   348  
   349  	// create a request and reconcile it
   350  	request := clusterstest.NewRequest(namespace, crName)
   351  	reconciler := newReconciler(cli)
   352  	result, err := reconciler.Reconcile(context.TODO(), request)
   353  
   354  	mocker.Finish()
   355  	assert.NoError(err)
   356  	assert.Equal(false, result.Requeue)
   357  }
   358  
   359  // doExpectGetConfigMapExists expects a call to get an K8S ConfigMap and return an "existing" one
   360  func doExpectGetConfigMapExists(cli *mocks.MockClient, metadata metav1.ObjectMeta) {
   361  	cli.EXPECT().
   362  		Get(gomock.Any(), types.NamespacedName{Namespace: namespace, Name: crName}, gomock.Not(gomock.Nil()), gomock.Any()).
   363  		DoAndReturn(func(ctx context.Context, name types.NamespacedName, configMap *v1.ConfigMap, opts ...client.GetOption) error {
   364  			existingCM, err := getExistingConfigMap()
   365  			if err == nil {
   366  				existingCM.DeepCopyInto(configMap)
   367  			}
   368  			return err
   369  		})
   370  }
   371  
   372  // doExpectStatusUpdateFailed expects a call to update status of MultiClusterConfigMap to failure
   373  func doExpectStatusUpdateFailed(cli *mocks.MockClient, mockStatusWriter *mocks.MockStatusWriter, assert *asserts.Assertions) {
   374  	// expect a call to fetch the MCRegistration secret to get the cluster name for status update
   375  	clusterstest.DoExpectGetMCRegistrationSecret(cli)
   376  
   377  	// expect a call to update the status of the MultiClusterConfigMap
   378  	cli.EXPECT().Status().Return(mockStatusWriter)
   379  
   380  	// the status update should be to failure status/conditions on the MultiClusterConfigMap
   381  	mockStatusWriter.EXPECT().
   382  		Update(gomock.Any(), gomock.AssignableToTypeOf(&clustersv1alpha1.MultiClusterConfigMap{}), gomock.Any()).
   383  		DoAndReturn(func(ctx context.Context, mcConfigMap *clustersv1alpha1.MultiClusterConfigMap, opts ...client.UpdateOption) error {
   384  			clusterstest.AssertMultiClusterResourceStatus(assert, mcConfigMap.Status, clustersv1alpha1.Failed, clustersv1alpha1.DeployFailed, v1.ConditionTrue)
   385  			return nil
   386  		})
   387  }
   388  
   389  // doExpectStatusUpdateSucceeded expects a call to update status of MultiClusterConfigMap to success
   390  func doExpectStatusUpdateSucceeded(cli *mocks.MockClient, mockStatusWriter *mocks.MockStatusWriter, assert *asserts.Assertions) {
   391  	// expect a call to fetch the MCRegistration secret to get the cluster name for status update
   392  	clusterstest.DoExpectGetMCRegistrationSecret(cli)
   393  
   394  	// expect a call to update the status of the MultiClusterConfigMap
   395  	cli.EXPECT().Status().Return(mockStatusWriter)
   396  
   397  	// the status update should be to success status/conditions on the MultiClusterConfigMap
   398  	mockStatusWriter.EXPECT().
   399  		Update(gomock.Any(), gomock.AssignableToTypeOf(&clustersv1alpha1.MultiClusterConfigMap{}), gomock.Any()).
   400  		DoAndReturn(func(ctx context.Context, mcConfigMap *clustersv1alpha1.MultiClusterConfigMap, opts ...client.UpdateOption) error {
   401  			clusterstest.AssertMultiClusterResourceStatus(assert, mcConfigMap.Status, clustersv1alpha1.Succeeded, clustersv1alpha1.DeployComplete, v1.ConditionTrue)
   402  			return nil
   403  		})
   404  }
   405  
   406  // doExpectGetMultiClusterConfigMap adds an expectation to the given MockClient to expect a Get
   407  // call for a MultiClusterConfigMap, and populate the multi cluster ConfigMap with given data
   408  func doExpectGetMultiClusterConfigMap(cli *mocks.MockClient, mcConfigMapSample clustersv1alpha1.MultiClusterConfigMap, addFinalizer bool) {
   409  	cli.EXPECT().
   410  		Get(gomock.Any(), types.NamespacedName{Namespace: namespace, Name: crName}, gomock.AssignableToTypeOf(&mcConfigMapSample), gomock.Any()).
   411  		DoAndReturn(func(ctx context.Context, name types.NamespacedName, mcConfigMap *clustersv1alpha1.MultiClusterConfigMap, opts ...client.GetOption) error {
   412  			mcConfigMap.ObjectMeta = mcConfigMapSample.ObjectMeta
   413  			mcConfigMap.TypeMeta = mcConfigMapSample.TypeMeta
   414  			mcConfigMap.Spec = mcConfigMapSample.Spec
   415  			if addFinalizer {
   416  				mcConfigMap.Finalizers = append(mcConfigMap.Finalizers, finalizerName)
   417  			}
   418  			return nil
   419  		})
   420  }
   421  
   422  // assertConfigMapValid asserts that the metadata and content of the created/updated K8S ConfigMap
   423  // are valid
   424  func assertConfigMapValid(assert *asserts.Assertions, cm *v1.ConfigMap, mcConfigMap clustersv1alpha1.MultiClusterConfigMap) {
   425  	assert.Equal(namespace, cm.ObjectMeta.Namespace)
   426  	assert.Equal(crName, cm.ObjectMeta.Name)
   427  	assert.Equal(mcConfigMap.Spec.Template.Data, cm.Data)
   428  	assert.Equal(mcConfigMap.Spec.Template.BinaryData, cm.BinaryData)
   429  	// assert that the configmap is labeled verrazzano-managed=true since it was created by Verrazzano
   430  	assert.NotNil(cm.Labels)
   431  	assert.Equal(constants.LabelVerrazzanoManagedDefault, cm.Labels[vzconst.VerrazzanoManagedLabelKey])
   432  }
   433  
   434  // getMCConfigMap creates and returns a sample MultiClusterConfigMap used in tests
   435  func getMCConfigMap(filename string) (clustersv1alpha1.MultiClusterConfigMap, error) {
   436  	mcConfigMap := clustersv1alpha1.MultiClusterConfigMap{}
   437  	sampleConfigMapFile, err := filepath.Abs(filename)
   438  	if err != nil {
   439  		return mcConfigMap, err
   440  	}
   441  
   442  	rawResource, err := clusterstest.ReadYaml2Json(sampleConfigMapFile)
   443  	if err != nil {
   444  		return mcConfigMap, err
   445  	}
   446  
   447  	err = json.Unmarshal(rawResource, &mcConfigMap)
   448  	return mcConfigMap, err
   449  }
   450  
   451  func getExistingConfigMap() (v1.ConfigMap, error) {
   452  	configMap := v1.ConfigMap{}
   453  	existingConfigMapFile, err := filepath.Abs("testdata/sample-configmap-existing.yaml")
   454  	if err != nil {
   455  		return configMap, err
   456  	}
   457  	rawResource, err := clusterstest.ReadYaml2Json(existingConfigMapFile)
   458  	if err != nil {
   459  		return configMap, err
   460  	}
   461  
   462  	err = json.Unmarshal(rawResource, &configMap)
   463  	return configMap, err
   464  }
   465  
   466  // newReconciler creates a new reconciler for testing
   467  // c - The K8s client to inject into the reconciler
   468  func newReconciler(c client.Client) Reconciler {
   469  	return Reconciler{
   470  		Client: c,
   471  		Log:    zap.S().With("test"),
   472  		Scheme: clusters.NewScheme(),
   473  	}
   474  }
   475  
   476  // TestReconcileKubeSystem tests to make sure we do not reconcile
   477  // Any resource that belong to the kube-system namespace
   478  func TestReconcileKubeSystem(t *testing.T) {
   479  	assert := asserts.New(t)
   480  
   481  	var mocker = gomock.NewController(t)
   482  	var cli = mocks.NewMockClient(mocker)
   483  
   484  	// create a request and reconcile it
   485  	request := clusterstest.NewRequest(vzconst.KubeSystem, "unit-test-verrazzano-helidon-workload")
   486  	reconciler := newReconciler(cli)
   487  	result, err := reconciler.Reconcile(context.TODO(), request)
   488  
   489  	mocker.Finish()
   490  	assert.Nil(err)
   491  	assert.True(result.IsZero())
   492  }