From 76f376a3563fcb144523137b8bbfbc4e8c495b6a Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Tue, 12 Dec 2017 12:35:27 -0800 Subject: [PATCH] vcsim: workaround xml ns issue with pyvsphere (#958) Fixes #945 --- simulator/property_collector_test.go | 164 +++++++++++++++++++++++++++ simulator/simulator.go | 18 ++- simulator/simulator_test.go | 2 +- 3 files changed, 182 insertions(+), 2 deletions(-) diff --git a/simulator/property_collector_test.go b/simulator/property_collector_test.go index f99fb1956..ea545ab12 100644 --- a/simulator/property_collector_test.go +++ b/simulator/property_collector_test.go @@ -891,3 +891,167 @@ func TestPropertyCollectorSelectionSpec(t *testing.T) { t.Fatalf("len(content)=%d", len(content)) } } + +func TestIssue945(t *testing.T) { + // pyvsphere request + xml := ` + + + + + propertyCollector + + + VirtualMachine + name + + + group-d1 + false + + visitFolders + Folder + childEntity + false + + visitFolders + + + dcToHf + + + dcToVmf + + + crToH + + + crToRp + + + dcToDs + + + hToVm + + + rpToVm + + + + dcToVmf + Datacenter + vmFolder + false + + visitFolders + + + + dcToDs + Datacenter + datastore + false + + visitFolders + + + + dcToHf + Datacenter + hostFolder + false + + visitFolders + + + + crToH + ComputeResource + host + false + + + crToRp + ComputeResource + resourcePool + false + + rpToRp + + + rpToVm + + + + rpToRp + ResourcePool + resourcePool + false + + rpToRp + + + rpToVm + + + + hToVm + HostSystem + vm + false + + visitFolders + + + + rpToVm + ResourcePool + vm + false + + + + + + +` + + method, err := UnmarshalBody([]byte(xml)) + if err != nil { + t.Fatal(err) + } + + req := method.Body.(*types.RetrievePropertiesEx) + + ctx := context.Background() + + m := VPX() + + defer m.Remove() + + err = m.Create() + if err != nil { + t.Fatal(err) + } + + s := m.Service.NewServer() + defer s.Close() + + client, err := govmomi.NewClient(ctx, s.URL, true) + if err != nil { + t.Fatal(err) + } + + res, err := methods.RetrievePropertiesEx(ctx, client, req) + if err != nil { + t.Fatal(err) + } + + content := res.Returnval.Objects + count := m.Count() + + if len(content) != count.Machine { + t.Fatalf("len(content)=%d", len(content)) + } +} diff --git a/simulator/simulator.go b/simulator/simulator.go index 9a9cf0194..18ad929f7 100644 --- a/simulator/simulator.go +++ b/simulator/simulator.go @@ -491,7 +491,23 @@ func (s *Server) Close() { } } -var typeFunc = types.TypeFunc() +var ( + vim25MapType = types.TypeFunc() + typeFunc = defaultMapType +) + +func defaultMapType(name string) (reflect.Type, bool) { + typ, ok := vim25MapType(name) + if !ok { + // See TestIssue945, in which case Go does not resolve the namespace and name == "ns1:TraversalSpec" + // Without this hack, the SelectSet would be all nil's + kind := strings.SplitN(name, ":", 2) + if len(kind) == 2 { + typ, ok = vim25MapType(kind[1]) + } + } + return typ, ok +} // UnmarshalBody extracts the Body from a soap.Envelope and unmarshals to the corresponding govmomi type func UnmarshalBody(data []byte) (*Method, error) { diff --git a/simulator/simulator_test.go b/simulator/simulator_test.go index a4fafd6e3..b825269e4 100644 --- a/simulator/simulator_test.go +++ b/simulator/simulator_test.go @@ -197,7 +197,7 @@ func TestUnmarshalError(t *testing.T) { } defer func() { - typeFunc = types.TypeFunc() // reset + typeFunc = defaultMapType // reset }() ttypes := map[string]reflect.Type{