Skip to content

Commit

Permalink
Add UT for reflect lib
Browse files Browse the repository at this point in the history
Signed-off-by: Shawn Wang <[email protected]>
  • Loading branch information
wsquan171 committed May 31, 2024
1 parent 65f673f commit 6326d26
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 3 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/google/uuid v1.3.0
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0
github.com/stretchr/testify v1.7.2
github.com/vmware/go-vmware-nsxt v0.0.0-20220328155605-f49a14c1ef5f
github.com/vmware/vsphere-automation-sdk-go/lib v0.7.0
github.com/vmware/vsphere-automation-sdk-go/runtime v0.7.0
Expand All @@ -22,6 +23,7 @@ require (
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/beevik/etree v1.1.0 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/gibson042/canonicaljson-go v1.0.3 // indirect
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
Expand Down Expand Up @@ -53,6 +55,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
Expand All @@ -67,4 +70,5 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
11 changes: 8 additions & 3 deletions nsxt/metadata/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ func StructToSchema(elem reflect.Value, d *schema.ResourceData, metadata map[str
if len(parent) > 0 {
log.Printf("[INFO] parent %s key %s", parent, key)
}
if elem.FieldByName(item.Metadata.SdkFieldName).IsNil() {
log.Printf("[INFO] skip key %s with nil value", key)
continue
}
if item.Metadata.SchemaType == "struct" {
nestedObj := elem.FieldByName(item.Metadata.SdkFieldName)
nestedSchema := make(map[string]interface{})
Expand All @@ -105,10 +109,10 @@ func StructToSchema(elem reflect.Value, d *schema.ResourceData, metadata map[str
}
} else {
if len(parent) > 0 {
log.Printf("[INFO] assigning nested value %v to %s", elem.FieldByName(item.Metadata.SdkFieldName).Interface(), key)
log.Printf("[INFO] assigning nested value %+v to %s", elem.FieldByName(item.Metadata.SdkFieldName).Interface(), key)
parentMap[key] = elem.FieldByName(item.Metadata.SdkFieldName).Interface()
} else {
log.Printf("[INFO] assigning value %v to %s", elem.FieldByName(item.Metadata.SdkFieldName).Interface(), key)
log.Printf("[INFO] assigning value %+v to %s", elem.FieldByName(item.Metadata.SdkFieldName).Interface(), key)
d.Set(key, elem.FieldByName(item.Metadata.SdkFieldName).Interface())
}
}
Expand All @@ -127,7 +131,7 @@ func SchemaToStruct(elem reflect.Value, d *schema.ResourceData, metadata map[str
continue
}

log.Printf("[INFO] inspecting key %s", key)
log.Printf("[INFO] inspecting key %s with type %s", key, item.Metadata.SchemaType)
if len(parent) > 0 {
log.Printf("[INFO] parent %s key %s", parent, key)
}
Expand Down Expand Up @@ -174,6 +178,7 @@ func SchemaToStruct(elem reflect.Value, d *schema.ResourceData, metadata map[str
nestedSchema := nestedSchemaList[0].(map[string]interface{})

childElem := item.Schema.Elem.(*ExtendedResource)
log.Printf("[INFO] calling recur %s", key)
SchemaToStruct(nestedObj.Elem(), d, childElem.Schema, key, nestedSchema)
log.Printf("[INFO] assigning struct %v to %s", nestedObj, key)
elem.FieldByName(item.Metadata.SdkFieldName).Set(nestedObj)
Expand Down
165 changes: 165 additions & 0 deletions nsxt/metadata/metadata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package metadata

import (
"reflect"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/stretchr/testify/assert"
)

type testStruct struct {
StringField *string
BoolField *bool
IntField *int64
StructField *testNestedStruct
}

type testNestedStruct struct {
StringField *string
BoolField *bool
IntField *int64
}

var testSchema = map[string]*schema.Schema{
"string_field": {
Type: schema.TypeString,
},
"bool_field": {
Type: schema.TypeBool,
},
"int_field": {
Type: schema.TypeInt,
},
"struct_field": {
Type: schema.TypeList,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"string_field": {
Type: schema.TypeString,
},
"bool_field": {
Type: schema.TypeBool,
},
"int_field": {
Type: schema.TypeInt,
},
},
},
},
}

func basicStringSchema() *ExtendedSchema {
return &ExtendedSchema{
Schema: schema.Schema{
Type: schema.TypeString,
},
Metadata: Metadata{
SchemaType: "string",
SdkFieldName: "StringField",
},
}
}

func basicBoolSchema() *ExtendedSchema {
return &ExtendedSchema{
Schema: schema.Schema{
Type: schema.TypeBool,
},
Metadata: Metadata{
SchemaType: "bool",
SdkFieldName: "BoolField",
},
}
}

func basicIntSchema() *ExtendedSchema {
return &ExtendedSchema{
Schema: schema.Schema{
Type: schema.TypeInt,
},
Metadata: Metadata{
SchemaType: "int",
SdkFieldName: "IntField",
},
}
}

var testExtendedSchema = map[string]*ExtendedSchema{
"string_field": basicStringSchema(),
"bool_field": basicBoolSchema(),
"int_field": basicIntSchema(),
"struct_field": {
Schema: schema.Schema{
Type: schema.TypeList,
MaxItems: 1,
Elem: &ExtendedResource{
Schema: map[string]*ExtendedSchema{
"string_field": basicStringSchema(),
"bool_field": basicBoolSchema(),
"int_field": basicIntSchema(),
},
},
},
Metadata: Metadata{
SchemaType: "struct",
SdkFieldName: "StructField",
ReflectType: reflect.TypeOf(testNestedStruct{}),
},
},
}

func TestStructToSchema(t *testing.T) {
testStr := "test_string"
testBool := true
testInt := int64(123)
obj := testStruct{
StringField: &testStr,
BoolField: &testBool,
IntField: &testInt,
StructField: &testNestedStruct{
StringField: &testStr,
BoolField: &testBool,
IntField: &testInt,
},
}
d := schema.TestResourceDataRaw(
t, testSchema, map[string]interface{}{})

elem := reflect.ValueOf(&obj).Elem()
StructToSchema(elem, d, testExtendedSchema, "", nil)
assert.Equal(t, "test_string", d.Get("string_field").(string))
assert.Equal(t, true, d.Get("bool_field").(bool))
assert.Equal(t, 123, d.Get("int_field").(int))
nestedObj := d.Get("struct_field").([]interface{})[0].(map[string]interface{})
assert.Equal(t, "test_string", nestedObj["string_field"].(string))
assert.Equal(t, true, nestedObj["bool_field"].(bool))
assert.Equal(t, 123, nestedObj["int_field"].(int))
}

func TestSchemaToStruct(t *testing.T) {
d := schema.TestResourceDataRaw(
t, testSchema, map[string]interface{}{
"string_field": "test_string",
"bool_field": true,
"int_field": 100,
"struct_field": []interface{}{
map[string]interface{}{
"string_field": "nested_string",
"bool_field": true,
"int_field": 1,
},
},
})

obj := testStruct{}
elem := reflect.ValueOf(&obj).Elem()
SchemaToStruct(elem, d, testExtendedSchema, "", nil)
assert.Equal(t, "test_string", *obj.StringField)
assert.Equal(t, true, *obj.BoolField)
assert.Equal(t, int64(100), *obj.IntField)
assert.Equal(t, "nested_string", *obj.StructField.StringField)
assert.Equal(t, true, *obj.StructField.BoolField)
assert.Equal(t, int64(1), *obj.StructField.IntField)
}

0 comments on commit 6326d26

Please sign in to comment.