github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/provider/vsphere/testing_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // +build !gccgo
     5  
     6  package vsphere
     7  
     8  import (
     9  	"net/http"
    10  	"net/http/httptest"
    11  	"net/url"
    12  	"reflect"
    13  
    14  	"github.com/juju/errors"
    15  	"github.com/juju/govmomi"
    16  	"github.com/juju/govmomi/session"
    17  	"github.com/juju/govmomi/vim25"
    18  	"github.com/juju/govmomi/vim25/methods"
    19  	"github.com/juju/govmomi/vim25/soap"
    20  	"github.com/juju/govmomi/vim25/types"
    21  	jc "github.com/juju/testing/checkers"
    22  	"golang.org/x/net/context"
    23  	gc "gopkg.in/check.v1"
    24  
    25  	"github.com/juju/juju/cloud"
    26  	"github.com/juju/juju/environs"
    27  	"github.com/juju/juju/environs/config"
    28  	"github.com/juju/juju/testing"
    29  )
    30  
    31  func ConfigAttrs() testing.Attrs {
    32  	return testing.FakeConfig().Merge(testing.Attrs{
    33  		"type":             "vsphere",
    34  		"uuid":             "2d02eeac-9dbb-11e4-89d3-123b93f75cba",
    35  		"external-network": "",
    36  	})
    37  }
    38  
    39  func FakeCloudSpec() environs.CloudSpec {
    40  	cred := FakeCredential()
    41  	return environs.CloudSpec{
    42  		Type:       "vsphere",
    43  		Name:       "vsphere",
    44  		Region:     "/datacenter1",
    45  		Endpoint:   "host1",
    46  		Credential: &cred,
    47  	}
    48  }
    49  
    50  func FakeCredential() cloud.Credential {
    51  	return cloud.NewCredential(cloud.UserPassAuthType, map[string]string{
    52  		"user":     "user1",
    53  		"password": "password1",
    54  	})
    55  }
    56  
    57  type BaseSuite struct {
    58  	testing.FakeJujuXDGDataHomeSuite
    59  
    60  	Config    *config.Config
    61  	EnvConfig *environConfig
    62  	Env       *environ
    63  
    64  	ServeMux  *http.ServeMux
    65  	ServerURL string
    66  }
    67  
    68  func (s *BaseSuite) SetUpTest(c *gc.C) {
    69  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    70  
    71  	s.PatchValue(&newConnection, newFakeConnection)
    72  	s.initEnv(c)
    73  	s.setUpHTTPProxy(c)
    74  	s.FakeMetadataServer()
    75  }
    76  
    77  func (s *BaseSuite) initEnv(c *gc.C) {
    78  	cfg, err := testing.ModelConfig(c).Apply(ConfigAttrs())
    79  	c.Assert(err, jc.ErrorIsNil)
    80  	env, err := environs.New(environs.OpenParams{
    81  		Cloud:  FakeCloudSpec(),
    82  		Config: cfg,
    83  	})
    84  	c.Assert(err, jc.ErrorIsNil)
    85  	s.Env = env.(*environ)
    86  	s.setConfig(c, cfg)
    87  }
    88  
    89  func (s *BaseSuite) setConfig(c *gc.C, cfg *config.Config) {
    90  	s.Config = cfg
    91  	ecfg, err := newValidConfig(cfg, configDefaults)
    92  	c.Assert(err, jc.ErrorIsNil)
    93  	s.EnvConfig = ecfg
    94  	s.Env.ecfg = s.EnvConfig
    95  }
    96  
    97  func (s *BaseSuite) UpdateConfig(c *gc.C, attrs map[string]interface{}) {
    98  	cfg, err := s.Config.Apply(attrs)
    99  	c.Assert(err, jc.ErrorIsNil)
   100  	s.setConfig(c, cfg)
   101  }
   102  
   103  func (s *BaseSuite) setUpHTTPProxy(c *gc.C) {
   104  	s.ServeMux = http.NewServeMux()
   105  	server := httptest.NewServer(s.ServeMux)
   106  	s.ServerURL = server.URL
   107  	cfg, _ := s.Config.Apply(map[string]interface{}{"image-metadata-url": server.URL})
   108  	s.setConfig(c, cfg)
   109  }
   110  
   111  type fakeAPIHandler func(req, res soap.HasFault)
   112  type fakePropertiesHandler func(req, res *methods.RetrievePropertiesBody)
   113  
   114  type fakeAPICall struct {
   115  	handler fakeAPIHandler
   116  	method  string
   117  }
   118  
   119  type fakePropertiesCall struct {
   120  	handler fakePropertiesHandler
   121  	object  string
   122  }
   123  
   124  type fakeClient struct {
   125  	handlers         []fakeAPICall
   126  	propertyHandlers []fakePropertiesCall
   127  }
   128  
   129  func (c *fakeClient) RoundTrip(ctx context.Context, req, res soap.HasFault) error {
   130  	reqType := reflect.ValueOf(req).Elem().FieldByName("Req").Elem().Type().Name()
   131  
   132  	if reqType == "RetrieveProperties" {
   133  		reqBody := req.(*methods.RetrievePropertiesBody)
   134  		resBody := res.(*methods.RetrievePropertiesBody)
   135  		obj := reqBody.Req.SpecSet[0].ObjectSet[0].Obj.Value
   136  		logger.Debugf("executing RetrieveProperties for object %s", obj)
   137  		call := c.propertyHandlers[0]
   138  		if call.object != obj {
   139  			return errors.Errorf("expected object of type %s, got %s", obj, call.object)
   140  		}
   141  		call.handler(reqBody, resBody)
   142  		c.propertyHandlers = c.propertyHandlers[1:]
   143  	} else {
   144  		logger.Infof("Executing RoundTrip method, type: %s", reqType)
   145  		call := c.handlers[0]
   146  		if call.method != reqType {
   147  			return errors.Errorf("expected method of type %s, got %s", reqType, call.method)
   148  		}
   149  		call.handler(req, res)
   150  		c.handlers = c.handlers[1:]
   151  	}
   152  	return nil
   153  }
   154  
   155  func (c *fakeClient) SetProxyHandler(method string, handler fakeAPIHandler) {
   156  	c.handlers = append(c.handlers, fakeAPICall{method: method, handler: handler})
   157  }
   158  
   159  func (c *fakeClient) SetPropertyProxyHandler(obj string, handler fakePropertiesHandler) {
   160  	c.propertyHandlers = append(c.propertyHandlers, fakePropertiesCall{object: obj, handler: handler})
   161  }
   162  
   163  var newFakeConnection = func(url *url.URL) (*govmomi.Client, error) {
   164  	fakeClient := &fakeClient{
   165  		handlers:         make([]fakeAPICall, 0, 100),
   166  		propertyHandlers: make([]fakePropertiesCall, 0, 100),
   167  	}
   168  
   169  	fakeClient.SetPropertyProxyHandler("FakeRootFolder", RetrieveDatacenter)
   170  
   171  	vimClient := &vim25.Client{
   172  		Client: &soap.Client{},
   173  		ServiceContent: types.ServiceContent{
   174  			RootFolder: types.ManagedObjectReference{
   175  				Type:  "Folder",
   176  				Value: "FakeRootFolder",
   177  			},
   178  			OvfManager: &types.ManagedObjectReference{
   179  				Type:  "OvfManager",
   180  				Value: "FakeOvfManager",
   181  			},
   182  		},
   183  		RoundTripper: fakeClient,
   184  	}
   185  
   186  	c := &govmomi.Client{
   187  		Client:         vimClient,
   188  		SessionManager: session.NewManager(vimClient),
   189  	}
   190  	return c, nil
   191  }
   192  
   193  var CommonRetrieveProperties = func(resBody *methods.RetrievePropertiesBody, objType, objValue, propName string, propValue interface{}) {
   194  	resBody.Res = &types.RetrievePropertiesResponse{
   195  		Returnval: []types.ObjectContent{
   196  			types.ObjectContent{
   197  				Obj: types.ManagedObjectReference{
   198  					Type:  objType,
   199  					Value: objValue,
   200  				},
   201  				PropSet: []types.DynamicProperty{
   202  					types.DynamicProperty{Name: propName, Val: propValue},
   203  				},
   204  			},
   205  		},
   206  	}
   207  }
   208  
   209  var RetrieveDatacenter = func(reqBody, resBody *methods.RetrievePropertiesBody) {
   210  	CommonRetrieveProperties(resBody, "Datacenter", "FakeDatacenter", "name", "datacenter1")
   211  }
   212  
   213  var RetrieveDatacenterProperties = func(reqBody, resBody *methods.RetrievePropertiesBody) {
   214  	resBody.Res = &types.RetrievePropertiesResponse{
   215  		Returnval: []types.ObjectContent{
   216  			types.ObjectContent{
   217  				Obj: types.ManagedObjectReference{
   218  					Type:  "Datacenter",
   219  					Value: "FakeDatacenter",
   220  				},
   221  				PropSet: []types.DynamicProperty{
   222  					types.DynamicProperty{Name: "hostFolder", Val: types.ManagedObjectReference{
   223  						Type:  "Folder",
   224  						Value: "FakeHostFolder",
   225  					}},
   226  					types.DynamicProperty{Name: "vmFolder", Val: types.ManagedObjectReference{
   227  						Type:  "Folder",
   228  						Value: "FakeVmFolder",
   229  					}},
   230  				},
   231  			},
   232  		},
   233  	}
   234  }