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 }