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 }