github.com/verrazzano/verrazzano@v1.7.1/cluster-operator/controllers/quickcreate/oke/oke_controller_test.go (about)

     1  // Copyright (c) 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 oke
     5  
     6  import (
     7  	"context"
     8  	_ "embed"
     9  	"github.com/stretchr/testify/assert"
    10  	vmcv1alpha1 "github.com/verrazzano/verrazzano/cluster-operator/apis/clusters/v1alpha1"
    11  	"github.com/verrazzano/verrazzano/cluster-operator/controllers/quickcreate/controller"
    12  	"github.com/verrazzano/verrazzano/cluster-operator/controllers/quickcreate/controller/oci"
    13  	ocifake "github.com/verrazzano/verrazzano/cluster-operator/controllers/quickcreate/controller/oci/fake"
    14  	corev1 "k8s.io/api/core/v1"
    15  	"k8s.io/apimachinery/pkg/runtime"
    16  	"k8s.io/apimachinery/pkg/types"
    17  	"sigs.k8s.io/cluster-api/api/v1beta1"
    18  	ctrl "sigs.k8s.io/controller-runtime"
    19  	clipkg "sigs.k8s.io/controller-runtime/pkg/client"
    20  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    21  	"sigs.k8s.io/yaml"
    22  	"testing"
    23  )
    24  
    25  const (
    26  	testNamespace = "test"
    27  	testName      = testNamespace
    28  )
    29  
    30  var (
    31  	scheme *runtime.Scheme
    32  	//go:embed testdata/base.yaml
    33  	testBase []byte
    34  	//go:embed testdata/completed-patch.yaml
    35  	testCompleted []byte
    36  	//go:embed testdata/existing-vcn-patch.yaml
    37  	testExistingVCN []byte
    38  	//go:embed testdata/new-vcn-native-patch.yaml
    39  	testNewVCN []byte
    40  	//go:embed testdata/existing-vcn-provisioning.yaml
    41  	testProvisioning []byte
    42  	testLoader       = &ocifake.CredentialsLoaderImpl{
    43  		Credentials: &oci.Credentials{},
    44  	}
    45  	testOCIClientGetter = func(_ *oci.Credentials) (oci.Client, error) {
    46  		return &ocifake.ClientImpl{
    47  			AvailabilityDomains: []oci.AvailabilityDomain{
    48  				{
    49  					Name: "x",
    50  					FaultDomains: []oci.FaultDomain{
    51  						{Name: "y"},
    52  					},
    53  				},
    54  			},
    55  		}, nil
    56  	}
    57  )
    58  
    59  func init() {
    60  	scheme = runtime.NewScheme()
    61  	_ = corev1.AddToScheme(scheme)
    62  	_ = vmcv1alpha1.AddToScheme(scheme)
    63  	_ = v1beta1.AddToScheme(scheme)
    64  }
    65  
    66  func TestReconcile(t *testing.T) {
    67  	existingVCNCR, err := testCreateCR(testExistingVCN)
    68  	assert.NoError(t, err)
    69  	completedCR, err := testCreateCR(testCompleted)
    70  	assert.NoError(t, err)
    71  	newVCNCR, err := testCreateCR(testNewVCN)
    72  	assert.NoError(t, err)
    73  	provisioningCR, err := testCreateCR(testProvisioning)
    74  	assert.NoError(t, err)
    75  
    76  	notFoundReconciler := testReconciler(fake.NewClientBuilder().WithScheme(scheme).Build())
    77  	existingVCNReconciler := testReconciler(fake.NewClientBuilder().WithScheme(scheme).WithObjects(existingVCNCR).Build())
    78  	completedReconciler := testReconciler(fake.NewClientBuilder().WithScheme(scheme).WithObjects(completedCR).Build())
    79  	newVCNReconciler := testReconciler(fake.NewClientBuilder().WithScheme(scheme).WithObjects(newVCNCR).Build())
    80  	provisioningReconciler := testReconciler(fake.NewClientBuilder().WithScheme(scheme).WithObjects(provisioningCR).Build())
    81  
    82  	var tests = []struct {
    83  		name        string
    84  		reconciler  *ClusterReconciler
    85  		assertsFunc func(t *testing.T)
    86  	}{
    87  		{
    88  			"no error when resource not found",
    89  			notFoundReconciler,
    90  			func(t *testing.T) {},
    91  		},
    92  		{
    93  			"create a cluster when using an existing VCN",
    94  			existingVCNReconciler,
    95  			func(t *testing.T) {
    96  				ctx := context.TODO()
    97  				assert.NoError(t, existingVCNReconciler.Client.Get(ctx, types.NamespacedName{
    98  					Namespace: testNamespace,
    99  					Name:      testName,
   100  				}, &v1beta1.Cluster{}))
   101  			},
   102  		},
   103  		{
   104  			"completed CRs are deleted",
   105  			completedReconciler,
   106  			func(t *testing.T) {
   107  				q, err := getTestCR(completedReconciler.Client)
   108  				assert.NoError(t, err)
   109  				assert.False(t, q.GetDeletionTimestamp().IsZero())
   110  			},
   111  		},
   112  		{
   113  			"create a cluster when creating a new VCN",
   114  			newVCNReconciler,
   115  			func(t *testing.T) {
   116  				ctx := context.TODO()
   117  				assert.NoError(t, newVCNReconciler.Client.Get(ctx, types.NamespacedName{
   118  					Namespace: testNamespace,
   119  					Name:      testName,
   120  				}, &v1beta1.Cluster{}))
   121  			},
   122  		},
   123  		{
   124  			"quick create moves to completed when reconciling provisioning",
   125  			provisioningReconciler,
   126  			func(t *testing.T) {
   127  				q, err := getTestCR(completedReconciler.Client)
   128  				assert.NoError(t, err)
   129  				assert.Equal(t, vmcv1alpha1.QuickCreatePhaseComplete, q.Status.Phase)
   130  			},
   131  		},
   132  	}
   133  
   134  	for _, tt := range tests {
   135  		t.Run(tt.name, func(t *testing.T) {
   136  			_, err := tt.reconciler.Reconcile(context.TODO(), ctrl.Request{
   137  				NamespacedName: types.NamespacedName{
   138  					Namespace: testNamespace,
   139  					Name:      testName,
   140  				},
   141  			})
   142  			assert.NoError(t, err)
   143  			tt.assertsFunc(t)
   144  		})
   145  	}
   146  }
   147  
   148  func testCreateCR(patch []byte) (*vmcv1alpha1.OKEQuickCreate, error) {
   149  	baseCR := &vmcv1alpha1.OKEQuickCreate{}
   150  	patchCR := &vmcv1alpha1.OKEQuickCreate{}
   151  	if err := yaml.Unmarshal(testBase, baseCR); err != nil {
   152  		return nil, err
   153  	}
   154  	if err := yaml.Unmarshal(patch, patchCR); err != nil {
   155  		return nil, err
   156  	}
   157  	baseCR.Spec = patchCR.Spec
   158  	baseCR.Status = patchCR.Status
   159  	return baseCR, nil
   160  }
   161  
   162  func testReconciler(cli clipkg.Client) *ClusterReconciler {
   163  	return &ClusterReconciler{
   164  		Base: &controller.Base{
   165  			Client: cli,
   166  		},
   167  		Scheme:            scheme,
   168  		CredentialsLoader: testLoader,
   169  		OCIClientGetter:   testOCIClientGetter,
   170  	}
   171  }
   172  
   173  func getTestCR(cli clipkg.Client) (*vmcv1alpha1.OKEQuickCreate, error) {
   174  	ctx := context.TODO()
   175  	q := &vmcv1alpha1.OKEQuickCreate{}
   176  	err := cli.Get(ctx, types.NamespacedName{
   177  		Namespace: testNamespace,
   178  		Name:      testName,
   179  	}, q)
   180  
   181  	return q, err
   182  }