github.com/verrazzano/verrazzano-monitoring-operator@v0.0.30/pkg/vmo/pvc_test.go (about) 1 // Copyright (C) 2020, 2022, 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 vmo 5 6 import ( 7 "testing" 8 9 "github.com/stretchr/testify/assert" 10 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/config" 11 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/constants" 12 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/resources" 13 corev1 "k8s.io/api/core/v1" 14 storagev1 "k8s.io/api/storage/v1" 15 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 16 ) 17 18 func TestNoPvcs(t *testing.T) { 19 threeAds := []string{"ad1", "ad2", "ad3"} 20 adCounter := NewAdPvcCounter(threeAds) 21 observedAd := adCounter.GetLeastUsedAd() 22 assert.Equal(t, true, resources.SliceContains(threeAds, observedAd), "With 3 unused ADs") 23 } 24 25 func TestNoADs(t *testing.T) { 26 var noAds []string 27 adCounter := NewAdPvcCounter(noAds) 28 observedAd := adCounter.GetLeastUsedAd() 29 assert.Equal(t, "", observedAd, "With no found ADs") 30 } 31 32 func TestNewThreeNodeES(t *testing.T) { 33 threeAds := []string{"ad1", "ad2", "ad3"} 34 adCounter := NewAdPvcCounter(threeAds) 35 first := adCounter.GetLeastUsedAd() 36 adCounter.Inc(first) 37 second := adCounter.GetLeastUsedAd() 38 adCounter.Inc(second) 39 third := adCounter.GetLeastUsedAd() 40 adCounter.Inc(third) 41 assert.Equal(t, true, resources.SliceContains(threeAds, first), "first") 42 assert.Equal(t, true, resources.SliceContains(threeAds, second), "first") 43 assert.Equal(t, true, resources.SliceContains(threeAds, third), "third") 44 assert.NotEqual(t, first, second) 45 assert.NotEqual(t, first, third) 46 assert.NotEqual(t, second, third) 47 } 48 49 func TestOnePvc(t *testing.T) { 50 threeAds := []string{"ad1", "ad2", "ad3"} 51 adCounter := NewAdPvcCounter(threeAds) 52 adCounter.Inc("ad1") 53 observedAd := adCounter.GetLeastUsedAd() 54 assert.Equal(t, true, resources.SliceContains(threeAds, observedAd), "With 2 unused ADs") 55 assert.NotEqual(t, "ad1", observedAd, "With one used AD") 56 } 57 58 func TestTwoPvcs(t *testing.T) { 59 threeAds := []string{"ad1", "ad2", "ad3"} 60 adCounter := NewAdPvcCounter(threeAds) 61 adCounter.Inc("ad1") 62 adCounter.Inc("ad2") 63 observedAd := adCounter.GetLeastUsedAd() 64 assert.Equal(t, true, resources.SliceContains(threeAds, observedAd), "With 1 unused AD") 65 assert.Equal(t, "ad3", observedAd, "With two used ADs") 66 } 67 68 func TestThreePvcs(t *testing.T) { 69 threeAds := []string{"ad1", "ad2", "ad3"} 70 adCounter := NewAdPvcCounter(threeAds) 71 adCounter.Inc("ad1") 72 adCounter.Inc("ad2") 73 adCounter.Inc("ad3") 74 observedAd := adCounter.GetLeastUsedAd() 75 assert.Equal(t, true, resources.SliceContains(threeAds, observedAd), "With 0 unused ADs") 76 } 77 78 func TestFourPvcs(t *testing.T) { 79 threeAds := []string{"ad1", "ad2", "ad3"} 80 adCounter := NewAdPvcCounter(threeAds) 81 adCounter.Inc("ad1") 82 adCounter.Inc("ad1") 83 adCounter.Inc("ad2") 84 adCounter.Inc("ad3") 85 observedAd := adCounter.GetLeastUsedAd() 86 assert.Equal(t, true, resources.SliceContains(threeAds, observedAd), "With 0 unused ADs") 87 assert.NotEqual(t, "ad1", observedAd, "With 3 used ADs") 88 } 89 90 func TestFivePvcs(t *testing.T) { 91 threeAds := []string{"ad1", "ad2", "ad3"} 92 adCounter := NewAdPvcCounter(threeAds) 93 adCounter.Inc("ad1") 94 adCounter.Inc("ad1") 95 adCounter.Inc("ad2") 96 adCounter.Inc("ad2") 97 adCounter.Inc("ad3") 98 observedAd := adCounter.GetLeastUsedAd() 99 assert.Equal(t, true, resources.SliceContains(threeAds, observedAd), "With 0 unused ADs") 100 assert.Equal(t, "ad3", observedAd, "With three used ADs") 101 } 102 103 func TestNonSchedulable(t *testing.T) { 104 twoAds := []string{"ad1", "ad2"} 105 adCounter := NewAdPvcCounter(twoAds) 106 adCounter.Inc("ad1") 107 adCounter.Inc("ad1") 108 adCounter.Inc("ad2") 109 adCounter.Inc("ad2") 110 adCounter.Inc("ad3") 111 observedAd := adCounter.GetLeastUsedAd() 112 assert.Equal(t, true, resources.SliceContains(twoAds, observedAd), "With 0 unused ADs") 113 } 114 115 func TestParseStorageClassInfoOciFlex(t *testing.T) { 116 storageClass := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass1"}, Provisioner: constants.OciFlexVolumeProvisioner} 117 expectedStorageClassInfo := StorageClassInfo{Name: "storageclass1", PvcAcceptsZone: true, PvcZoneMatchLabel: constants.OciAvailabilityDomainLabel} 118 assert.Equal(t, expectedStorageClassInfo, parseStorageClassInfo(&storageClass, &config.OperatorConfig{}), "OCI Flex Volume with no operator config") 119 } 120 121 func TestParseStorageClassInfoWithMatchLabel(t *testing.T) { 122 storageClass := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass2"}, Provisioner: "someprovisioner"} 123 expectedStorageClassInfo := StorageClassInfo{Name: "storageclass2", PvcAcceptsZone: true, PvcZoneMatchLabel: "somematchlabel"} 124 assert.Equal(t, expectedStorageClassInfo, parseStorageClassInfo(&storageClass, &config.OperatorConfig{Pvcs: config.Pvcs{ZoneMatchLabel: "somematchlabel"}}), "Match label specified in operator config") 125 } 126 127 func TestParseStorageClassInfoWithoutMatchLabel(t *testing.T) { 128 storageClass := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass3"}, Provisioner: "someprovisioner"} 129 expectedStorageClassInfo := StorageClassInfo{Name: "storageclass3", PvcAcceptsZone: false} 130 assert.Equal(t, expectedStorageClassInfo, parseStorageClassInfo(&storageClass, &config.OperatorConfig{}), "No match label specified in operator config") 131 } 132 133 func TestAdFromExistingPVC1(t *testing.T) { 134 // Storage class accepts an AD, and the PVC is labels as expected 135 storageClassInfo := StorageClassInfo{Name: "storageclass1", PvcAcceptsZone: true, PvcZoneMatchLabel: "somematchlabel"} 136 pvc := corev1.PersistentVolumeClaim{Spec: corev1.PersistentVolumeClaimSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"somematchlabel": "zone1"}}}} 137 assert.Equal(t, "zone1", getZoneFromExistingPvc(storageClassInfo, &pvc), "Existing PVC contains expected AD label") 138 } 139 140 func TestAdFromExistingPVC2(t *testing.T) { 141 // Storage class accepts an AD, but the PVC is not labeled correctly - should just return an empty string 142 storageClassInfo := StorageClassInfo{Name: "storageclass1", PvcAcceptsZone: true, PvcZoneMatchLabel: "somematchlabel"} 143 pvc := corev1.PersistentVolumeClaim{} 144 assert.Equal(t, "", getZoneFromExistingPvc(storageClassInfo, &pvc), "Existing PVC contains expected AD label") 145 } 146 147 func TestAdFromExistingPVC3(t *testing.T) { 148 // Storage class doesn't accept an AD 149 storageClassInfo := StorageClassInfo{Name: "storageclass1", PvcAcceptsZone: false} 150 pvc := corev1.PersistentVolumeClaim{} 151 assert.Equal(t, "", getZoneFromExistingPvc(storageClassInfo, &pvc), "Storage class doesn't accept AD labels on PVCs") 152 } 153 154 func TestGetDefaultStorageClass1(t *testing.T) { 155 storageClass1 := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass1"}} 156 storageClass2 := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass2", Annotations: map[string]string{constants.K8sDefaultStorageClassAnnotation: "true"}}} 157 storageClass3 := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass3"}} 158 result := getDefaultStorageClass([]*storagev1.StorageClass{&storageClass1, &storageClass2, &storageClass3}) 159 assert.Equal(t, result, &storageClass2, "Default storage class found based on standard label") 160 } 161 162 func TestGetDefaultStorageClass2(t *testing.T) { 163 storageClass1 := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass1"}} 164 storageClass2 := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass2"}} 165 storageClass3 := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass3", Annotations: map[string]string{constants.K8sDefaultStorageClassBetaAnnotation: "true"}}} 166 result := getDefaultStorageClass([]*storagev1.StorageClass{&storageClass1, &storageClass2, &storageClass3}) 167 assert.Equal(t, result, &storageClass3, "Default storage class found based on beta label") 168 } 169 170 func TestGetDefaultStorageClass3(t *testing.T) { 171 storageClass1 := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass1"}} 172 storageClass2 := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass2"}} 173 storageClass3 := storagev1.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: "storageclass3"}} 174 result := getDefaultStorageClass([]*storagev1.StorageClass{&storageClass1, &storageClass2, &storageClass3}) 175 assert.Equal(t, result.Name, "", "Expect storage class name to be empty") 176 } 177 178 func TestGetDefaultStorageClass4(t *testing.T) { 179 result := getDefaultStorageClass([]*storagev1.StorageClass{}) 180 assert.Equal(t, result.Name, "", "Expect storage class name to be empty") 181 }