github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/vsphere/internal/vsphereclient/mock_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package vsphereclient 5 6 import ( 7 "context" 8 9 "github.com/juju/errors" 10 "github.com/juju/loggo" 11 "github.com/juju/testing" 12 "github.com/juju/utils" 13 "github.com/vmware/govmomi/vim25/methods" 14 "github.com/vmware/govmomi/vim25/soap" 15 "github.com/vmware/govmomi/vim25/types" 16 ) 17 18 var logger = loggo.GetLogger("vsphereclient") 19 20 var ( 21 lease = types.ManagedObjectReference{ 22 Type: "Lease", 23 Value: "FakeLease", 24 } 25 reconfigVMTask = types.ManagedObjectReference{ 26 Type: "Task", 27 Value: "ReconfigVMTask", 28 } 29 destroyTask = types.ManagedObjectReference{ 30 Type: "Task", 31 Value: "DestroyTask", 32 } 33 moveIntoFolderTask = types.ManagedObjectReference{ 34 Type: "Task", 35 Value: "MoveIntoFolder", 36 } 37 powerOffVMTask = types.ManagedObjectReference{ 38 Type: "Task", 39 Value: "PowerOffVM", 40 } 41 powerOnVMTask = types.ManagedObjectReference{ 42 Type: "Task", 43 Value: "PowerOnVM", 44 } 45 cloneVMTask = types.ManagedObjectReference{ 46 Type: "Task", 47 Value: "CloneVM", 48 } 49 searchDatastoreTask = types.ManagedObjectReference{ 50 Type: "Task", 51 Value: "SearchDatastore", 52 } 53 deleteDatastoreFileTask = types.ManagedObjectReference{ 54 Type: "Task", 55 Value: "DeleteDatastoreFile", 56 } 57 moveDatastoreFileTask = types.ManagedObjectReference{ 58 Type: "Task", 59 Value: "MoveDatastoreFile", 60 } 61 extendVirtualDiskTask = types.ManagedObjectReference{ 62 Type: "Task", 63 Value: "ExtendVirtualDisk", 64 } 65 ) 66 67 type mockRoundTripper struct { 68 testing.Stub 69 70 serverURL string 71 roundTrip func(ctx context.Context, req, res soap.HasFault) error 72 contents map[string][]types.ObjectContent 73 collectors map[string]*collector 74 importVAppResult types.ManagedObjectReference 75 taskError map[types.ManagedObjectReference]*types.LocalizedMethodFault 76 taskResult map[types.ManagedObjectReference]types.AnyType 77 } 78 79 func (r *mockRoundTripper) RoundTrip(ctx context.Context, req, res soap.HasFault) error { 80 if err := r.NextErr(); err != nil { 81 return err 82 } 83 84 if r.roundTrip != nil { 85 return r.roundTrip(ctx, req, res) 86 } 87 88 switch res := res.(type) { 89 case *methods.RetrievePropertiesBody: 90 req := req.(*methods.RetrievePropertiesBody).Req 91 res.Res = r.retrieveProperties(req) 92 case *methods.LogoutBody: 93 r.MethodCall(r, "Logout") 94 res.Res = &types.LogoutResponse{} 95 case *methods.ReconfigVM_TaskBody: 96 r.MethodCall(r, "ReconfigVM_Task") 97 res.Res = &types.ReconfigVM_TaskResponse{reconfigVMTask} 98 case *methods.Destroy_TaskBody: 99 r.MethodCall(r, "Destroy_Task") 100 res.Res = &types.Destroy_TaskResponse{destroyTask} 101 case *methods.MoveIntoFolder_TaskBody: 102 r.MethodCall(r, "MoveIntoFolder_Task") 103 res.Res = &types.MoveIntoFolder_TaskResponse{moveIntoFolderTask} 104 case *methods.PowerOffVM_TaskBody: 105 r.MethodCall(r, "PowerOffVM_Task") 106 res.Res = &types.PowerOffVM_TaskResponse{powerOffVMTask} 107 case *methods.PowerOnVM_TaskBody: 108 r.MethodCall(r, "PowerOnVM_Task") 109 res.Res = &types.PowerOnVM_TaskResponse{powerOnVMTask} 110 case *methods.CloneVM_TaskBody: 111 r.MethodCall(r, "CloneVM_Task") 112 res.Res = &types.CloneVM_TaskResponse{cloneVMTask} 113 case *methods.CreateFolderBody: 114 r.MethodCall(r, "CreateFolder") 115 res.Res = &types.CreateFolderResponse{} 116 case *methods.CreateImportSpecBody: 117 req := req.(*methods.CreateImportSpecBody).Req 118 r.MethodCall(r, "CreateImportSpec", req.OvfDescriptor, req.Datastore, req.Cisp) 119 res.Res = &types.CreateImportSpecResponse{ 120 types.OvfCreateImportSpecResult{ 121 FileItem: []types.OvfFileItem{ 122 { 123 DeviceId: "key1", 124 Path: "ubuntu-14.04-server-cloudimg-amd64.vmdk", 125 Size: 14, 126 }, 127 }, 128 ImportSpec: &types.VirtualMachineImportSpec{ 129 ConfigSpec: types.VirtualMachineConfigSpec{ 130 Name: "vm-name", 131 }, 132 }, 133 }, 134 } 135 case *methods.ImportVAppBody: 136 req := req.(*methods.ImportVAppBody).Req 137 r.MethodCall(r, "ImportVApp", req.Spec) 138 res.Res = &types.ImportVAppResponse{lease} 139 case *methods.SearchDatastore_TaskBody: 140 req := req.(*methods.SearchDatastore_TaskBody).Req 141 r.MethodCall(r, "SearchDatastore", req.DatastorePath, req.SearchSpec) 142 res.Res = &types.SearchDatastore_TaskResponse{searchDatastoreTask} 143 case *methods.DeleteDatastoreFile_TaskBody: 144 req := req.(*methods.DeleteDatastoreFile_TaskBody).Req 145 r.MethodCall(r, "DeleteDatastoreFile", req.Name) 146 res.Res = &types.DeleteDatastoreFile_TaskResponse{deleteDatastoreFileTask} 147 case *methods.MoveDatastoreFile_TaskBody: 148 req := req.(*methods.MoveDatastoreFile_TaskBody).Req 149 r.MethodCall(r, "MoveDatastoreFile", req.SourceName, req.DestinationName, req.Force) 150 res.Res = &types.MoveDatastoreFile_TaskResponse{moveDatastoreFileTask} 151 case *methods.MakeDirectoryBody: 152 req := req.(*methods.MakeDirectoryBody).Req 153 r.MethodCall(r, "MakeDirectory", req.Name) 154 res.Res = &types.MakeDirectoryResponse{} 155 case *methods.ExtendVirtualDisk_TaskBody: 156 req := req.(*methods.ExtendVirtualDisk_TaskBody).Req 157 r.MethodCall(r, "ExtendVirtualDisk", req.Name, req.NewCapacityKb) 158 res.Res = &types.ExtendVirtualDisk_TaskResponse{extendVirtualDiskTask} 159 case *methods.CreatePropertyCollectorBody: 160 r.MethodCall(r, "CreatePropertyCollector") 161 uuid := utils.MustNewUUID().String() 162 r.collectors[uuid] = &collector{} 163 res.Res = &types.CreatePropertyCollectorResponse{ 164 Returnval: types.ManagedObjectReference{ 165 Type: "PropertyCollector", 166 Value: uuid, 167 }, 168 } 169 case *methods.CreateFilterBody: 170 r.MethodCall(r, "CreateFilter") 171 req := req.(*methods.CreateFilterBody).Req 172 r.collectors[req.This.Value].filter = req.Spec 173 res.Res = &types.CreateFilterResponse{ 174 Returnval: req.Spec.ObjectSet[0].Obj, 175 } 176 case *methods.HttpNfcLeaseCompleteBody: 177 req := req.(*methods.HttpNfcLeaseCompleteBody).Req 178 r.MethodCall(r, "HttpNfcLeaseComplete", req.This.Value) 179 delete(r.collectors, req.This.Value) 180 res.Res = &types.HttpNfcLeaseCompleteResponse{} 181 case *methods.WaitForUpdatesExBody: 182 r.MethodCall(r, "WaitForUpdatesEx") 183 req := req.(*methods.WaitForUpdatesExBody).Req 184 collector := r.collectors[req.This.Value] 185 186 var changes []types.PropertyChange 187 if collector.filter.ObjectSet[0].Obj == lease { 188 changes = []types.PropertyChange{{ 189 Name: "info", 190 Val: types.HttpNfcLeaseInfo{ 191 Entity: r.importVAppResult, 192 DeviceUrl: []types.HttpNfcLeaseDeviceUrl{ 193 { 194 ImportKey: "key1", 195 Url: r.serverURL + "/disk-device/", 196 }, 197 }, 198 }, 199 }, { 200 Name: "state", 201 Val: types.HttpNfcLeaseStateReady, 202 }} 203 } else { 204 task := collector.filter.ObjectSet[0].Obj 205 taskState := types.TaskInfoStateSuccess 206 taskResult := r.taskResult[task] 207 taskError := r.taskError[task] 208 if taskError != nil { 209 taskState = types.TaskInfoStateError 210 } 211 changes = []types.PropertyChange{{ 212 Name: "info", 213 Op: types.PropertyChangeOpAssign, 214 Val: types.TaskInfo{ 215 Entity: &types.ManagedObjectReference{}, 216 State: taskState, 217 Result: taskResult, 218 Error: taskError, 219 }, 220 }} 221 } 222 res.Res = &types.WaitForUpdatesExResponse{ 223 Returnval: &types.UpdateSet{ 224 FilterSet: []types.PropertyFilterUpdate{{ 225 ObjectSet: []types.ObjectUpdate{{ 226 Obj: collector.filter.ObjectSet[0].Obj, 227 ChangeSet: changes, 228 }}, 229 }}, 230 }, 231 } 232 233 default: 234 return errors.Errorf("unknown type %T", res) 235 } 236 return nil 237 } 238 239 func (r *mockRoundTripper) retrieveProperties(req *types.RetrieveProperties) *types.RetrievePropertiesResponse { 240 spec := req.SpecSet[0] 241 var args []interface{} 242 for _, obj := range spec.ObjectSet { 243 args = append(args, obj.Obj.Value) 244 } 245 r.MethodCall(r, "RetrieveProperties", args...) 246 logger.Debugf("RetrieveProperties for %s", args) 247 var contents []types.ObjectContent 248 for _, obj := range spec.ObjectSet { 249 for _, content := range r.contents[obj.Obj.Value] { 250 var match bool 251 for _, prop := range spec.PropSet { 252 if prop.Type == content.Obj.Type { 253 match = true 254 break 255 } 256 } 257 if match { 258 contents = append(contents, content) 259 } 260 } 261 } 262 return &types.RetrievePropertiesResponse{contents} 263 } 264 265 func retrievePropertiesStubCall(objs ...string) testing.StubCall { 266 args := make([]interface{}, len(objs)) 267 for i, obj := range objs { 268 args[i] = obj 269 } 270 return testing.StubCall{"RetrieveProperties", args} 271 } 272 273 type collector struct { 274 filter types.PropertyFilterSpec 275 }