diff --git a/sku.go b/sku.go index 7a6dbad..87ac4a4 100644 --- a/sku.go +++ b/sku.go @@ -148,7 +148,7 @@ func (s *SKU) GetCapabilityIntegerQuantity(name string) (int64, error) { return -1, &ErrCapabilityNotFound{name} } for _, capability := range *s.Capabilities { - if capability.Name != nil && *capability.Name == name { + if capability.Name != nil && strings.EqualFold(*capability.Name, name) { if capability.Value != nil { intVal, err := strconv.ParseInt(*capability.Value, ten, sixtyFour) if err != nil { @@ -171,7 +171,7 @@ func (s *SKU) GetCapabilityFloatQuantity(name string) (float64, error) { return -1, &ErrCapabilityNotFound{name} } for _, capability := range *s.Capabilities { - if capability.Name != nil && *capability.Name == name { + if capability.Name != nil && strings.EqualFold(*capability.Name, name) { if capability.Value != nil { intVal, err := strconv.ParseFloat(*capability.Value, sixtyFour) if err != nil { @@ -192,7 +192,7 @@ func (s *SKU) GetCapabilityString(name string) (string, error) { return "", &ErrCapabilityNotFound{name} } for _, capability := range *s.Capabilities { - if capability.Name != nil && *capability.Name == name { + if capability.Name != nil && strings.EqualFold(*capability.Name, name) { if capability.Value != nil { return *capability.Value, nil } @@ -576,7 +576,7 @@ func (s *SKU) Equal(other *SKU) bool { // MemberOf returns true if the SKU's name is in the list of SKUs. func (s *SKU) MemberOf(skuList []SKU) bool { for _, sku := range skuList { - if s.GetName() == sku.GetName() { + if strings.EqualFold(s.GetName(), sku.GetName()) { return true } } diff --git a/sku_test.go b/sku_test.go index ec79d0a..371eba3 100644 --- a/sku_test.go +++ b/sku_test.go @@ -52,6 +52,42 @@ func Test_SKU_GetCapabilityQuantity(t *testing.T) { capability: "foo", expect: 100, }, + "capability name matching should be case insensitive - lowercase query": { + sku: compute.ResourceSku{ + Capabilities: &[]compute.ResourceSkuCapabilities{ + { + Name: to.StringPtr("VCPUs"), + Value: to.StringPtr("8"), + }, + }, + }, + capability: "vcpus", + expect: 8, + }, + "capability name matching should be case insensitive - uppercase query": { + sku: compute.ResourceSku{ + Capabilities: &[]compute.ResourceSkuCapabilities{ + { + Name: to.StringPtr("memoryGB"), + Value: to.StringPtr("32"), + }, + }, + }, + capability: "MEMORYGB", + expect: 32, + }, + "capability name matching should be case insensitive - mixed case query": { + sku: compute.ResourceSku{ + Capabilities: &[]compute.ResourceSkuCapabilities{ + { + Name: to.StringPtr("maxResourceVolumeMB"), + Value: to.StringPtr("1024"), + }, + }, + }, + capability: "MaxResourceVolumeMb", + expect: 1024, + }, } for name, tc := range cases { @@ -78,6 +114,142 @@ func Test_SKU_GetCapabilityQuantity(t *testing.T) { } } +func Test_SKU_GetCapabilityFloatQuantity(t *testing.T) { + cases := map[string]struct { + sku compute.ResourceSku + capability string + expect float64 + err string + }{ + "empty capability list should return capability not found": { + sku: compute.ResourceSku{}, + capability: "", + err: (&ErrCapabilityNotFound{""}).Error(), + }, + "capability should return successfully with float": { + sku: compute.ResourceSku{ + Capabilities: &[]compute.ResourceSkuCapabilities{ + { + Name: to.StringPtr("memoryGB"), + Value: to.StringPtr("7.5"), + }, + }, + }, + capability: "memoryGB", + expect: 7.5, + }, + "capability name matching should be case insensitive for float": { + sku: compute.ResourceSku{ + Capabilities: &[]compute.ResourceSkuCapabilities{ + { + Name: to.StringPtr("MemoryGB"), + Value: to.StringPtr("16.0"), + }, + }, + }, + capability: "memorygb", + expect: 16.0, + }, + } + + for name, tc := range cases { + tc := tc + t.Run(name, func(t *testing.T) { + sku := SKU(tc.sku) + quantity, err := sku.GetCapabilityFloatQuantity(tc.capability) + if tc.err != "" { + if err == nil { + t.Errorf("expected failure with error '%s' but did not occur", tc.err) + } + if diff := cmp.Diff(tc.err, err.Error()); diff != "" { + t.Error(diff) + } + } else { + if err != nil { + t.Errorf("expected success but failure occurred with error '%s'", err) + } + if diff := cmp.Diff(tc.expect, quantity); diff != "" { + t.Error(diff) + } + } + }) + } +} + +func Test_SKU_GetCapabilityString(t *testing.T) { + cases := map[string]struct { + sku compute.ResourceSku + capability string + expect string + err string + }{ + "empty capability list should return capability not found": { + sku: compute.ResourceSku{}, + capability: "", + err: (&ErrCapabilityNotFound{""}).Error(), + }, + "capability should return successfully with string": { + sku: compute.ResourceSku{ + Capabilities: &[]compute.ResourceSkuCapabilities{ + { + Name: to.StringPtr("CPUArchitectureType"), + Value: to.StringPtr("x64"), + }, + }, + }, + capability: "CPUArchitectureType", + expect: "x64", + }, + "capability name matching should be case insensitive for string": { + sku: compute.ResourceSku{ + Capabilities: &[]compute.ResourceSkuCapabilities{ + { + Name: to.StringPtr("CPUArchitectureType"), + Value: to.StringPtr("Arm64"), + }, + }, + }, + capability: "cpuarchitecturetype", + expect: "Arm64", + }, + "capability name matching should be case insensitive - mixed case string": { + sku: compute.ResourceSku{ + Capabilities: &[]compute.ResourceSkuCapabilities{ + { + Name: to.StringPtr("hyperVGenerations"), + Value: to.StringPtr("V1,V2"), + }, + }, + }, + capability: "HyperVGenerations", + expect: "V1,V2", + }, + } + + for name, tc := range cases { + tc := tc + t.Run(name, func(t *testing.T) { + sku := SKU(tc.sku) + result, err := sku.GetCapabilityString(tc.capability) + if tc.err != "" { + if err == nil { + t.Errorf("expected failure with error '%s' but did not occur", tc.err) + } + if diff := cmp.Diff(tc.err, err.Error()); diff != "" { + t.Error(diff) + } + } else { + if err != nil { + t.Errorf("expected success but failure occurred with error '%s'", err) + } + if diff := cmp.Diff(tc.expect, result); diff != "" { + t.Error(diff) + } + } + }) + } +} + func Test_SKU_HasCapability(t *testing.T) { cases := map[string]struct { sku compute.ResourceSku @@ -139,6 +311,30 @@ func Test_SKU_HasCapability(t *testing.T) { capability: "foo", expect: true, }, + "capability name matching should be case insensitive - uppercase capability": { + sku: compute.ResourceSku{ + Capabilities: &[]compute.ResourceSkuCapabilities{ + { + Name: to.StringPtr("EncryptionAtHostSupported"), + Value: to.StringPtr("True"), + }, + }, + }, + capability: "encryptionathostsupported", + expect: true, + }, + "capability name matching should be case insensitive - mixed case capability": { + sku: compute.ResourceSku{ + Capabilities: &[]compute.ResourceSkuCapabilities{ + { + Name: to.StringPtr("acceleratednetworkingenabled"), + Value: to.StringPtr("True"), + }, + }, + }, + capability: "AcceleratedNetworkingEnabled", + expect: true, + }, } for name, tc := range cases { @@ -557,6 +753,20 @@ func Test_SKU_Includes(t *testing.T) { }, expect: true, }, + "name matching should be case insensitive": { + skuList: []SKU{ + { + Name: to.StringPtr("Standard_D4s_v3"), + }, + { + Name: to.StringPtr("Standard_F8s_v2"), + }, + }, + sku: SKU{ + Name: to.StringPtr("standard_d4s_v3"), + }, + expect: true, + }, } for name, tc := range cases { tc := tc diff --git a/v2/sku.go b/v2/sku.go index 816450e..b3623a6 100644 --- a/v2/sku.go +++ b/v2/sku.go @@ -145,7 +145,7 @@ func (s *SKU) GetCPUArchitectureType() (string, error) { // parsed as an integer. func (s *SKU) GetCapabilityIntegerQuantity(name string) (int64, error) { for _, capability := range s.Capabilities { - if capability != nil && capability.Name != nil && *capability.Name == name { + if capability != nil && capability.Name != nil && strings.EqualFold(*capability.Name, name) { if capability.Value != nil { intVal, err := strconv.ParseInt(*capability.Value, ten, sixtyFour) if err != nil { @@ -165,7 +165,7 @@ func (s *SKU) GetCapabilityIntegerQuantity(name string) (int64, error) { // not be parsed as an integer. func (s *SKU) GetCapabilityFloatQuantity(name string) (float64, error) { for _, capability := range s.Capabilities { - if capability != nil && capability.Name != nil && *capability.Name == name { + if capability != nil && capability.Name != nil && strings.EqualFold(*capability.Name, name) { if capability.Value != nil { intVal, err := strconv.ParseFloat(*capability.Value, sixtyFour) if err != nil { @@ -183,7 +183,7 @@ func (s *SKU) GetCapabilityFloatQuantity(name string) (float64, error) { // It errors if the capability is not found or the value was nil func (s *SKU) GetCapabilityString(name string) (string, error) { for _, capability := range s.Capabilities { - if capability != nil && capability.Name != nil && *capability.Name == name { + if capability != nil && capability.Name != nil && strings.EqualFold(*capability.Name, name) { if capability.Value != nil { return *capability.Value, nil } @@ -538,7 +538,7 @@ func (s *SKU) Equal(other *SKU) bool { // MemberOf returns true if the SKU's name is in the list of SKUs. func (s *SKU) MemberOf(skuList []SKU) bool { for _, sku := range skuList { - if s.GetName() == sku.GetName() { + if strings.EqualFold(s.GetName(), sku.GetName()) { return true } } diff --git a/v2/sku_test.go b/v2/sku_test.go index d28a00f..f81cf1f 100644 --- a/v2/sku_test.go +++ b/v2/sku_test.go @@ -52,6 +52,42 @@ func Test_SKU_GetCapabilityQuantity(t *testing.T) { capability: "foo", expect: 100, }, + "capability name matching should be case insensitive - lowercase query": { + sku: armcompute.ResourceSKU{ + Capabilities: []*armcompute.ResourceSKUCapabilities{ + { + Name: to.Ptr("VCPUs"), + Value: to.Ptr("8"), + }, + }, + }, + capability: "vcpus", + expect: 8, + }, + "capability name matching should be case insensitive - uppercase query": { + sku: armcompute.ResourceSKU{ + Capabilities: []*armcompute.ResourceSKUCapabilities{ + { + Name: to.Ptr("memoryGB"), + Value: to.Ptr("32"), + }, + }, + }, + capability: "MEMORYGB", + expect: 32, + }, + "capability name matching should be case insensitive - mixed case query": { + sku: armcompute.ResourceSKU{ + Capabilities: []*armcompute.ResourceSKUCapabilities{ + { + Name: to.Ptr("maxResourceVolumeMB"), + Value: to.Ptr("1024"), + }, + }, + }, + capability: "MaxResourceVolumeMb", + expect: 1024, + }, } for name, tc := range cases { @@ -78,6 +114,142 @@ func Test_SKU_GetCapabilityQuantity(t *testing.T) { } } +func Test_SKU_GetCapabilityFloatQuantity(t *testing.T) { + cases := map[string]struct { + sku armcompute.ResourceSKU + capability string + expect float64 + err string + }{ + "empty capability list should return capability not found": { + sku: armcompute.ResourceSKU{}, + capability: "", + err: (&ErrCapabilityNotFound{""}).Error(), + }, + "capability should return successfully with float": { + sku: armcompute.ResourceSKU{ + Capabilities: []*armcompute.ResourceSKUCapabilities{ + { + Name: to.Ptr("memoryGB"), + Value: to.Ptr("7.5"), + }, + }, + }, + capability: "memoryGB", + expect: 7.5, + }, + "capability name matching should be case insensitive for float": { + sku: armcompute.ResourceSKU{ + Capabilities: []*armcompute.ResourceSKUCapabilities{ + { + Name: to.Ptr("MemoryGB"), + Value: to.Ptr("16.0"), + }, + }, + }, + capability: "memorygb", + expect: 16.0, + }, + } + + for name, tc := range cases { + tc := tc + t.Run(name, func(t *testing.T) { + sku := SKU(tc.sku) + quantity, err := sku.GetCapabilityFloatQuantity(tc.capability) + if tc.err != "" { + if err == nil { + t.Errorf("expected failure with error '%s' but did not occur", tc.err) + } + if diff := cmp.Diff(tc.err, err.Error()); diff != "" { + t.Error(diff) + } + } else { + if err != nil { + t.Errorf("expected success but failure occurred with error '%s'", err) + } + if diff := cmp.Diff(tc.expect, quantity); diff != "" { + t.Error(diff) + } + } + }) + } +} + +func Test_SKU_GetCapabilityString(t *testing.T) { + cases := map[string]struct { + sku armcompute.ResourceSKU + capability string + expect string + err string + }{ + "empty capability list should return capability not found": { + sku: armcompute.ResourceSKU{}, + capability: "", + err: (&ErrCapabilityNotFound{""}).Error(), + }, + "capability should return successfully with string": { + sku: armcompute.ResourceSKU{ + Capabilities: []*armcompute.ResourceSKUCapabilities{ + { + Name: to.Ptr("CPUArchitectureType"), + Value: to.Ptr("x64"), + }, + }, + }, + capability: "CPUArchitectureType", + expect: "x64", + }, + "capability name matching should be case insensitive for string": { + sku: armcompute.ResourceSKU{ + Capabilities: []*armcompute.ResourceSKUCapabilities{ + { + Name: to.Ptr("CPUArchitectureType"), + Value: to.Ptr("Arm64"), + }, + }, + }, + capability: "cpuarchitecturetype", + expect: "Arm64", + }, + "capability name matching should be case insensitive - mixed case string": { + sku: armcompute.ResourceSKU{ + Capabilities: []*armcompute.ResourceSKUCapabilities{ + { + Name: to.Ptr("hyperVGenerations"), + Value: to.Ptr("V1,V2"), + }, + }, + }, + capability: "HyperVGenerations", + expect: "V1,V2", + }, + } + + for name, tc := range cases { + tc := tc + t.Run(name, func(t *testing.T) { + sku := SKU(tc.sku) + result, err := sku.GetCapabilityString(tc.capability) + if tc.err != "" { + if err == nil { + t.Errorf("expected failure with error '%s' but did not occur", tc.err) + } + if diff := cmp.Diff(tc.err, err.Error()); diff != "" { + t.Error(diff) + } + } else { + if err != nil { + t.Errorf("expected success but failure occurred with error '%s'", err) + } + if diff := cmp.Diff(tc.expect, result); diff != "" { + t.Error(diff) + } + } + }) + } +} + func Test_SKU_HasCapability(t *testing.T) { cases := map[string]struct { sku armcompute.ResourceSKU @@ -139,6 +311,30 @@ func Test_SKU_HasCapability(t *testing.T) { capability: "foo", expect: true, }, + "capability name matching should be case insensitive - uppercase capability": { + sku: armcompute.ResourceSKU{ + Capabilities: []*armcompute.ResourceSKUCapabilities{ + { + Name: to.Ptr("EncryptionAtHostSupported"), + Value: to.Ptr("True"), + }, + }, + }, + capability: "encryptionathostsupported", + expect: true, + }, + "capability name matching should be case insensitive - mixed case capability": { + sku: armcompute.ResourceSKU{ + Capabilities: []*armcompute.ResourceSKUCapabilities{ + { + Name: to.Ptr("acceleratednetworkingenabled"), + Value: to.Ptr("True"), + }, + }, + }, + capability: "AcceleratedNetworkingEnabled", + expect: true, + }, } for name, tc := range cases { @@ -557,6 +753,20 @@ func Test_SKU_Includes(t *testing.T) { }, expect: true, }, + "name matching should be case insensitive": { + skuList: []SKU{ + { + Name: to.Ptr("Standard_D4s_v3"), + }, + { + Name: to.Ptr("Standard_F8s_v2"), + }, + }, + sku: SKU{ + Name: to.Ptr("standard_d4s_v3"), + }, + expect: true, + }, } for name, tc := range cases { t.Run(name, func(t *testing.T) {