Просмотр исходного кода

updating test cases and documentation

Signed-off-by: Alan Rodrigues <alanr5691@yahoo.com>
Alan Rodrigues 3 лет назад
Родитель
Сommit
b7c2b9aeeb
2 измененных файлов с 218 добавлено и 40 удалено
  1. 12 17
      pkg/cloud/aliyunprovider.go
  2. 206 23
      pkg/cloud/aliyunprovider_test.go

+ 12 - 17
pkg/cloud/aliyunprovider.go

@@ -153,10 +153,14 @@ func NewSlimK8sNode(instanceType, regionID, priceUnit, memorySizeInKiB, osType,
 // Basic Attributes needed atleast to get the key, Some attributes from k8s Node response
 // be populated directly into *Node object.
 type AlibabaNodeAttributes struct {
-	InstanceType    string `json:"instanceType"`
+	// InstanceType represents the type of instance.
+	InstanceType string `json:"instanceType"`
+	// MemorySizeInKiB represents the size of memory of instance.
 	MemorySizeInKiB string `json:"memorySizeInKiB"`
-	IsIoOptimized   bool   `json:"isIoOptimized"`
-	OSType          string `json:"osType"`
+	// IsIoOptimized represents the if instance is I/O optimized.
+	IsIoOptimized bool `json:"isIoOptimized"`
+	// OSType represents the OS installed in the Instance.
+	OSType string `json:"osType"`
 }
 
 func NewAlibabaNodeAttributes(node *SlimK8sNode) *AlibabaNodeAttributes {
@@ -410,14 +414,14 @@ func (alibaba *Alibaba) DownloadPricingData() error {
 	return nil
 }
 
-// AllNodePricing returns all the billing data for nodes and pvs
+// AllNodePricing returns all the pricing data for all nodes and pvs
 func (alibaba *Alibaba) AllNodePricing() (interface{}, error) {
 	alibaba.DownloadPricingDataLock.RLock()
 	defer alibaba.DownloadPricingDataLock.RUnlock()
 	return alibaba.Pricing, nil
 }
 
-// NodePricing gives a specific node pricing information given by the key
+// NodePricing gives pricing information of a specific node given by the key
 func (alibaba *Alibaba) NodePricing(key Key) (*Node, error) {
 	alibaba.DownloadPricingDataLock.RLock()
 	defer alibaba.DownloadPricingDataLock.RUnlock()
@@ -437,7 +441,7 @@ func (alibaba *Alibaba) NodePricing(key Key) (*Node, error) {
 	return returnNode, nil
 }
 
-// PVPricing gives a specific PV price for the PVkey
+// PVPricing gives a pricing information of a specific PV gien by PVkey
 func (alibaba *Alibaba) PVPricing(pvk PVKey) (*PV, error) {
 	alibaba.DownloadPricingDataLock.RLock()
 	defer alibaba.DownloadPricingDataLock.RUnlock()
@@ -957,19 +961,10 @@ func generateSlimK8sDiskFromV1PV(pv *v1.PersistentVolume, regionID string) *Slim
 		}
 	}
 
-	// Highly unlikely that label "csi.alibabacloud.com/disktype" doesn't exist but if occured default to cloud (most basic disk type)
+	// Highly unlikely that label pv.Spec.CSI.VolumeAttributes["type"] doesn't exist but if occured default to cloud (most basic disk type)
 	if diskCategory == "" {
 		diskCategory = ALIBABA_DISK_CLOUD_CATEGORY
 	}
 
-	return &SlimK8sDisk{
-		DiskType:         diskType,
-		RegionID:         regionID,
-		PriceUnit:        priceUnit,
-		SizeInGiB:        sizeInGiB,
-		DiskCategory:     diskCategory,
-		PerformanceLevel: performanceLevel,
-		ProviderID:       providerID,
-		StorageClass:     pv.Spec.StorageClassName,
-	}
+	return NewSlimK8sDisk(diskType, regionID, priceUnit, diskCategory, performanceLevel, providerID, pv.Spec.StorageClassName, sizeInGiB)
 }

+ 206 - 23
pkg/cloud/aliyunprovider_test.go

@@ -22,9 +22,42 @@ func TestCreateDescribePriceACSRequest(t *testing.T) {
 		ProviderID:         "Ali-XXX-node-01",
 		InstanceTypeFamily: "g6",
 	}
-	_, err := createDescribePriceACSRequest(node)
-	if err != nil {
-		t.Errorf("Error converting to Alibaba cloud request")
+
+	disk := &SlimK8sDisk{
+		DiskType:         "data",
+		RegionID:         "cn-hangzhou",
+		PriceUnit:        "Hour",
+		SizeInGiB:        "20",
+		DiskCategory:     "diskCategory",
+		PerformanceLevel: "cloud_essd",
+		ProviderID:       "d-Ali-XXX-01",
+		StorageClass:     "testStorageClass",
+	}
+
+	cases := []struct {
+		name          string
+		testStruct    interface{}
+		expectedError error
+	}{
+		{
+			name:          "test CreateDescribePriceACSRequest with SlimK8sNode struct Object",
+			testStruct:    node,
+			expectedError: nil,
+		},
+		{
+			name:          "test CreateDescribePriceACSRequest with SlimK8sDisk struct Object",
+			testStruct:    disk,
+			expectedError: nil,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			_, err := createDescribePriceACSRequest(c.testStruct)
+			if err != nil && c.expectedError == nil {
+				t.Fatalf("Case name %s: Error converting to Alibaba cloud request", c.name)
+			}
+		})
 	}
 }
 
@@ -47,12 +80,12 @@ func TestProcessDescribePriceAndCreateAlibabaPricing(t *testing.T) {
 
 	cases := []struct {
 		name          string
-		testNode      *SlimK8sNode
+		teststruct    interface{}
 		expectedError error
 	}{
 		{
 			name: "test Enhanced General Purpose Type g6e instance family",
-			testNode: &SlimK8sNode{
+			teststruct: &SlimK8sNode{
 				InstanceType:       "ecs.g6e.xlarge",
 				RegionID:           "cn-hangzhou",
 				PriceUnit:          "Hour",
@@ -66,7 +99,7 @@ func TestProcessDescribePriceAndCreateAlibabaPricing(t *testing.T) {
 		},
 		{
 			name: "test General Purpose Type g6 instance family",
-			testNode: &SlimK8sNode{
+			teststruct: &SlimK8sNode{
 				InstanceType:       "ecs.g6.3xlarge",
 				RegionID:           "cn-hangzhou",
 				PriceUnit:          "Hour",
@@ -80,7 +113,7 @@ func TestProcessDescribePriceAndCreateAlibabaPricing(t *testing.T) {
 		},
 		{
 			name: "test General Purpose Type g5 instance family",
-			testNode: &SlimK8sNode{
+			teststruct: &SlimK8sNode{
 				InstanceType:       "ecs.g5.2xlarge",
 				RegionID:           "cn-hangzhou",
 				PriceUnit:          "Hour",
@@ -94,7 +127,7 @@ func TestProcessDescribePriceAndCreateAlibabaPricing(t *testing.T) {
 		},
 		{
 			name: "test General Purpose Type sn2 instance family",
-			testNode: &SlimK8sNode{
+			teststruct: &SlimK8sNode{
 				InstanceType:       "ecs.sn2.large",
 				RegionID:           "cn-hangzhou",
 				PriceUnit:          "Hour",
@@ -108,7 +141,7 @@ func TestProcessDescribePriceAndCreateAlibabaPricing(t *testing.T) {
 		},
 		{
 			name: "test General Purpose Type with Enhanced Network Performance sn2ne instance family",
-			testNode: &SlimK8sNode{
+			teststruct: &SlimK8sNode{
 				InstanceType:       "ecs.sn2ne.2xlarge",
 				RegionID:           "cn-hangzhou",
 				PriceUnit:          "Hour",
@@ -122,21 +155,76 @@ func TestProcessDescribePriceAndCreateAlibabaPricing(t *testing.T) {
 		},
 		{
 			name:          "test for a nil information",
-			testNode:      nil,
+			teststruct:    nil,
 			expectedError: fmt.Errorf("unsupported ECS pricing component at this time"),
 		},
+		{
+			name: "test Cloud Disk with Category cloud representing basic disk",
+			teststruct: &SlimK8sDisk{
+				DiskType:     "data",
+				RegionID:     "cn-hangzhou",
+				PriceUnit:    "Hour",
+				SizeInGiB:    "20",
+				DiskCategory: "cloud",
+				ProviderID:   "d-Ali-cloud-XXX-01",
+				StorageClass: "temp",
+			},
+			expectedError: nil,
+		},
+		{
+			name: "test Cloud Disk with Category cloud_efficiency representing ultra disk",
+			teststruct: &SlimK8sDisk{
+				DiskType:     "data",
+				RegionID:     "cn-hangzhou",
+				PriceUnit:    "Hour",
+				SizeInGiB:    "40",
+				DiskCategory: "cloud_efficiency",
+				ProviderID:   "d-Ali-cloud-XXX-02",
+				StorageClass: "temp",
+			},
+			expectedError: nil,
+		},
+		{
+			name: "test Cloud Disk with Category cloud_ssd representing standard SSD",
+			teststruct: &SlimK8sDisk{
+				DiskType:     "data",
+				RegionID:     "cn-hangzhou",
+				PriceUnit:    "Hour",
+				SizeInGiB:    "40",
+				DiskCategory: "cloud_efficiency",
+				ProviderID:   "d-Ali-cloud-XXX-02",
+				StorageClass: "temp",
+			},
+			expectedError: nil,
+		},
+		{
+			name: "test Cloud Disk with Category cloud_essd representing Enhanced SSD with PL2 performance level",
+			teststruct: &SlimK8sDisk{
+				DiskType:         "data",
+				RegionID:         "cn-hangzhou",
+				PriceUnit:        "Hour",
+				SizeInGiB:        "80",
+				DiskCategory:     "cloud_ssd",
+				PerformanceLevel: "PL2",
+				ProviderID:       "d-Ali-cloud-XXX-04",
+				StorageClass:     "temp",
+			},
+			expectedError: nil,
+		},
 	}
 	custom := &CustomPricing{}
 	for _, c := range cases {
 		t.Run(c.name, func(t *testing.T) {
-			pricingObj, err := processDescribePriceAndCreateAlibabaPricing(client, c.testNode, signer, custom)
+			pricingObj, err := processDescribePriceAndCreateAlibabaPricing(client, c.teststruct, signer, custom)
 			if err != nil && c.expectedError == nil {
 				t.Fatalf("Case name %s: got an error %s", c.name, err)
 			}
-			if pricingObj == nil {
-				t.Fatalf("Case name %s: got a nil pricing object", c.name)
+			if c.teststruct != nil {
+				if pricingObj == nil {
+					t.Fatalf("Case name %s: got a nil pricing object", c.name)
+				}
+				t.Logf("Case name %s: Pricing Information gathered for instanceType is %v", c.name, pricingObj.PricingTerms.PricingDetails.TradePrice)
 			}
-			t.Logf("Pricing Information gathered for instanceType %s is %v", c.name, pricingObj.PricingTerms.PricingDetails.TradePrice)
 		})
 	}
 }
@@ -185,7 +273,7 @@ func TestDetermineKeyForPricing(t *testing.T) {
 		expectedError error
 	}{
 		{
-			name: "test when all RegionID, InstanceType, OSType & ALIBABA_OPTIMIZE_KEYWORD words are used to key",
+			name: "test when all RegionID, InstanceType, OSType & ALIBABA_OPTIMIZE_KEYWORD words are used in Node key",
 			testVar: &SlimK8sNode{
 				InstanceType:       "ecs.sn2.large",
 				RegionID:           "cn-hangzhou",
@@ -200,7 +288,7 @@ func TestDetermineKeyForPricing(t *testing.T) {
 			expectedError: nil,
 		},
 		{
-			name: "test missing InstanceType to create key",
+			name: "test missing InstanceType to create Node key",
 			testVar: &SlimK8sNode{
 				RegionID:        "cn-hangzhou",
 				PriceUnit:       "Hour",
@@ -226,6 +314,35 @@ func TestDetermineKeyForPricing(t *testing.T) {
 			expectedKey:   "",
 			expectedError: fmt.Errorf("unsupported ECS type randomK8sStruct for DescribePrice at this time"),
 		},
+		{
+			name: "test when all RegionID, InstanceType, OSType & ALIBABA_OPTIMIZE_KEYWORD words are used to key",
+			testVar: &SlimK8sDisk{
+				DiskType:     "data",
+				RegionID:     "cn-hangzhou",
+				PriceUnit:    "Hour",
+				SizeInGiB:    "40",
+				DiskCategory: "cloud_efficiency",
+				ProviderID:   "d-Ali-cloud-XXX-02",
+				StorageClass: "temp",
+			},
+			expectedKey:   "cn-hangzhou::data::cloud_efficiency::40",
+			expectedError: nil,
+		},
+		{
+			name: "test missing InstanceType to create key",
+			testVar: &SlimK8sDisk{
+				DiskType:         "data",
+				RegionID:         "cn-hangzhou",
+				PriceUnit:        "Hour",
+				SizeInGiB:        "80",
+				DiskCategory:     "cloud_ssd",
+				PerformanceLevel: "PL2",
+				ProviderID:       "d-Ali-cloud-XXX-04",
+				StorageClass:     "temp",
+			},
+			expectedKey:   "cn-hangzhou::data::cloud_ssd::PL2::80",
+			expectedError: nil,
+		},
 	}
 	for _, c := range cases {
 		t.Run(c.name, func(t *testing.T) {
@@ -260,7 +377,7 @@ func TestGenerateSlimK8sNodeFromV1Node(t *testing.T) {
 			expectedSlimNode: &SlimK8sNode{
 				InstanceType:       "ecs.sn2ne.2xlarge",
 				RegionID:           "us-east-1",
-				PriceUnit:          "Hour",
+				PriceUnit:          ALIBABA_HOUR_PRICE_UNIT,
 				MemorySizeInKiB:    "16",
 				IsIoOptimized:      true,
 				OSType:             "linux",
@@ -272,22 +389,88 @@ func TestGenerateSlimK8sNodeFromV1Node(t *testing.T) {
 		t.Run(c.name, func(t *testing.T) {
 			returnSlimK8sNode := generateSlimK8sNodeFromV1Node(c.testNode)
 			if returnSlimK8sNode.InstanceType != c.expectedSlimNode.InstanceType {
-				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected InstanceType: %s , recieved Instance Type: %s", c.expectedSlimNode.InstanceType, returnSlimK8sNode.InstanceType)
+				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected InstanceType: %s , recieved InstanceType: %s", c.expectedSlimNode.InstanceType, returnSlimK8sNode.InstanceType)
 			}
 			if returnSlimK8sNode.RegionID != c.expectedSlimNode.RegionID {
-				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected RegionID: %s , recieved RegionID Type: %s", c.expectedSlimNode.RegionID, returnSlimK8sNode.RegionID)
+				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected RegionID: %s , recieved RegionID: %s", c.expectedSlimNode.RegionID, returnSlimK8sNode.RegionID)
 			}
 			if returnSlimK8sNode.PriceUnit != c.expectedSlimNode.PriceUnit {
-				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected PriceUnit: %s , recieved PriceUnit Type: %s", c.expectedSlimNode.PriceUnit, returnSlimK8sNode.PriceUnit)
+				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected PriceUnit: %s , recieved PriceUnit: %s", c.expectedSlimNode.PriceUnit, returnSlimK8sNode.PriceUnit)
 			}
 			if returnSlimK8sNode.MemorySizeInKiB != c.expectedSlimNode.MemorySizeInKiB {
-				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected MemorySizeInKiB: %s , recieved MemorySizeInKiB Type: %s", c.expectedSlimNode.MemorySizeInKiB, returnSlimK8sNode.MemorySizeInKiB)
+				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected MemorySizeInKiB: %s , recieved MemorySizeInKiB: %s", c.expectedSlimNode.MemorySizeInKiB, returnSlimK8sNode.MemorySizeInKiB)
 			}
 			if returnSlimK8sNode.OSType != c.expectedSlimNode.OSType {
-				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected OSType: %s , recieved OSType Type: %s", c.expectedSlimNode.OSType, returnSlimK8sNode.OSType)
+				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected OSType: %s , recieved OSType: %s", c.expectedSlimNode.OSType, returnSlimK8sNode.OSType)
 			}
 			if returnSlimK8sNode.InstanceTypeFamily != c.expectedSlimNode.InstanceTypeFamily {
-				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected InstanceTypeFamily: %s , recieved InstanceTypeFamily Type: %s", c.expectedSlimNode.InstanceTypeFamily, returnSlimK8sNode.InstanceTypeFamily)
+				t.Fatalf("unexpected conversion in function generateSlimK8sNodeFromV1Node expected InstanceTypeFamily: %s , recieved InstanceTypeFamily: %s", c.expectedSlimNode.InstanceTypeFamily, returnSlimK8sNode.InstanceTypeFamily)
+			}
+		})
+	}
+}
+
+func TestGenerateSlimK8sDiskFromV1PV(t *testing.T) {
+	testv1PV := &v1.PersistentVolume{}
+	testv1PV.Spec.Capacity = v1.ResourceList{
+		v1.ResourceStorage: *resource.NewQuantity(16*1024*1024*1024, resource.BinarySI),
+	}
+	testv1PV.Spec.CSI = &v1.CSIPersistentVolumeSource{}
+	testv1PV.Spec.CSI.VolumeHandle = "testPV"
+	testv1PV.Spec.CSI.VolumeAttributes = map[string]string{
+		"performanceLevel": "PL2",
+		"type":             "cloud_essd",
+	}
+	testv1PV.Spec.CSI.VolumeHandle = "testPV"
+	testv1PV.Spec.StorageClassName = "testStorageClass"
+	cases := []struct {
+		name             string
+		testPV           *v1.PersistentVolume
+		expectedSlimDisk *SlimK8sDisk
+		inpRegionID      string
+	}{
+		{
+			name:   "test a generic *v1.Node to *SlimK8sNode Conversion",
+			testPV: testv1PV,
+			expectedSlimDisk: &SlimK8sDisk{
+				DiskType:         ALIBABA_DATA_DISK_CATEGORY,
+				RegionID:         "us-east-1",
+				PriceUnit:        ALIBABA_HOUR_PRICE_UNIT,
+				SizeInGiB:        "16",
+				DiskCategory:     "cloud_essd",
+				PerformanceLevel: "PL2",
+				ProviderID:       "testPV",
+				StorageClass:     "testStorageClass",
+			},
+			inpRegionID: "us-east-1",
+		},
+	}
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			returnSlimK8sDisk := generateSlimK8sDiskFromV1PV(c.testPV, c.inpRegionID)
+			if returnSlimK8sDisk.DiskType != c.expectedSlimDisk.DiskType {
+				t.Fatalf("unexpected conversion in function generateSlimK8sDiskFromV1PV expected DiskType: %s , recieved DiskType: %s", c.expectedSlimDisk.DiskType, returnSlimK8sDisk.DiskType)
+			}
+			if returnSlimK8sDisk.RegionID != c.expectedSlimDisk.RegionID {
+				t.Fatalf("unexpected conversion in function generateSlimK8sDiskFromV1PV expected RegionID: %s , recieved RegionID Type: %s", c.expectedSlimDisk.RegionID, returnSlimK8sDisk.RegionID)
+			}
+			if returnSlimK8sDisk.PriceUnit != c.expectedSlimDisk.PriceUnit {
+				t.Fatalf("unexpected conversion in function generateSlimK8sDiskFromV1PV expected PriceUnit: %s , recieved PriceUnit Type: %s", c.expectedSlimDisk.PriceUnit, returnSlimK8sDisk.PriceUnit)
+			}
+			if returnSlimK8sDisk.SizeInGiB != c.expectedSlimDisk.SizeInGiB {
+				t.Fatalf("unexpected conversion in function generateSlimK8sDiskFromV1PV expected SizeInGiB: %s , recieved SizeInGiB Type: %s", c.expectedSlimDisk.SizeInGiB, returnSlimK8sDisk.SizeInGiB)
+			}
+			if returnSlimK8sDisk.DiskCategory != c.expectedSlimDisk.DiskCategory {
+				t.Fatalf("unexpected conversion in function generateSlimK8sDiskFromV1PV expected DiskCategory: %s , recieved DiskCategory Type: %s", c.expectedSlimDisk.DiskCategory, returnSlimK8sDisk.DiskCategory)
+			}
+			if returnSlimK8sDisk.PerformanceLevel != c.expectedSlimDisk.PerformanceLevel {
+				t.Fatalf("unexpected conversion in function generateSlimK8sDiskFromV1PV expected PerformanceLevel: %s , recieved PerformanceLevel Type: %s", c.expectedSlimDisk.PerformanceLevel, returnSlimK8sDisk.PerformanceLevel)
+			}
+			if returnSlimK8sDisk.ProviderID != c.expectedSlimDisk.ProviderID {
+				t.Fatalf("unexpected conversion in function generateSlimK8sDiskFromV1PV expected ProviderID: %s , recieved ProviderID Type: %s", c.expectedSlimDisk.ProviderID, returnSlimK8sDisk.ProviderID)
+			}
+			if returnSlimK8sDisk.StorageClass != c.expectedSlimDisk.StorageClass {
+				t.Fatalf("unexpected conversion in function generateSlimK8sDiskFromV1PV expected StorageClass: %s , recieved StorageClass Type: %s", c.expectedSlimDisk.StorageClass, returnSlimK8sDisk.StorageClass)
 			}
 		})
 	}