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  }