github.com/vmware/govmomi@v0.51.0/simulator/example_extend_test.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package simulator_test 6 7 import ( 8 "context" 9 "fmt" 10 "log" 11 12 "github.com/vmware/govmomi" 13 "github.com/vmware/govmomi/object" 14 "github.com/vmware/govmomi/simulator" 15 "github.com/vmware/govmomi/vim25/methods" 16 "github.com/vmware/govmomi/vim25/soap" 17 "github.com/vmware/govmomi/vim25/types" 18 ) 19 20 // BusyVM changes the behavior of simulator.VirtualMachine 21 type BusyVM struct { 22 *simulator.VirtualMachine 23 } 24 25 // Override simulator.VirtualMachine.PowerOffVMTask to inject faults 26 func (vm *BusyVM) PowerOffVMTask(ctx *simulator.Context, req *types.PowerOffVM_Task) soap.HasFault { 27 task := simulator.CreateTask(req.This, "powerOff", func(*simulator.Task) (types.AnyType, types.BaseMethodFault) { 28 return nil, &types.TaskInProgress{} 29 }) 30 31 return &methods.PowerOffVM_TaskBody{ 32 Res: &types.PowerOffVM_TaskResponse{ 33 Returnval: task.Run(ctx), 34 }, 35 } 36 } 37 38 // Add AcquireTicket method, not implemented by simulator.VirtualMachine 39 func (vm *BusyVM) AcquireTicket(req *types.AcquireTicket) soap.HasFault { 40 body := &methods.AcquireTicketBody{} 41 42 if req.TicketType != "mks" { 43 body.Fault_ = simulator.Fault("", &types.InvalidArgument{}) 44 } 45 46 body.Res = &types.AcquireTicketResponse{ 47 Returnval: types.VirtualMachineTicket{ 48 Ticket: "welcome 2 the machine", 49 }, 50 } 51 52 return body 53 } 54 55 // Example of extending the simulator to inject faults. 56 func Example() { 57 ctx := context.Background() 58 model := simulator.VPX() 59 60 defer model.Remove() 61 _ = model.Create() 62 63 s := model.Service.NewServer() 64 defer s.Close() 65 66 // NewClient connects to s.URL over https and invokes 2 SOAP methods (RetrieveServiceContent + Login) 67 c, _ := govmomi.NewClient(ctx, s.URL, true) 68 69 // Shortcut to choose any VM, rather than using the more verbose Finder or ContainerView. 70 obj := model.Map().Any("VirtualMachine").(*simulator.VirtualMachine) 71 // Validate VM is powered on 72 if obj.Runtime.PowerState != "poweredOn" { 73 log.Fatal(obj.Runtime.PowerState) 74 } 75 76 // Wrap the existing vm object, using the same vm.Self (ManagedObjectReference) value as the Map key. 77 model.Map().Put(&BusyVM{obj}) 78 79 vm := object.NewVirtualMachine(c.Client, obj.Reference()) 80 81 // Start a PowerOff task using the SOAP client. 82 task, _ := vm.PowerOff(ctx) 83 84 // Wait for task completion, expecting failure. 85 err := task.Wait(ctx) 86 if err == nil { 87 log.Fatal("expected error") 88 } 89 90 // Invalid ticket type, expecting failure. 91 _, err = vm.AcquireTicket(ctx, "pks") 92 if err == nil { 93 log.Fatal("expected error") 94 } 95 96 mks, _ := vm.AcquireTicket(ctx, "mks") 97 98 fmt.Println(mks.Ticket, obj.Runtime.PowerState) 99 // Output: welcome 2 the machine poweredOn 100 }