Skip to content

Commit

Permalink
Add more helper functions in topologymutation variables.go
Browse files Browse the repository at this point in the history
  • Loading branch information
lubronzhan committed Nov 3, 2023
1 parent 8bef2f3 commit d263ca5
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 1 deletion.
45 changes: 45 additions & 0 deletions exp/runtime/topologymutation/variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ limitations under the License.
package topologymutation

import (
"encoding/json"
"strconv"
"strings"

"github.com/pkg/errors"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"

patchvariables "sigs.k8s.io/cluster-api/internal/controllers/topology/cluster/patches/variables"
Expand Down Expand Up @@ -53,3 +56,45 @@ func GetStringVariable(templateVariables map[string]apiextensionsv1.JSON, variab
}
return stringValue, true, nil
}

// GetBoolVariable get the value as a bool.
func GetBoolVariable(templateVariables map[string]apiextensionsv1.JSON, variableName string) (bool, bool, error) {
value, found, err := GetVariable(templateVariables, variableName)
if !found || err != nil {
return false, found, err
}

// Unquote the JSON string.
stringValue, err := strconv.Unquote(string(value.Raw))
if err != nil {
return false, true, err
}
// Parse the JSON bool.
boolValue, err := strconv.ParseBool(stringValue)
if err != nil {
return false, true, err
}
return boolValue, true, nil
}

// GetVariableObject returns unmarshaled object with type passed in v interface{}

Check failure on line 80 in exp/runtime/topologymutation/variables.go

View workflow job for this annotation

GitHub Actions / lint

Comment should end in a period (godot)

Check failure on line 80 in exp/runtime/topologymutation/variables.go

View workflow job for this annotation

GitHub Actions / lint

Comment should end in a period (godot)
func GetVariableObject(templateVariables map[string]apiextensionsv1.JSON, variableName string, v interface{}) (bool, error) {
value, found, err := GetVariable(templateVariables, variableName)
if err != nil {
return false, err
}
if !found {
return false, nil
}

if err := json.Unmarshal(sanitizeJson(value.Raw), v); err != nil {
return false, errors.Wrapf(err, "failed to unmarshal variable json %q into %q", string(value.Raw), v)
}

return true, nil
}

func sanitizeJson(input []byte) (output []byte) {

Check failure on line 97 in exp/runtime/topologymutation/variables.go

View workflow job for this annotation

GitHub Actions / lint

var-naming: func sanitizeJson should be sanitizeJSON (revive)

Check warning on line 97 in exp/runtime/topologymutation/variables.go

View workflow job for this annotation

GitHub Actions / lint

var-naming: func sanitizeJson should be sanitizeJSON (revive)
output = []byte(strings.ReplaceAll(string(input), "\\", ""))
return output
}
148 changes: 147 additions & 1 deletion exp/runtime/topologymutation/variables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

. "github.com/onsi/gomega"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/utils/pointer"
)

func Test_GetRawTemplateVariable(t *testing.T) {
Expand Down Expand Up @@ -106,7 +107,7 @@ func Test_GetStringTemplateVariable(t *testing.T) {
expectedErr: false,
},
{
name: "variable not found",
name: "valid variable",
variables: map[string]apiextensionsv1.JSON{
"a": varA,
},
Expand All @@ -130,3 +131,148 @@ func Test_GetStringTemplateVariable(t *testing.T) {
})
}
}

func Test_GetBoolVariable(t *testing.T) {
g := NewWithT(t)

varA := apiextensionsv1.JSON{Raw: toJSON("true")}
tests := []struct {
name string
variables map[string]apiextensionsv1.JSON
variableName string
expectedValue bool
expectedFound bool
expectedErr bool
}{
{
name: "Fails for invalid variable reference",
variables: nil,
variableName: "invalid[",
expectedValue: false,
expectedFound: false,
expectedErr: true,
},
{
name: "variable not found",
variables: nil,
variableName: "notEsists",
expectedValue: false,
expectedFound: false,
expectedErr: false,
},
{
name: "valid variable",
variables: map[string]apiextensionsv1.JSON{
"a": varA,
},
variableName: "a",
expectedValue: true,
expectedFound: true,
expectedErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
value, found, err := GetBoolVariable(tt.variables, tt.variableName)
if tt.expectedErr {
g.Expect(err).To(HaveOccurred())
} else {
g.Expect(err).ToNot(HaveOccurred())
}
g.Expect(value).To(Equal(tt.expectedValue))
g.Expect(found).To(Equal(tt.expectedFound))

Check failure on line 184 in exp/runtime/topologymutation/variables_test.go

View workflow job for this annotation

GitHub Actions / lint

unnecessary trailing newline (whitespace)
})
}
}

func Test_GetVariableObjectWithNestedType(t *testing.T) {
type AddressesFromPool struct {
ApiGroup string `json:"apiGroup"`

Check failure on line 191 in exp/runtime/topologymutation/variables_test.go

View workflow job for this annotation

GitHub Actions / lint

var-naming: struct field ApiGroup should be APIGroup (revive)

Check warning on line 191 in exp/runtime/topologymutation/variables_test.go

View workflow job for this annotation

GitHub Actions / lint

var-naming: struct field ApiGroup should be APIGroup (revive)
Kind string `json:"kind"`
Name string `json:"name"`
}
type Network struct {
AddressesFromPools *[]AddressesFromPool `json:"addressesFromPools,omitempty"`
Ipv6Primary *bool `json:"ipv6Primary,omitempty"`
}

g := NewWithT(t)

tests := []struct {
name string
variables map[string]apiextensionsv1.JSON
variableName string
expectedValue bool
expectedFound bool
expectedErr bool
object Network
expepctedVariableObject interface{}
}{
{
name: "Fails for invalid variable reference",
variables: nil,
variableName: "invalid[",
expectedValue: false,
expectedFound: false,
object: Network{},
expepctedVariableObject: Network{},
expectedErr: true,
},
{
name: "variable not found",
variables: nil,
variableName: "notEsists",
expectedValue: false,
expectedFound: false,
object: Network{},
expepctedVariableObject: Network{},
expectedErr: false,
},
{
name: "unmarshal error",
variables: map[string]apiextensionsv1.JSON{
"node": {Raw: []byte(`{"name": "aadfasdfasd`)},
"network": {Raw: []byte(`{"ipv6Primary": true, "addressesFromPools":[{"name":"name"}]asdfasdf`)},
},
variableName: "network",
expectedValue: false,
expectedFound: false,
object: Network{},
expepctedVariableObject: Network{},
expectedErr: true,
},
{
name: "valid variable",
variables: map[string]apiextensionsv1.JSON{
"node": {Raw: []byte(`{"name": "a"}`)},
"network": {Raw: []byte(`{"ipv6Primary": true, "addressesFromPools":[{"name":"name"}]}`)},
},
variableName: "network",
expectedValue: true,
expectedFound: true,
expectedErr: false,
object: Network{},
expepctedVariableObject: Network{
Ipv6Primary: pointer.Bool(true),
AddressesFromPools: &[]AddressesFromPool{
{
Name: "name",
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
found, err := GetVariableObject(tt.variables, tt.variableName, &tt.object)
if tt.expectedErr {
g.Expect(err).To(HaveOccurred())
} else {
g.Expect(err).ToNot(HaveOccurred())
}
g.Expect(tt.object).To(Equal(tt.expepctedVariableObject))
g.Expect(found).To(Equal(tt.expectedFound))
})
}
}

0 comments on commit d263ca5

Please sign in to comment.