github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/environs/configstore/cachefile_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package configstore_test 5 6 import ( 7 "fmt" 8 "path/filepath" 9 10 "github.com/juju/juju/testing" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/environs/configstore" 15 "github.com/juju/juju/feature" 16 ) 17 18 var _ = gc.Suite(&cacheFileInterfaceSuite{}) 19 20 type cacheFileInterfaceSuite struct { 21 interfaceSuite 22 dir string 23 store configstore.Storage 24 } 25 26 func (s *cacheFileInterfaceSuite) SetUpTest(c *gc.C) { 27 s.interfaceSuite.SetUpTest(c) 28 s.SetFeatureFlags(feature.JES) 29 s.dir = c.MkDir() 30 s.NewStore = func(c *gc.C) configstore.Storage { 31 store, err := configstore.NewDisk(s.dir) 32 c.Assert(err, jc.ErrorIsNil) 33 return store 34 } 35 s.store = s.NewStore(c) 36 } 37 38 func (s *cacheFileInterfaceSuite) writeEnv(c *gc.C, name, envUUID, srvUUID, user, password string) configstore.EnvironInfo { 39 info := s.store.CreateInfo(name) 40 info.SetAPIEndpoint(configstore.APIEndpoint{ 41 Addresses: []string{"address1", "address2"}, 42 Hostnames: []string{"hostname1", "hostname2"}, 43 CACert: testing.CACert, 44 EnvironUUID: envUUID, 45 ServerUUID: srvUUID, 46 }) 47 info.SetAPICredentials(configstore.APICredentials{ 48 User: user, 49 Password: password, 50 }) 51 err := info.Write() 52 c.Assert(err, jc.ErrorIsNil) 53 return info 54 } 55 56 func (s *cacheFileInterfaceSuite) TestServerUUIDWrite(c *gc.C) { 57 envUUID := testing.EnvironmentTag.Id() 58 info := s.writeEnv(c, "testing", envUUID, envUUID, "tester", "secret") 59 60 // Now make sure the cache file exists and the jenv doesn't 61 envDir := filepath.Join(s.dir, "environments") 62 filename := configstore.CacheFilename(envDir) 63 c.Assert(info.Location(), gc.Equals, fmt.Sprintf("file %q", filename)) 64 65 cache := s.readCacheFile(c) 66 c.Assert(cache.Server, gc.HasLen, 1) 67 c.Assert(cache.ServerData, gc.HasLen, 1) 68 c.Assert(cache.Environment, gc.HasLen, 1) 69 } 70 71 func (s *cacheFileInterfaceSuite) TestServerEnvNameExists(c *gc.C) { 72 envUUID := testing.EnvironmentTag.Id() 73 s.writeEnv(c, "testing", envUUID, envUUID, "tester", "secret") 74 75 info := s.store.CreateInfo("testing") 76 // In order to trigger the writing to the cache file, we need to store 77 // a server uuid. 78 info.SetAPIEndpoint(configstore.APIEndpoint{ 79 EnvironUUID: envUUID, 80 ServerUUID: envUUID, 81 }) 82 err := info.Write() 83 c.Assert(err, gc.ErrorMatches, "environment info already exists") 84 } 85 86 func (s *cacheFileInterfaceSuite) TestWriteServerOnly(c *gc.C) { 87 envUUID := testing.EnvironmentTag.Id() 88 s.writeEnv(c, "testing", "", envUUID, "tester", "secret") 89 cache := s.readCacheFile(c) 90 c.Assert(cache.Server, gc.HasLen, 1) 91 c.Assert(cache.ServerData, gc.HasLen, 1) 92 c.Assert(cache.Environment, gc.HasLen, 0) 93 } 94 95 func (s *cacheFileInterfaceSuite) TestWriteEnvAfterServer(c *gc.C) { 96 envUUID := testing.EnvironmentTag.Id() 97 s.writeEnv(c, "testing", "", envUUID, "tester", "secret") 98 info := s.store.CreateInfo("testing") 99 100 info.SetAPIEndpoint(configstore.APIEndpoint{ 101 EnvironUUID: envUUID, 102 ServerUUID: envUUID, 103 }) 104 err := info.Write() 105 c.Assert(err, jc.ErrorIsNil) 106 cache := s.readCacheFile(c) 107 c.Assert(cache.Server, gc.HasLen, 1) 108 c.Assert(cache.ServerData, gc.HasLen, 1) 109 c.Assert(cache.Environment, gc.HasLen, 1) 110 } 111 112 func (s *cacheFileInterfaceSuite) TestWriteDupEnvAfterServer(c *gc.C) { 113 envUUID := testing.EnvironmentTag.Id() 114 s.writeEnv(c, "testing", "", envUUID, "tester", "secret") 115 info := s.store.CreateInfo("testing") 116 117 info.SetAPIEndpoint(configstore.APIEndpoint{ 118 EnvironUUID: "fake-uuid", 119 ServerUUID: "fake-uuid", 120 }) 121 err := info.Write() 122 c.Assert(err, gc.ErrorMatches, "environment info already exists") 123 } 124 125 func (s *cacheFileInterfaceSuite) TestServerUUIDRead(c *gc.C) { 126 envUUID := testing.EnvironmentTag.Id() 127 s.writeEnv(c, "testing", envUUID, envUUID, "tester", "secret") 128 129 info, err := s.store.ReadInfo("testing") 130 c.Assert(err, jc.ErrorIsNil) 131 c.Assert(info.APICredentials(), jc.DeepEquals, configstore.APICredentials{ 132 User: "tester", 133 Password: "secret", 134 }) 135 c.Assert(info.APIEndpoint(), jc.DeepEquals, configstore.APIEndpoint{ 136 Addresses: []string{"address1", "address2"}, 137 Hostnames: []string{"hostname1", "hostname2"}, 138 CACert: testing.CACert, 139 EnvironUUID: envUUID, 140 ServerUUID: envUUID, 141 }) 142 } 143 144 func (s *cacheFileInterfaceSuite) TestServerDetailsShared(c *gc.C) { 145 envUUID := testing.EnvironmentTag.Id() 146 s.writeEnv(c, "testing", envUUID, envUUID, "tester", "secret") 147 info := s.writeEnv(c, "second", "fake-uuid", envUUID, "tester", "new-secret") 148 endpoint := info.APIEndpoint() 149 endpoint.Addresses = []string{"address2", "address3"} 150 endpoint.Hostnames = []string{"hostname2", "hostname3"} 151 info.SetAPIEndpoint(endpoint) 152 err := info.Write() 153 c.Assert(err, jc.ErrorIsNil) 154 155 info, err = s.store.ReadInfo("testing") 156 c.Assert(err, jc.ErrorIsNil) 157 c.Assert(info.APICredentials(), jc.DeepEquals, configstore.APICredentials{ 158 User: "tester", 159 Password: "new-secret", 160 }) 161 c.Assert(info.APIEndpoint(), jc.DeepEquals, configstore.APIEndpoint{ 162 Addresses: []string{"address2", "address3"}, 163 Hostnames: []string{"hostname2", "hostname3"}, 164 CACert: testing.CACert, 165 EnvironUUID: envUUID, 166 ServerUUID: envUUID, 167 }) 168 169 cache := s.readCacheFile(c) 170 c.Assert(cache.Server, gc.HasLen, 1) 171 c.Assert(cache.ServerData, gc.HasLen, 1) 172 c.Assert(cache.Environment, gc.HasLen, 2) 173 } 174 175 func (s *cacheFileInterfaceSuite) TestMigrateJENV(c *gc.C) { 176 envUUID := testing.EnvironmentTag.Id() 177 info := s.writeEnv(c, "testing", envUUID, "", "tester", "secret") 178 envDir := filepath.Join(s.dir, "environments") 179 jenvFilename := configstore.JENVFilename(envDir, "testing") 180 c.Assert(info.Location(), gc.Equals, fmt.Sprintf("file %q", jenvFilename)) 181 182 // Add server details and write again will migrate the info to the 183 // cache file. 184 endpoint := info.APIEndpoint() 185 endpoint.ServerUUID = envUUID 186 info.SetAPIEndpoint(endpoint) 187 err := info.Write() 188 c.Assert(err, jc.ErrorIsNil) 189 190 c.Assert(jenvFilename, jc.DoesNotExist) 191 cache := s.readCacheFile(c) 192 193 envInfo, ok := cache.Environment["testing"] 194 c.Assert(ok, jc.IsTrue) 195 c.Assert(envInfo.User, gc.Equals, "tester") 196 c.Assert(envInfo.EnvironmentUUID, gc.Equals, envUUID) 197 c.Assert(envInfo.ServerUUID, gc.Equals, envUUID) 198 // Server entry also written. 199 srvInfo, ok := cache.Server["testing"] 200 c.Assert(ok, jc.IsTrue) 201 c.Assert(srvInfo.User, gc.Equals, "tester") 202 c.Assert(srvInfo.ServerUUID, gc.Equals, envUUID) 203 204 readInfo, err := s.store.ReadInfo("testing") 205 c.Assert(err, jc.ErrorIsNil) 206 c.Assert(readInfo.APIEndpoint(), jc.DeepEquals, info.APIEndpoint()) 207 } 208 209 func (s *cacheFileInterfaceSuite) readCacheFile(c *gc.C) configstore.CacheFile { 210 envDir := filepath.Join(s.dir, "environments") 211 filename := configstore.CacheFilename(envDir) 212 cache, err := configstore.ReadCacheFile(filename) 213 c.Assert(err, jc.ErrorIsNil) 214 return cache 215 } 216 217 func (s *cacheFileInterfaceSuite) TestExistingJENVBlocksNew(c *gc.C) { 218 envUUID := testing.EnvironmentTag.Id() 219 info := s.writeEnv(c, "testing", envUUID, "", "tester", "secret") 220 envDir := filepath.Join(s.dir, "environments") 221 jenvFilename := configstore.JENVFilename(envDir, "testing") 222 c.Assert(info.Location(), gc.Equals, fmt.Sprintf("file %q", jenvFilename)) 223 224 info = s.store.CreateInfo("testing") 225 // In order to trigger the writing to the cache file, we need to store 226 // a server uuid. 227 info.SetAPIEndpoint(configstore.APIEndpoint{ 228 EnvironUUID: envUUID, 229 ServerUUID: envUUID, 230 }) 231 err := info.Write() 232 c.Assert(err, gc.ErrorMatches, "environment info already exists") 233 } 234 235 func (s *cacheFileInterfaceSuite) TestList(c *gc.C) { 236 // List returns both JENV environments and the cache file environments. 237 s.writeEnv(c, "jenv-1", "fake-uuid1", "", "tester", "secret") 238 s.writeEnv(c, "jenv-2", "fake-uuid2", "", "tester", "secret") 239 s.writeEnv(c, "cache-1", "fake-uuid3", "fake-server", "tester", "secret") 240 s.writeEnv(c, "cache-2", "fake-uuid4", "fake-server", "tester", "secret") 241 242 environments, err := s.store.List() 243 c.Assert(err, jc.ErrorIsNil) 244 c.Assert(environments, jc.SameContents, []string{"jenv-1", "jenv-2", "cache-1", "cache-2"}) 245 246 // Confirm that the sources are from where we'd expect. 247 envDir := filepath.Join(s.dir, "environments") 248 c.Assert(configstore.JENVFilename(envDir, "jenv-1"), jc.IsNonEmptyFile) 249 c.Assert(configstore.JENVFilename(envDir, "jenv-2"), jc.IsNonEmptyFile) 250 cache := s.readCacheFile(c) 251 names := make([]string, 0) 252 for name := range cache.Environment { 253 names = append(names, name) 254 } 255 c.Assert(names, jc.SameContents, []string{"cache-1", "cache-2"}) 256 } 257 258 func (s *cacheFileInterfaceSuite) TestDestroy(c *gc.C) { 259 info := s.writeEnv(c, "cache-1", "fake-uuid", "fake-server", "tester", "secret") 260 261 err := info.Destroy() 262 c.Assert(err, jc.ErrorIsNil) 263 264 cache := s.readCacheFile(c) 265 c.Assert(cache.Server, gc.HasLen, 0) 266 c.Assert(cache.ServerData, gc.HasLen, 0) 267 c.Assert(cache.Environment, gc.HasLen, 0) 268 } 269 270 func (s *cacheFileInterfaceSuite) TestDestroyTwice(c *gc.C) { 271 info := s.writeEnv(c, "cache-1", "fake-uuid", "fake-server", "tester", "secret") 272 273 err := info.Destroy() 274 c.Assert(err, jc.ErrorIsNil) 275 err = info.Destroy() 276 c.Assert(err, gc.ErrorMatches, "environment info has already been removed") 277 } 278 279 func (s *cacheFileInterfaceSuite) TestDestroyKeepsSharedData(c *gc.C) { 280 info := s.writeEnv(c, "cache-1", "fake-uuid1", "fake-server", "tester", "secret") 281 s.writeEnv(c, "cache-2", "fake-uuid2", "fake-server", "tester", "secret") 282 283 err := info.Destroy() 284 c.Assert(err, jc.ErrorIsNil) 285 286 cache := s.readCacheFile(c) 287 c.Assert(cache.Server, gc.HasLen, 0) 288 c.Assert(cache.ServerData, gc.HasLen, 1) 289 c.Assert(cache.Environment, gc.HasLen, 1) 290 } 291 292 func (s *cacheFileInterfaceSuite) TestDestroyServerRemovesEnvironments(c *gc.C) { 293 // Bit more setup with this test. 294 // Create three server references, to two different systems, so we have 295 // one system through two different users. 296 info := s.writeEnv(c, "cache-1", "fake-server", "fake-server", "tester", "secret") 297 s.writeEnv(c, "cache-2", "fake-server", "fake-server", "other", "secret") 298 s.writeEnv(c, "cache-3", "fake-server2", "fake-server2", "tester", "secret") 299 300 // And a few environments on each server 301 s.writeEnv(c, "cache-4", "fake-env-1", "fake-server", "tester", "secret") 302 s.writeEnv(c, "cache-5", "fake-env-2", "fake-server", "other", "secret") 303 s.writeEnv(c, "cache-6", "fake-env-3", "fake-server2", "tester", "secret") 304 s.writeEnv(c, "cache-7", "fake-env-4", "fake-server2", "tester", "secret") 305 306 err := info.Destroy() 307 c.Assert(err, jc.ErrorIsNil) 308 309 cache := s.readCacheFile(c) 310 c.Assert(cache.Server, gc.HasLen, 1) 311 c.Assert(cache.ServerData, gc.HasLen, 1) 312 expected := []string{"cache-3", "cache-6", "cache-7"} 313 names := []string{} 314 for name := range cache.Environment { 315 names = append(names, name) 316 } 317 c.Assert(names, jc.SameContents, expected) 318 }