172 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Go
		
	
	
	
| package cluster
 | |
| 
 | |
| import (
 | |
| 	"testing"
 | |
| 
 | |
| 	"context"
 | |
| 
 | |
| 	v1 "k8s.io/api/core/v1"
 | |
| 	"k8s.io/apimachinery/pkg/api/resource"
 | |
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | |
| 	"k8s.io/apimachinery/pkg/labels"
 | |
| 
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| 	acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
 | |
| 	"github.com/zalando/postgres-operator/pkg/util/config"
 | |
| 	"github.com/zalando/postgres-operator/pkg/util/constants"
 | |
| 	"github.com/zalando/postgres-operator/pkg/util/k8sutil"
 | |
| 	"k8s.io/client-go/kubernetes/fake"
 | |
| )
 | |
| 
 | |
| func NewFakeKubernetesClient() (k8sutil.KubernetesClient, *fake.Clientset) {
 | |
| 	clientSet := fake.NewSimpleClientset()
 | |
| 
 | |
| 	return k8sutil.KubernetesClient{
 | |
| 		PersistentVolumeClaimsGetter: clientSet.CoreV1(),
 | |
| 	}, clientSet
 | |
| }
 | |
| 
 | |
| func TestResizeVolumeClaim(t *testing.T) {
 | |
| 	testName := "test resizing of persistent volume claims"
 | |
| 	client, _ := NewFakeKubernetesClient()
 | |
| 	clusterName := "acid-test-cluster"
 | |
| 	namespace := "default"
 | |
| 	newVolumeSize := "2Gi"
 | |
| 
 | |
| 	// new cluster with pvc storage resize mode and configured labels
 | |
| 	var cluster = New(
 | |
| 		Config{
 | |
| 			OpConfig: config.Config{
 | |
| 				Resources: config.Resources{
 | |
| 					ClusterLabels:    map[string]string{"application": "spilo"},
 | |
| 					ClusterNameLabel: "cluster-name",
 | |
| 				},
 | |
| 				StorageResizeMode: "pvc",
 | |
| 			},
 | |
| 		}, client, acidv1.Postgresql{}, logger, eventRecorder)
 | |
| 
 | |
| 	// set metadata, so that labels will get correct values
 | |
| 	cluster.Name = clusterName
 | |
| 	cluster.Namespace = namespace
 | |
| 	filterLabels := cluster.labelsSet(false)
 | |
| 
 | |
| 	// define and create PVCs for 1Gi volumes
 | |
| 	storage1Gi, err := resource.ParseQuantity("1Gi")
 | |
| 	assert.NoError(t, err)
 | |
| 
 | |
| 	pvcList := &v1.PersistentVolumeClaimList{
 | |
| 		Items: []v1.PersistentVolumeClaim{
 | |
| 			{
 | |
| 				ObjectMeta: metav1.ObjectMeta{
 | |
| 					Name:      constants.DataVolumeName + "-" + clusterName + "-0",
 | |
| 					Namespace: namespace,
 | |
| 					Labels:    filterLabels,
 | |
| 				},
 | |
| 				Spec: v1.PersistentVolumeClaimSpec{
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceStorage: storage1Gi,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 			{
 | |
| 				ObjectMeta: metav1.ObjectMeta{
 | |
| 					Name:      constants.DataVolumeName + "-" + clusterName + "-1",
 | |
| 					Namespace: namespace,
 | |
| 					Labels:    filterLabels,
 | |
| 				},
 | |
| 				Spec: v1.PersistentVolumeClaimSpec{
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceStorage: storage1Gi,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 			{
 | |
| 				ObjectMeta: metav1.ObjectMeta{
 | |
| 					Name:      constants.DataVolumeName + "-" + clusterName + "-2-0",
 | |
| 					Namespace: namespace,
 | |
| 					Labels:    labels.Set{},
 | |
| 				},
 | |
| 				Spec: v1.PersistentVolumeClaimSpec{
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceStorage: storage1Gi,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, pvc := range pvcList.Items {
 | |
| 		cluster.KubeClient.PersistentVolumeClaims(namespace).Create(context.TODO(), &pvc, metav1.CreateOptions{})
 | |
| 	}
 | |
| 
 | |
| 	// test resizing
 | |
| 	cluster.resizeVolumeClaims(acidv1.Volume{Size: newVolumeSize})
 | |
| 
 | |
| 	pvcs, err := cluster.listPersistentVolumeClaims()
 | |
| 	assert.NoError(t, err)
 | |
| 
 | |
| 	// check if listPersistentVolumeClaims returns only the PVCs matching the filter
 | |
| 	if len(pvcs) != len(pvcList.Items)-1 {
 | |
| 		t.Errorf("%s: could not find all PVCs, got %v, expected %v", testName, len(pvcs), len(pvcList.Items)-1)
 | |
| 	}
 | |
| 
 | |
| 	// check if PVCs were correctly resized
 | |
| 	for _, pvc := range pvcs {
 | |
| 		newStorageSize := quantityToGigabyte(pvc.Spec.Resources.Requests[v1.ResourceStorage])
 | |
| 		expectedQuantity, err := resource.ParseQuantity(newVolumeSize)
 | |
| 		assert.NoError(t, err)
 | |
| 		expectedSize := quantityToGigabyte(expectedQuantity)
 | |
| 		if newStorageSize != expectedSize {
 | |
| 			t.Errorf("%s: resizing failed, got %v, expected %v", testName, newStorageSize, expectedSize)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// check if other PVC was not resized
 | |
| 	pvc2, err := cluster.KubeClient.PersistentVolumeClaims(namespace).Get(context.TODO(), constants.DataVolumeName+"-"+clusterName+"-2-0", metav1.GetOptions{})
 | |
| 	assert.NoError(t, err)
 | |
| 	unchangedSize := quantityToGigabyte(pvc2.Spec.Resources.Requests[v1.ResourceStorage])
 | |
| 	expectedSize := quantityToGigabyte(storage1Gi)
 | |
| 	if unchangedSize != expectedSize {
 | |
| 		t.Errorf("%s: volume size changed, got %v, expected %v", testName, unchangedSize, expectedSize)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestQuantityToGigabyte(t *testing.T) {
 | |
| 	tests := []struct {
 | |
| 		name        string
 | |
| 		quantityStr string
 | |
| 		expected    int64
 | |
| 	}{
 | |
| 		{
 | |
| 			"test with 1Gi",
 | |
| 			"1Gi",
 | |
| 			1,
 | |
| 		},
 | |
| 		{
 | |
| 			"test with float",
 | |
| 			"1.5Gi",
 | |
| 			int64(1),
 | |
| 		},
 | |
| 		{
 | |
| 			"test with 1000Mi",
 | |
| 			"1000Mi",
 | |
| 			int64(0),
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, tt := range tests {
 | |
| 		quantity, err := resource.ParseQuantity(tt.quantityStr)
 | |
| 		assert.NoError(t, err)
 | |
| 		gigabyte := quantityToGigabyte(quantity)
 | |
| 		if gigabyte != tt.expected {
 | |
| 			t.Errorf("%s: got %v, expected %v", tt.name, gigabyte, tt.expected)
 | |
| 		}
 | |
| 	}
 | |
| }
 |