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  }