Skip to content

Commit

Permalink
fix: handle base types by default in mo.LoadObjectContent
Browse files Browse the repository at this point in the history
Commit 3b7ff25 added support for use of base types with indexed properties.
Enable this by default, so base type fields can be used with any property.
  • Loading branch information
dougm committed Jun 28, 2024
1 parent 71f407c commit 1bc3a4a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 12 deletions.
29 changes: 29 additions & 0 deletions vim25/mo/retrieve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,32 @@ func TestEventReferences(t *testing.T) {
t.Errorf("%d refs", n)
}
}

func TestDatastoreInfoURL(t *testing.T) {
// Datastore.Info is types.BaseDatastoreInfo
// LoadObjectContent() should populate Info with the base type (*types.DatastoreInfo) in this case
content := []types.ObjectContent{
{
Obj: types.ManagedObjectReference{Type: "Datastore", Value: "datastore-48", ServerGUID: ""},
PropSet: []types.DynamicProperty{
{
Name: "info.url",
Val: "ds:///vmfs/volumes/666d7a79-cb0d28b2-57c8-0645602e1b58/",
},
},
MissingSet: nil,
},
}

var ds Datastore

if err := LoadObjectContent(content, &ds); err != nil {
t.Fatal(err)
}

info := ds.Info.GetDatastoreInfo()

if info.Url != content[0].PropSet[0].Val.(string) {
t.Errorf("info.url=%s", info.Url)
}
}
26 changes: 14 additions & 12 deletions vim25/mo/type_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ type typeInfo struct {

// Map property names to field indices.
props map[string][]int

// Use base type for interface indices.
base bool
}

var typeInfoLock sync.RWMutex
Expand Down Expand Up @@ -68,20 +65,22 @@ func typeInfoForType(tname string) *typeInfo {

func baseType(ftyp reflect.Type) reflect.Type {
base := strings.TrimPrefix(ftyp.Name(), "Base")
switch base {
case "MethodFault":
return nil
}
if kind, ok := types.TypeFunc()(base); ok {
return kind
}
return ftyp
return nil
}

func newTypeInfo(typ reflect.Type, base ...bool) *typeInfo {
func newTypeInfo(typ reflect.Type) *typeInfo {
t := typeInfo{
typ: typ,
props: make(map[string][]int),
}
if len(base) == 1 {
t.base = base[0]
}

t.build(typ, "", []int{})

return &t
Expand Down Expand Up @@ -170,13 +169,16 @@ func (t *typeInfo) build(typ reflect.Type, fn string, fi []int) {
t.build(ftyp, fnc, fic)
}

// Base type can only access base fields, for example Datastore.Info
// is types.BaseDataStore, so we create a new(types.DatastoreInfo)
// Indexed property path may traverse into array element fields.
// When interface, use the base type to index fields.
// For example, BaseVirtualDevice:
// config.hardware.device[4000].deviceInfo.label
if t.base && ftyp.Kind() == reflect.Interface {
base := baseType(ftyp)
t.build(base, fnc, fic)
if ftyp.Kind() == reflect.Interface {
if base := baseType(ftyp); base != nil {
t.build(base, fnc, fic)
}
}
}
}
Expand Down Expand Up @@ -283,7 +285,7 @@ func assignValue(val reflect.Value, fi []int, pv reflect.Value, field ...string)
item = reflect.New(rt.Elem())
}

field := newTypeInfo(item.Type(), true)
field := newTypeInfo(item.Type())
if ix, ok := field.props[path]; ok {
assignValue(item, ix, pv)
}
Expand Down

0 comments on commit 1bc3a4a

Please sign in to comment.