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