Fix: the array type cannot be converted to interface type (#5578)

* Fix: the array type cannot be converted to interface type

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

* Fix: the array type cannot be converted to interface type

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

* Fix: the array type cannot be converted to interface type

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

* Fix: the array type cannot be converted to interface type

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

---------

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
This commit is contained in:
JohnJan
2023-03-01 09:42:05 +08:00
committed by GitHub
parent f454ec34e4
commit 7f54ca96e7
2 changed files with 71 additions and 24 deletions

View File

@@ -18,6 +18,7 @@ package service
import (
"fmt"
"reflect"
)
// guaranteePolicyExist check the slice whether contain the target policy, if not put it in.
@@ -57,16 +58,36 @@ func extractPolicyListAndProperty(property map[string]interface{}) ([]string, ma
if policies == nil {
return nil, property, nil
}
list, ok := policies.([]interface{})
if !ok {
list, err := InterfaceSlice(policies)
if err != nil {
return nil, nil, fmt.Errorf("the policies incorrect")
}
if len(list) == 0 {
return nil, property, nil
}
res := []string{}
var res []string
for _, i := range list {
res = append(res, i.(string))
}
return res, property, nil
}
// InterfaceSlice interface to []interface{}
func InterfaceSlice(slice interface{}) ([]interface{}, error) {
if arr, ok := slice.([]interface{}); ok {
return arr, nil
}
s := reflect.ValueOf(slice)
if s.Kind() != reflect.Slice {
return nil, fmt.Errorf("InterfaceSlice() given a non-slice type")
}
// Keep the distinction between nil and empty slice input
if s.IsNil() {
return nil, nil
}
ret := make([]interface{}, s.Len())
for i := 0; i < s.Len(); i++ {
ret[i] = s.Index(i).Interface()
}
return ret, nil
}

View File

@@ -174,61 +174,87 @@ func TestExtractPolicyListAndProperty(t *testing.T) {
testCases := []struct {
input string
res struct {
policies []string
properties map[string]interface{}
noError bool
policies []string
properties map[string]interface{}
noUnmarshallError bool
noExtractError bool
}
}{
{
input: `{"policies": null, "components": null}`,
res: struct {
policies []string
properties map[string]interface{}
noUnmarshallError bool
noExtractError bool
}{policies: nil, properties: map[string]interface{}{
"policies": nil,
"components": nil,
}, noUnmarshallError: true, noExtractError: true},
},
{
input: `{"policies": "policy1", "components": "comp1"}`,
res: struct {
policies []string
properties map[string]interface{}
noUnmarshallError bool
noExtractError bool
}{policies: nil, properties: nil, noUnmarshallError: true, noExtractError: false},
},
{
input: `{"policies":["policy1","policy2"], "components": ["comp1"]}`,
res: struct {
policies []string
properties map[string]interface{}
noError bool
policies []string
properties map[string]interface{}
noUnmarshallError bool
noExtractError bool
}{policies: []string{"policy1", "policy2"}, properties: map[string]interface{}{
"policies": []interface{}{"policy1", "policy2"},
"components": []interface{}{"comp1"},
}, noError: true},
}, noUnmarshallError: true, noExtractError: true},
},
{
input: `{"policies":["policy1"], "components": ["comp1"]}`,
res: struct {
policies []string
properties map[string]interface{}
noError bool
policies []string
properties map[string]interface{}
noUnmarshallError bool
noExtractError bool
}{policies: []string{"policy1"}, properties: map[string]interface{}{
"policies": []interface{}{"policy1"},
"components": []interface{}{"comp1"},
}, noError: true},
}, noUnmarshallError: true, noExtractError: true},
},
{
input: `{"policies":["policy1", "components": ["comp1"]}`,
res: struct {
policies []string
properties map[string]interface{}
noError bool
}{noError: false},
policies []string
properties map[string]interface{}
noUnmarshallError bool
noExtractError bool
}{noUnmarshallError: false, noExtractError: false},
},
{
input: `{}`,
res: struct {
policies []string
properties map[string]interface{}
noError bool
}{policies: nil, properties: nil, noError: true},
policies []string
properties map[string]interface{}
noUnmarshallError bool
noExtractError bool
}{policies: nil, properties: nil, noUnmarshallError: true, noExtractError: true},
},
}
for _, testCase := range testCases {
var in = map[string]interface{}{}
err := json.Unmarshal([]byte(testCase.input), &in)
if testCase.res.noError {
if testCase.res.noUnmarshallError {
assert.NilError(t, err)
} else {
assert.Equal(t, err != nil, true)
continue
}
policy, properties, err := extractPolicyListAndProperty(in)
if testCase.res.noError {
if testCase.res.noExtractError {
assert.NilError(t, err)
} else {
assert.Equal(t, err != nil, true)