From 4247387144f3d8c5462c51eac920036e4d1a463e Mon Sep 17 00:00:00 2001 From: ONE7live Date: Fri, 27 May 2022 16:10:01 +0800 Subject: [PATCH] add some unit test for models Signed-off-by: ONE7live --- .../persistentvolumeclaims_test.go | 240 ++++++++++++++++++ .../federatedpersistentvolumeclaims_test.go | 217 ++++++++++++++++ 2 files changed, 457 insertions(+) create mode 100644 pkg/models/resources/v1alpha2/persistentvolumeclaim/persistentvolumeclaims_test.go create mode 100644 pkg/models/resources/v1alpha3/federatedpersistentvolumeclaim/federatedpersistentvolumeclaims_test.go diff --git a/pkg/models/resources/v1alpha2/persistentvolumeclaim/persistentvolumeclaims_test.go b/pkg/models/resources/v1alpha2/persistentvolumeclaim/persistentvolumeclaims_test.go new file mode 100644 index 000000000..609d2f654 --- /dev/null +++ b/pkg/models/resources/v1alpha2/persistentvolumeclaim/persistentvolumeclaims_test.go @@ -0,0 +1,240 @@ +package persistentvolumeclaim + +import ( + "testing" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes/fake" + + "github.com/google/go-cmp/cmp" + snapshot "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1" + snapshotefakeclient "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned/fake" + snapshotinformers "github.com/kubernetes-csi/external-snapshotter/client/v4/informers/externalversions" + + "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2" + "kubesphere.io/kubesphere/pkg/server/params" +) + +var ( + testStorageClassName = "sc1" +) + +var ( + pvc1 = &corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-1", + Namespace: "default", + Annotations: map[string]string{ + "kubesphere.io/in-use": "false", + "kubesphere.io/allow-snapshot": "false", + }, + }, + Spec: corev1.PersistentVolumeClaimSpec{ + StorageClassName: &testStorageClassName, + }, + Status: corev1.PersistentVolumeClaimStatus{ + Phase: corev1.ClaimPending, + }, + } + + pvc2 = &corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-2", + Namespace: "default", + Annotations: map[string]string{ + "kubesphere.io/in-use": "false", + "kubesphere.io/allow-snapshot": "false", + }, + }, + Spec: corev1.PersistentVolumeClaimSpec{ + StorageClassName: &testStorageClassName, + }, + Status: corev1.PersistentVolumeClaimStatus{ + Phase: corev1.ClaimLost, + }, + } + + pvc3 = &corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-3", + Namespace: "default", + Annotations: map[string]string{ + "kubesphere.io/in-use": "true", + "kubesphere.io/allow-snapshot": "false", + }, + }, + Spec: corev1.PersistentVolumeClaimSpec{ + StorageClassName: &testStorageClassName, + }, + Status: corev1.PersistentVolumeClaimStatus{ + Phase: corev1.ClaimBound, + }, + } + + pod1 = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod-1", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "data", + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: pvc3.Name, + }, + }, + }, + }, + }, + } + + vsc1 = &snapshot.VolumeSnapshotClass{ + ObjectMeta: metav1.ObjectMeta{ + Name: "VolumeSnapshotClass-1", + Namespace: "default", + }, + Driver: testStorageClassName, + } + + persistentVolumeClaims = []interface{}{pvc1, pvc2, pvc3} + pods = []interface{}{pod1} + volumeSnapshotClasses = []interface{}{vsc1} +) + +func prepare() (v1alpha2.Interface, error) { + client := fake.NewSimpleClientset() + informer := informers.NewSharedInformerFactory(client, 0) + snapshotClient := snapshotefakeclient.NewSimpleClientset() + snapshotInformers := snapshotinformers.NewSharedInformerFactory(snapshotClient, 0) + + for _, persistentVolumeClaim := range persistentVolumeClaims { + err := informer.Core().V1().PersistentVolumeClaims().Informer().GetIndexer().Add(persistentVolumeClaim) + if err != nil { + return nil, err + } + } + + for _, pod := range pods { + err := informer.Core().V1().Pods().Informer().GetIndexer().Add(pod) + if err != nil { + return nil, err + } + } + + for _, volumeSnapshotClass := range volumeSnapshotClasses { + err := snapshotInformers.Snapshot().V1().VolumeSnapshotClasses().Informer().GetIndexer().Add(volumeSnapshotClass) + if err != nil { + return nil, err + } + } + + return NewPersistentVolumeClaimSearcher(informer, snapshotInformers), nil +} + +func TestGet(t *testing.T) { + tests := []struct { + Namespace string + Name string + Expected interface{} + ExpectedErr error + }{ + { + "default", + "pvc-1", + pvc1, + nil, + }, + } + + getter, err := prepare() + if err != nil { + t.Fatal(err) + } + + for _, test := range tests { + got, err := getter.Get(test.Namespace, test.Name) + if test.ExpectedErr != nil && err != test.ExpectedErr { + t.Errorf("expected error, got nothing") + } else if err != nil { + t.Fatal(err) + } + + diff := cmp.Diff(got, test.Expected) + if diff != "" { + t.Errorf("%T differ (-got, +want): %s", test.Expected, diff) + } + } +} + +func TestSearch(t *testing.T) { + tests := []struct { + Namespace string + Conditions *params.Conditions + OrderBy string + Reverse bool + Expected []interface{} + ExpectedErr error + }{ + { + Namespace: "default", + Conditions: ¶ms.Conditions{ + Match: map[string]string{ + v1alpha2.Status: v1alpha2.StatusPending, + }, + Fuzzy: nil, + }, + OrderBy: "name", + Reverse: false, + Expected: []interface{}{pvc1}, + ExpectedErr: nil, + }, + { + Namespace: "default", + Conditions: ¶ms.Conditions{ + Match: map[string]string{ + v1alpha2.Status: v1alpha2.StatusLost, + }, + Fuzzy: nil, + }, + OrderBy: "name", + Reverse: false, + Expected: []interface{}{pvc2}, + ExpectedErr: nil, + }, + { + Namespace: "default", + Conditions: ¶ms.Conditions{ + Match: map[string]string{ + v1alpha2.Status: v1alpha2.StatusBound, + }, + Fuzzy: nil, + }, + OrderBy: "name", + Reverse: false, + Expected: []interface{}{pvc3}, + ExpectedErr: nil, + }, + } + + searcher, err := prepare() + if err != nil { + t.Fatal(err) + } + + for _, test := range tests { + got, err := searcher.Search(test.Namespace, test.Conditions, test.OrderBy, test.Reverse) + if test.ExpectedErr != nil && err != test.ExpectedErr { + t.Errorf("expected error, got nothing") + } else if err != nil { + t.Fatal(err) + } + + if diff := cmp.Diff(got, test.Expected); diff != "" { + t.Errorf("%T differ (-got, +want): %s", test.Expected, diff) + } + } +} diff --git a/pkg/models/resources/v1alpha3/federatedpersistentvolumeclaim/federatedpersistentvolumeclaims_test.go b/pkg/models/resources/v1alpha3/federatedpersistentvolumeclaim/federatedpersistentvolumeclaims_test.go new file mode 100644 index 000000000..78bddce4a --- /dev/null +++ b/pkg/models/resources/v1alpha3/federatedpersistentvolumeclaim/federatedpersistentvolumeclaims_test.go @@ -0,0 +1,217 @@ +package federatedpersistentvolumeclaim + +import ( + "testing" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + + "github.com/google/go-cmp/cmp" + + fedv1beta1 "kubesphere.io/api/types/v1beta1" + + "kubesphere.io/kubesphere/pkg/api" + "kubesphere.io/kubesphere/pkg/apiserver/query" + "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake" + "kubesphere.io/kubesphere/pkg/client/informers/externalversions" + "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3" +) + +var ( + testStorageClassName = "sc1" +) + +var ( + pvc1 = &fedv1beta1.FederatedPersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-1", + Namespace: "default", + }, + } + + pvc2 = &fedv1beta1.FederatedPersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-2", + Namespace: "default", + }, + Spec: fedv1beta1.FederatedPersistentVolumeClaimSpec{ + Template: fedv1beta1.PersistentVolumeClaimTemplate{ + Spec: corev1.PersistentVolumeClaimSpec{ + StorageClassName: &testStorageClassName, + }, + }, + }, + } + + pvc3 = &fedv1beta1.FederatedPersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-3", + Namespace: "default", + Labels: map[string]string{ + "kubesphere.io/in-use": "false", + }, + }, + Spec: fedv1beta1.FederatedPersistentVolumeClaimSpec{ + Template: fedv1beta1.PersistentVolumeClaimTemplate{ + Spec: corev1.PersistentVolumeClaimSpec{ + StorageClassName: &testStorageClassName, + }, + }, + }, + } + + federatedPersistentVolumeClaims = []*fedv1beta1.FederatedPersistentVolumeClaim{pvc1, pvc2, pvc3} +) + +func fedPVCsToInterface(federatedPersistentVolumeClaims ...*fedv1beta1.FederatedPersistentVolumeClaim) []interface{} { + items := make([]interface{}, 0) + + for _, fedPVC := range federatedPersistentVolumeClaims { + items = append(items, fedPVC) + } + + return items +} + +func fedPVCsToRuntimeObject(federatedPersistentVolumeClaims ...*fedv1beta1.FederatedPersistentVolumeClaim) []runtime.Object { + items := make([]runtime.Object, 0) + + for _, fedPVC := range federatedPersistentVolumeClaims { + items = append(items, fedPVC) + } + + return items +} + +func prepare() (v1alpha3.Interface, error) { + client := fake.NewSimpleClientset(fedPVCsToRuntimeObject(federatedPersistentVolumeClaims...)...) + informer := externalversions.NewSharedInformerFactory(client, 0) + + for _, fedPVC := range federatedPersistentVolumeClaims { + err := informer.Types().V1beta1().FederatedPersistentVolumeClaims().Informer().GetIndexer().Add(fedPVC) + if err != nil { + return nil, err + } + } + + return New(informer), nil +} + +func TestGet(t *testing.T) { + tests := []struct { + namespace string + name string + expected runtime.Object + expectedErr error + }{ + { + namespace: "default", + name: "pvc-1", + expected: fedPVCsToRuntimeObject(pvc1)[0], + expectedErr: nil, + }, + } + + getter, err := prepare() + if err != nil { + t.Fatal(err) + } + + for _, test := range tests { + pvc, err := getter.Get(test.namespace, test.name) + if test.expectedErr != nil && err != test.expectedErr { + t.Errorf("expected error, got nothing") + } else if err != nil { + t.Fatal(err) + } + + diff := cmp.Diff(pvc, test.expected) + if diff != "" { + t.Errorf("%T differ (-got, +want): %s", test.expected, diff) + } + } +} + +func TestList(t *testing.T) { + tests := []struct { + description string + namespace string + query *query.Query + expected *api.ListResult + expectedErr error + }{ + { + description: "test name filter", + namespace: "default", + query: &query.Query{ + Pagination: &query.Pagination{ + Limit: 10, + Offset: 0, + }, + SortBy: query.FieldName, + Ascending: false, + Filters: map[query.Field]query.Value{query.FieldName: query.Value(pvc1.Name)}, + }, + expected: &api.ListResult{ + Items: fedPVCsToInterface(federatedPersistentVolumeClaims[0]), + TotalItems: 1, + }, + expectedErr: nil, + }, + { + description: "test storageClass filter", + namespace: "default", + query: &query.Query{ + Pagination: &query.Pagination{ + Limit: 10, + Offset: 0, + }, + SortBy: query.FieldName, + Ascending: false, + Filters: map[query.Field]query.Value{query.Field(storageClassName): query.Value(*pvc2.Spec.Template.Spec.StorageClassName)}, + }, + expected: &api.ListResult{ + Items: fedPVCsToInterface(federatedPersistentVolumeClaims[2], federatedPersistentVolumeClaims[1]), + TotalItems: 2, + }, + expectedErr: nil, + }, + { + description: "test label filter", + namespace: "default", + query: &query.Query{ + Pagination: &query.Pagination{ + Limit: 10, + Offset: 0, + }, + SortBy: query.FieldName, + Ascending: false, + LabelSelector: "kubesphere.io/in-use=false", + Filters: map[query.Field]query.Value{query.Field(storageClassName): query.Value(*pvc2.Spec.Template.Spec.StorageClassName)}, + }, + expected: &api.ListResult{ + Items: fedPVCsToInterface(federatedPersistentVolumeClaims[2]), + TotalItems: 1, + }, + expectedErr: nil, + }, + } + + lister, err := prepare() + if err != nil { + t.Fatal(err) + } + + for _, test := range tests { + got, err := lister.List(test.namespace, test.query) + if test.expectedErr != nil && err != test.expectedErr { + t.Errorf("expected error, got nothing") + } else if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(got, test.expected); diff != "" { + t.Errorf("[%s] %T differ (-got, +want): %s", test.description, test.expected, diff) + } + } +}