Skip to content

Commit e5d6c26

Browse files
fix: address inconsistencies in SKU property case-sensitivity string checks (#31)
* fix: make sku capability name checks case-insensitive * fix: convert MemberOf function to use case insensitive string matches
1 parent 0119bd0 commit e5d6c26

File tree

4 files changed

+428
-8
lines changed

4 files changed

+428
-8
lines changed

sku.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ func (s *SKU) GetCapabilityIntegerQuantity(name string) (int64, error) {
148148
return -1, &ErrCapabilityNotFound{name}
149149
}
150150
for _, capability := range *s.Capabilities {
151-
if capability.Name != nil && *capability.Name == name {
151+
if capability.Name != nil && strings.EqualFold(*capability.Name, name) {
152152
if capability.Value != nil {
153153
intVal, err := strconv.ParseInt(*capability.Value, ten, sixtyFour)
154154
if err != nil {
@@ -171,7 +171,7 @@ func (s *SKU) GetCapabilityFloatQuantity(name string) (float64, error) {
171171
return -1, &ErrCapabilityNotFound{name}
172172
}
173173
for _, capability := range *s.Capabilities {
174-
if capability.Name != nil && *capability.Name == name {
174+
if capability.Name != nil && strings.EqualFold(*capability.Name, name) {
175175
if capability.Value != nil {
176176
intVal, err := strconv.ParseFloat(*capability.Value, sixtyFour)
177177
if err != nil {
@@ -192,7 +192,7 @@ func (s *SKU) GetCapabilityString(name string) (string, error) {
192192
return "", &ErrCapabilityNotFound{name}
193193
}
194194
for _, capability := range *s.Capabilities {
195-
if capability.Name != nil && *capability.Name == name {
195+
if capability.Name != nil && strings.EqualFold(*capability.Name, name) {
196196
if capability.Value != nil {
197197
return *capability.Value, nil
198198
}
@@ -576,7 +576,7 @@ func (s *SKU) Equal(other *SKU) bool {
576576
// MemberOf returns true if the SKU's name is in the list of SKUs.
577577
func (s *SKU) MemberOf(skuList []SKU) bool {
578578
for _, sku := range skuList {
579-
if s.GetName() == sku.GetName() {
579+
if strings.EqualFold(s.GetName(), sku.GetName()) {
580580
return true
581581
}
582582
}

sku_test.go

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,42 @@ func Test_SKU_GetCapabilityQuantity(t *testing.T) {
5252
capability: "foo",
5353
expect: 100,
5454
},
55+
"capability name matching should be case insensitive - lowercase query": {
56+
sku: compute.ResourceSku{
57+
Capabilities: &[]compute.ResourceSkuCapabilities{
58+
{
59+
Name: to.StringPtr("VCPUs"),
60+
Value: to.StringPtr("8"),
61+
},
62+
},
63+
},
64+
capability: "vcpus",
65+
expect: 8,
66+
},
67+
"capability name matching should be case insensitive - uppercase query": {
68+
sku: compute.ResourceSku{
69+
Capabilities: &[]compute.ResourceSkuCapabilities{
70+
{
71+
Name: to.StringPtr("memoryGB"),
72+
Value: to.StringPtr("32"),
73+
},
74+
},
75+
},
76+
capability: "MEMORYGB",
77+
expect: 32,
78+
},
79+
"capability name matching should be case insensitive - mixed case query": {
80+
sku: compute.ResourceSku{
81+
Capabilities: &[]compute.ResourceSkuCapabilities{
82+
{
83+
Name: to.StringPtr("maxResourceVolumeMB"),
84+
Value: to.StringPtr("1024"),
85+
},
86+
},
87+
},
88+
capability: "MaxResourceVolumeMb",
89+
expect: 1024,
90+
},
5591
}
5692

5793
for name, tc := range cases {
@@ -78,6 +114,142 @@ func Test_SKU_GetCapabilityQuantity(t *testing.T) {
78114
}
79115
}
80116

117+
func Test_SKU_GetCapabilityFloatQuantity(t *testing.T) {
118+
cases := map[string]struct {
119+
sku compute.ResourceSku
120+
capability string
121+
expect float64
122+
err string
123+
}{
124+
"empty capability list should return capability not found": {
125+
sku: compute.ResourceSku{},
126+
capability: "",
127+
err: (&ErrCapabilityNotFound{""}).Error(),
128+
},
129+
"capability should return successfully with float": {
130+
sku: compute.ResourceSku{
131+
Capabilities: &[]compute.ResourceSkuCapabilities{
132+
{
133+
Name: to.StringPtr("memoryGB"),
134+
Value: to.StringPtr("7.5"),
135+
},
136+
},
137+
},
138+
capability: "memoryGB",
139+
expect: 7.5,
140+
},
141+
"capability name matching should be case insensitive for float": {
142+
sku: compute.ResourceSku{
143+
Capabilities: &[]compute.ResourceSkuCapabilities{
144+
{
145+
Name: to.StringPtr("MemoryGB"),
146+
Value: to.StringPtr("16.0"),
147+
},
148+
},
149+
},
150+
capability: "memorygb",
151+
expect: 16.0,
152+
},
153+
}
154+
155+
for name, tc := range cases {
156+
tc := tc
157+
t.Run(name, func(t *testing.T) {
158+
sku := SKU(tc.sku)
159+
quantity, err := sku.GetCapabilityFloatQuantity(tc.capability)
160+
if tc.err != "" {
161+
if err == nil {
162+
t.Errorf("expected failure with error '%s' but did not occur", tc.err)
163+
}
164+
if diff := cmp.Diff(tc.err, err.Error()); diff != "" {
165+
t.Error(diff)
166+
}
167+
} else {
168+
if err != nil {
169+
t.Errorf("expected success but failure occurred with error '%s'", err)
170+
}
171+
if diff := cmp.Diff(tc.expect, quantity); diff != "" {
172+
t.Error(diff)
173+
}
174+
}
175+
})
176+
}
177+
}
178+
179+
func Test_SKU_GetCapabilityString(t *testing.T) {
180+
cases := map[string]struct {
181+
sku compute.ResourceSku
182+
capability string
183+
expect string
184+
err string
185+
}{
186+
"empty capability list should return capability not found": {
187+
sku: compute.ResourceSku{},
188+
capability: "",
189+
err: (&ErrCapabilityNotFound{""}).Error(),
190+
},
191+
"capability should return successfully with string": {
192+
sku: compute.ResourceSku{
193+
Capabilities: &[]compute.ResourceSkuCapabilities{
194+
{
195+
Name: to.StringPtr("CPUArchitectureType"),
196+
Value: to.StringPtr("x64"),
197+
},
198+
},
199+
},
200+
capability: "CPUArchitectureType",
201+
expect: "x64",
202+
},
203+
"capability name matching should be case insensitive for string": {
204+
sku: compute.ResourceSku{
205+
Capabilities: &[]compute.ResourceSkuCapabilities{
206+
{
207+
Name: to.StringPtr("CPUArchitectureType"),
208+
Value: to.StringPtr("Arm64"),
209+
},
210+
},
211+
},
212+
capability: "cpuarchitecturetype",
213+
expect: "Arm64",
214+
},
215+
"capability name matching should be case insensitive - mixed case string": {
216+
sku: compute.ResourceSku{
217+
Capabilities: &[]compute.ResourceSkuCapabilities{
218+
{
219+
Name: to.StringPtr("hyperVGenerations"),
220+
Value: to.StringPtr("V1,V2"),
221+
},
222+
},
223+
},
224+
capability: "HyperVGenerations",
225+
expect: "V1,V2",
226+
},
227+
}
228+
229+
for name, tc := range cases {
230+
tc := tc
231+
t.Run(name, func(t *testing.T) {
232+
sku := SKU(tc.sku)
233+
result, err := sku.GetCapabilityString(tc.capability)
234+
if tc.err != "" {
235+
if err == nil {
236+
t.Errorf("expected failure with error '%s' but did not occur", tc.err)
237+
}
238+
if diff := cmp.Diff(tc.err, err.Error()); diff != "" {
239+
t.Error(diff)
240+
}
241+
} else {
242+
if err != nil {
243+
t.Errorf("expected success but failure occurred with error '%s'", err)
244+
}
245+
if diff := cmp.Diff(tc.expect, result); diff != "" {
246+
t.Error(diff)
247+
}
248+
}
249+
})
250+
}
251+
}
252+
81253
func Test_SKU_HasCapability(t *testing.T) {
82254
cases := map[string]struct {
83255
sku compute.ResourceSku
@@ -139,6 +311,30 @@ func Test_SKU_HasCapability(t *testing.T) {
139311
capability: "foo",
140312
expect: true,
141313
},
314+
"capability name matching should be case insensitive - uppercase capability": {
315+
sku: compute.ResourceSku{
316+
Capabilities: &[]compute.ResourceSkuCapabilities{
317+
{
318+
Name: to.StringPtr("EncryptionAtHostSupported"),
319+
Value: to.StringPtr("True"),
320+
},
321+
},
322+
},
323+
capability: "encryptionathostsupported",
324+
expect: true,
325+
},
326+
"capability name matching should be case insensitive - mixed case capability": {
327+
sku: compute.ResourceSku{
328+
Capabilities: &[]compute.ResourceSkuCapabilities{
329+
{
330+
Name: to.StringPtr("acceleratednetworkingenabled"),
331+
Value: to.StringPtr("True"),
332+
},
333+
},
334+
},
335+
capability: "AcceleratedNetworkingEnabled",
336+
expect: true,
337+
},
142338
}
143339

144340
for name, tc := range cases {
@@ -557,6 +753,20 @@ func Test_SKU_Includes(t *testing.T) {
557753
},
558754
expect: true,
559755
},
756+
"name matching should be case insensitive": {
757+
skuList: []SKU{
758+
{
759+
Name: to.StringPtr("Standard_D4s_v3"),
760+
},
761+
{
762+
Name: to.StringPtr("Standard_F8s_v2"),
763+
},
764+
},
765+
sku: SKU{
766+
Name: to.StringPtr("standard_d4s_v3"),
767+
},
768+
expect: true,
769+
},
560770
}
561771
for name, tc := range cases {
562772
tc := tc

v2/sku.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func (s *SKU) GetCPUArchitectureType() (string, error) {
145145
// parsed as an integer.
146146
func (s *SKU) GetCapabilityIntegerQuantity(name string) (int64, error) {
147147
for _, capability := range s.Capabilities {
148-
if capability != nil && capability.Name != nil && *capability.Name == name {
148+
if capability != nil && capability.Name != nil && strings.EqualFold(*capability.Name, name) {
149149
if capability.Value != nil {
150150
intVal, err := strconv.ParseInt(*capability.Value, ten, sixtyFour)
151151
if err != nil {
@@ -165,7 +165,7 @@ func (s *SKU) GetCapabilityIntegerQuantity(name string) (int64, error) {
165165
// not be parsed as an integer.
166166
func (s *SKU) GetCapabilityFloatQuantity(name string) (float64, error) {
167167
for _, capability := range s.Capabilities {
168-
if capability != nil && capability.Name != nil && *capability.Name == name {
168+
if capability != nil && capability.Name != nil && strings.EqualFold(*capability.Name, name) {
169169
if capability.Value != nil {
170170
intVal, err := strconv.ParseFloat(*capability.Value, sixtyFour)
171171
if err != nil {
@@ -183,7 +183,7 @@ func (s *SKU) GetCapabilityFloatQuantity(name string) (float64, error) {
183183
// It errors if the capability is not found or the value was nil
184184
func (s *SKU) GetCapabilityString(name string) (string, error) {
185185
for _, capability := range s.Capabilities {
186-
if capability != nil && capability.Name != nil && *capability.Name == name {
186+
if capability != nil && capability.Name != nil && strings.EqualFold(*capability.Name, name) {
187187
if capability.Value != nil {
188188
return *capability.Value, nil
189189
}
@@ -538,7 +538,7 @@ func (s *SKU) Equal(other *SKU) bool {
538538
// MemberOf returns true if the SKU's name is in the list of SKUs.
539539
func (s *SKU) MemberOf(skuList []SKU) bool {
540540
for _, sku := range skuList {
541-
if s.GetName() == sku.GetName() {
541+
if strings.EqualFold(s.GetName(), sku.GetName()) {
542542
return true
543543
}
544544
}

0 commit comments

Comments
 (0)