Skip to content

Commit

Permalink
vcsim: fix ModifyListView to return unresolved references
Browse files Browse the repository at this point in the history
BREAKING: api: view.ListView.{Add,Remove,Reset} methods now return unresolved references
  • Loading branch information
dougm committed Oct 11, 2023
1 parent 88629ae commit 0754d75
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 35 deletions.
4 changes: 2 additions & 2 deletions simulator/race_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func TestRace(t *testing.T) {
if terr != nil {
t.Error(terr)
}
terr = lv.Add(ctx, []types.ManagedObjectReference{r.Result.(types.ManagedObjectReference)})
_, terr = lv.Add(ctx, []types.ManagedObjectReference{r.Result.(types.ManagedObjectReference)})
if terr != nil {
t.Error(terr)
}
Expand Down Expand Up @@ -221,7 +221,7 @@ func TestRace(t *testing.T) {
time.AfterFunc(100*time.Millisecond, func() {
defer wg.Done()

_ = lv.Remove(ctx, []types.ManagedObjectReference{vm.Reference()})
_, _ = lv.Remove(ctx, []types.ManagedObjectReference{vm.Reference()})
task, _ := vm.PowerOff(ctx)
_ = task.Wait(ctx)
})
Expand Down
38 changes: 18 additions & 20 deletions simulator/view_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ func (m *ViewManager) CreateListView(ctx *Context, req *types.CreateListView) so
body := new(methods.CreateListViewBody)
list := new(ListView)

if err := list.add(ctx, req.Obj); err != nil {
body.Fault_ = Fault("", err)
if refs := list.add(ctx, req.Obj); len(refs) != 0 {
body.Fault_ = Fault("", &types.ManagedObjectNotFound{Obj: refs[0]})
return body
}

Expand All @@ -249,15 +249,16 @@ func (v *ListView) update(ctx *Context) {
ctx.Map.Update(v, []types.PropertyChange{{Name: "view", Val: v.View}})
}

func (v *ListView) add(ctx *Context, refs []types.ManagedObjectReference) *types.ManagedObjectNotFound {
func (v *ListView) add(ctx *Context, refs []types.ManagedObjectReference) []types.ManagedObjectReference {
var unresolved []types.ManagedObjectReference
for _, ref := range refs {
obj := ctx.Session.Get(ref)
if obj == nil {
return &types.ManagedObjectNotFound{Obj: ref}
unresolved = append(unresolved, ref)
}
v.View = append(v.View, ref)
}
return nil
return unresolved
}

func (v *ListView) DestroyView(ctx *Context, c *types.DestroyView) soap.HasFault {
Expand All @@ -266,19 +267,19 @@ func (v *ListView) DestroyView(ctx *Context, c *types.DestroyView) soap.HasFault
}

func (v *ListView) ModifyListView(ctx *Context, req *types.ModifyListView) soap.HasFault {
body := new(methods.ModifyListViewBody)
body := &methods.ModifyListViewBody{
Res: new(types.ModifyListViewResponse),
}

body.Res.Returnval = v.add(ctx, req.Add)

for _, ref := range req.Remove {
RemoveReference(&v.View, ref)
if ctx.Map.Get(ref) == nil {
body.Res.Returnval = append(body.Res.Returnval, ref)
}
}

if err := v.add(ctx, req.Add); err != nil {
body.Fault_ = Fault("", err)
return body
}

body.Res = new(types.ModifyListViewResponse)

if len(req.Remove) != 0 || len(req.Add) != 0 {
v.update(ctx)
}
Expand All @@ -287,16 +288,13 @@ func (v *ListView) ModifyListView(ctx *Context, req *types.ModifyListView) soap.
}

func (v *ListView) ResetListView(ctx *Context, req *types.ResetListView) soap.HasFault {
body := new(methods.ResetListViewBody)
body := &methods.ResetListViewBody{
Res: new(types.ResetListViewResponse),
}

v.View = nil

if err := v.add(ctx, req.Obj); err != nil {
body.Fault_ = Fault("", err)
return body
}

body.Res = new(types.ResetListViewResponse)
body.Res.Returnval = v.add(ctx, req.Obj)

v.update(ctx)

Expand Down
26 changes: 26 additions & 0 deletions simulator/view_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package simulator

import (
"context"
"log"
"sync"
"testing"

Expand Down Expand Up @@ -198,3 +199,28 @@ func TestViewManager_CreateContainerView(t *testing.T) {
t.Errorf("Failed to run simulation: %s", err.Error())
}
}

func TestListViewModify(t *testing.T) {
Test(func(ctx context.Context, c *vim25.Client) {
list, err := view.NewManager(c).CreateListView(ctx, nil)
if err != nil {
log.Fatal(err)
}

defer list.Destroy(ctx)

add := []types.ManagedObjectReference{
c.ServiceContent.RootFolder,
{Type: "Folder", Value: "invalid"},
}

refs, err := list.Add(ctx, add)
if err != nil {
log.Fatal(err)
}

if len(refs) != 1 {
t.Errorf("unresolved refs=%s", refs)
}
})
}
4 changes: 2 additions & 2 deletions view/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func ExampleListView_tasks() {

switch info.State {
case types.TaskInfoStateSuccess, types.TaskInfoStateError:
_ = list.Remove(ctx, []types.ManagedObjectReference{update.Obj})
_, _ = list.Remove(ctx, []types.ManagedObjectReference{update.Obj})
result[info.State]++
n--
wg.Done()
Expand All @@ -228,7 +228,7 @@ func ExampleListView_tasks() {
if err != nil {
return err
}
err = list.Add(ctx, []types.ManagedObjectReference{task.Reference()})
_, err = list.Add(ctx, []types.ManagedObjectReference{task.Reference()})
if err != nil {
return err
}
Expand Down
30 changes: 21 additions & 9 deletions view/list_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,41 @@ func NewListView(c *vim25.Client, ref types.ManagedObjectReference) *ListView {
}
}

func (v ListView) Add(ctx context.Context, refs []types.ManagedObjectReference) error {
func (v ListView) Add(ctx context.Context, refs []types.ManagedObjectReference) ([]types.ManagedObjectReference, error) {
req := types.ModifyListView{
This: v.Reference(),
Add: refs,
}
_, err := methods.ModifyListView(ctx, v.Client(), &req)
return err
res, err := methods.ModifyListView(ctx, v.Client(), &req)
if err != nil {
return nil, err
}

return res.Returnval, nil
}

func (v ListView) Remove(ctx context.Context, refs []types.ManagedObjectReference) error {
func (v ListView) Remove(ctx context.Context, refs []types.ManagedObjectReference) ([]types.ManagedObjectReference, error) {
req := types.ModifyListView{
This: v.Reference(),
Remove: refs,
}
_, err := methods.ModifyListView(ctx, v.Client(), &req)
return err
res, err := methods.ModifyListView(ctx, v.Client(), &req)
if err != nil {
return nil, err
}

return res.Returnval, nil
}

func (v ListView) Reset(ctx context.Context, refs []types.ManagedObjectReference) error {
func (v ListView) Reset(ctx context.Context, refs []types.ManagedObjectReference) ([]types.ManagedObjectReference, error) {
req := types.ResetListView{
This: v.Reference(),
Obj: refs,
}
_, err := methods.ResetListView(ctx, v.Client(), &req)
return err
res, err := methods.ResetListView(ctx, v.Client(), &req)
if err != nil {
return nil, err
}

return res.Returnval, nil
}
4 changes: 2 additions & 2 deletions view/task_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (v TaskView) Collect(ctx context.Context, f func([]types.TaskInfo)) error {
tasks = change.Val.(types.ArrayOfManagedObjectReference).ManagedObjectReference
if len(tasks) != 0 {
reset = func() {
_ = v.Reset(ctx, tasks)
_, _ = v.Reset(ctx, tasks)

// Remember any tasks we've reported as complete already,
// to avoid reporting multiple times when Reset is triggered.
Expand Down Expand Up @@ -113,7 +113,7 @@ func (v TaskView) Collect(ctx context.Context, f func([]types.TaskInfo)) error {
if reset != nil {
reset()
} else if len(prune) != 0 {
_ = v.Remove(ctx, prune)
_, _ = v.Remove(ctx, prune)
}

if len(tasks) != 0 && len(infos) == 0 {
Expand Down

0 comments on commit 0754d75

Please sign in to comment.