1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
4
package configstore_test
10
jc "github.com/juju/testing/checkers"
11
gc "gopkg.in/check.v1"
13
"github.com/juju/juju/environs/configstore"
14
"github.com/juju/juju/testing"
17
var _ = gc.Suite(&cacheFileInterfaceSuite{})
19
type cacheFileInterfaceSuite struct {
22
store configstore.Storage
25
func (s *cacheFileInterfaceSuite) SetUpTest(c *gc.C) {
26
s.interfaceSuite.SetUpTest(c)
28
s.NewStore = func(c *gc.C) configstore.Storage {
29
store, err := configstore.NewDisk(s.dir)
30
c.Assert(err, jc.ErrorIsNil)
33
s.store = s.NewStore(c)
36
func (s *cacheFileInterfaceSuite) writeEnv(c *gc.C, name, modelUUID, srvUUID, user, password string) configstore.EnvironInfo {
37
info := s.store.CreateInfo(name)
38
info.SetAPIEndpoint(configstore.APIEndpoint{
39
Addresses: []string{"address1", "address2"},
40
Hostnames: []string{"hostname1", "hostname2"},
41
CACert: testing.CACert,
45
info.SetAPICredentials(configstore.APICredentials{
50
c.Assert(err, jc.ErrorIsNil)
54
func (s *cacheFileInterfaceSuite) TestServerUUIDWrite(c *gc.C) {
55
modelUUID := testing.ModelTag.Id()
56
info := s.writeEnv(c, "testing", modelUUID, modelUUID, "tester", "secret")
58
// Now make sure the cache file exists and the jenv doesn't
59
envDir := filepath.Join(s.dir, "models")
60
filename := configstore.CacheFilename(envDir)
61
c.Assert(info.Location(), gc.Equals, fmt.Sprintf("file %q", filename))
63
cache := s.readCacheFile(c)
64
c.Assert(cache.Server, gc.HasLen, 1)
65
c.Assert(cache.ServerData, gc.HasLen, 1)
66
c.Assert(cache.Environment, gc.HasLen, 1)
69
func (s *cacheFileInterfaceSuite) TestServerModelNameExists(c *gc.C) {
70
modelUUID := testing.ModelTag.Id()
71
s.writeEnv(c, "testing", modelUUID, modelUUID, "tester", "secret")
73
info := s.store.CreateInfo("testing")
74
// In order to trigger the writing to the cache file, we need to store
76
info.SetAPIEndpoint(configstore.APIEndpoint{
78
ServerUUID: modelUUID,
81
c.Assert(err, gc.ErrorMatches, "model info already exists")
84
func (s *cacheFileInterfaceSuite) TestWriteServerOnly(c *gc.C) {
85
modelUUID := testing.ModelTag.Id()
86
s.writeEnv(c, "testing", "", modelUUID, "tester", "secret")
87
cache := s.readCacheFile(c)
88
c.Assert(cache.Server, gc.HasLen, 1)
89
c.Assert(cache.ServerData, gc.HasLen, 1)
90
c.Assert(cache.Environment, gc.HasLen, 0)
93
func (s *cacheFileInterfaceSuite) TestWriteEnvAfterServer(c *gc.C) {
94
modelUUID := testing.ModelTag.Id()
95
s.writeEnv(c, "testing", "", modelUUID, "tester", "secret")
96
info := s.store.CreateInfo("testing")
98
info.SetAPIEndpoint(configstore.APIEndpoint{
100
ServerUUID: modelUUID,
103
c.Assert(err, jc.ErrorIsNil)
104
cache := s.readCacheFile(c)
105
c.Assert(cache.Server, gc.HasLen, 1)
106
c.Assert(cache.ServerData, gc.HasLen, 1)
107
c.Assert(cache.Environment, gc.HasLen, 1)
110
func (s *cacheFileInterfaceSuite) TestWriteDupEnvAfterServer(c *gc.C) {
111
modelUUID := testing.ModelTag.Id()
112
s.writeEnv(c, "testing", "", modelUUID, "tester", "secret")
113
info := s.store.CreateInfo("testing")
115
info.SetAPIEndpoint(configstore.APIEndpoint{
116
ModelUUID: "fake-uuid",
117
ServerUUID: "fake-uuid",
120
c.Assert(err, gc.ErrorMatches, "model info already exists")
123
func (s *cacheFileInterfaceSuite) TestServerUUIDRead(c *gc.C) {
124
modelUUID := testing.ModelTag.Id()
125
s.writeEnv(c, "testing", modelUUID, modelUUID, "tester", "secret")
127
info, err := s.store.ReadInfo("testing")
128
c.Assert(err, jc.ErrorIsNil)
129
c.Assert(info.APICredentials(), jc.DeepEquals, configstore.APICredentials{
133
c.Assert(info.APIEndpoint(), jc.DeepEquals, configstore.APIEndpoint{
134
Addresses: []string{"address1", "address2"},
135
Hostnames: []string{"hostname1", "hostname2"},
136
CACert: testing.CACert,
137
ModelUUID: modelUUID,
138
ServerUUID: modelUUID,
142
func (s *cacheFileInterfaceSuite) TestServerDetailsShared(c *gc.C) {
143
modelUUID := testing.ModelTag.Id()
144
s.writeEnv(c, "testing", modelUUID, modelUUID, "tester", "secret")
145
info := s.writeEnv(c, "second", "fake-uuid", modelUUID, "tester", "new-secret")
146
endpoint := info.APIEndpoint()
147
endpoint.Addresses = []string{"address2", "address3"}
148
endpoint.Hostnames = []string{"hostname2", "hostname3"}
149
info.SetAPIEndpoint(endpoint)
151
c.Assert(err, jc.ErrorIsNil)
153
info, err = s.store.ReadInfo("testing")
154
c.Assert(err, jc.ErrorIsNil)
155
c.Assert(info.APICredentials(), jc.DeepEquals, configstore.APICredentials{
157
Password: "new-secret",
159
c.Assert(info.APIEndpoint(), jc.DeepEquals, configstore.APIEndpoint{
160
Addresses: []string{"address2", "address3"},
161
Hostnames: []string{"hostname2", "hostname3"},
162
CACert: testing.CACert,
163
ModelUUID: modelUUID,
164
ServerUUID: modelUUID,
167
cache := s.readCacheFile(c)
168
c.Assert(cache.Server, gc.HasLen, 1)
169
c.Assert(cache.ServerData, gc.HasLen, 1)
170
c.Assert(cache.Environment, gc.HasLen, 2)
173
func (s *cacheFileInterfaceSuite) TestMigrateJENV(c *gc.C) {
174
modelUUID := testing.ModelTag.Id()
175
info := s.writeEnv(c, "testing", modelUUID, "", "tester", "secret")
176
envDir := filepath.Join(s.dir, "models")
177
jenvFilename := configstore.JENVFilename(envDir, "testing")
178
c.Assert(info.Location(), gc.Equals, fmt.Sprintf("file %q", jenvFilename))
180
// Add server details and write again will migrate the info to the
182
endpoint := info.APIEndpoint()
183
endpoint.ServerUUID = modelUUID
184
info.SetAPIEndpoint(endpoint)
186
c.Assert(err, jc.ErrorIsNil)
188
c.Assert(jenvFilename, jc.DoesNotExist)
189
cache := s.readCacheFile(c)
191
envInfo, ok := cache.Environment["testing"]
192
c.Assert(ok, jc.IsTrue)
193
c.Assert(envInfo.User, gc.Equals, "tester")
194
c.Assert(envInfo.ModelUUID, gc.Equals, modelUUID)
195
c.Assert(envInfo.ServerUUID, gc.Equals, modelUUID)
196
// Server entry also written.
197
srvInfo, ok := cache.Server["testing"]
198
c.Assert(ok, jc.IsTrue)
199
c.Assert(srvInfo.User, gc.Equals, "tester")
200
c.Assert(srvInfo.ServerUUID, gc.Equals, modelUUID)
202
readInfo, err := s.store.ReadInfo("testing")
203
c.Assert(err, jc.ErrorIsNil)
204
c.Assert(readInfo.APIEndpoint(), jc.DeepEquals, info.APIEndpoint())
207
func (s *cacheFileInterfaceSuite) readCacheFile(c *gc.C) configstore.CacheFile {
208
envDir := filepath.Join(s.dir, "models")
209
filename := configstore.CacheFilename(envDir)
210
cache, err := configstore.ReadCacheFile(filename)
211
c.Assert(err, jc.ErrorIsNil)
215
func (s *cacheFileInterfaceSuite) TestExistingJENVBlocksNew(c *gc.C) {
216
modelUUID := testing.ModelTag.Id()
217
info := s.writeEnv(c, "testing", modelUUID, "", "tester", "secret")
218
envDir := filepath.Join(s.dir, "models")
219
jenvFilename := configstore.JENVFilename(envDir, "testing")
220
c.Assert(info.Location(), gc.Equals, fmt.Sprintf("file %q", jenvFilename))
222
info = s.store.CreateInfo("testing")
223
// In order to trigger the writing to the cache file, we need to store
225
info.SetAPIEndpoint(configstore.APIEndpoint{
226
ModelUUID: modelUUID,
227
ServerUUID: modelUUID,
230
c.Assert(err, gc.ErrorMatches, "model info already exists")
233
func (s *cacheFileInterfaceSuite) TestList(c *gc.C) {
234
// List returns both JENV environments and the cache file environments.
235
s.writeEnv(c, "jenv-1", "fake-uuid1", "", "tester", "secret")
236
s.writeEnv(c, "jenv-2", "fake-uuid2", "", "tester", "secret")
237
s.writeEnv(c, "cache-1", "fake-uuid3", "fake-server", "tester", "secret")
238
s.writeEnv(c, "cache-2", "fake-uuid4", "fake-server", "tester", "secret")
240
environments, err := s.store.List()
241
c.Assert(err, jc.ErrorIsNil)
242
c.Assert(environments, jc.SameContents, []string{"jenv-1", "jenv-2", "cache-1", "cache-2"})
244
// Confirm that the sources are from where we'd expect.
245
envDir := filepath.Join(s.dir, "models")
246
c.Assert(configstore.JENVFilename(envDir, "jenv-1"), jc.IsNonEmptyFile)
247
c.Assert(configstore.JENVFilename(envDir, "jenv-2"), jc.IsNonEmptyFile)
248
cache := s.readCacheFile(c)
249
names := make([]string, 0)
250
for name := range cache.Environment {
251
names = append(names, name)
253
c.Assert(names, jc.SameContents, []string{"cache-1", "cache-2"})
256
func (s *cacheFileInterfaceSuite) TestDestroy(c *gc.C) {
257
info := s.writeEnv(c, "cache-1", "fake-uuid", "fake-server", "tester", "secret")
259
err := info.Destroy()
260
c.Assert(err, jc.ErrorIsNil)
262
cache := s.readCacheFile(c)
263
c.Assert(cache.Server, gc.HasLen, 0)
264
c.Assert(cache.ServerData, gc.HasLen, 0)
265
c.Assert(cache.Environment, gc.HasLen, 0)
268
func (s *cacheFileInterfaceSuite) TestDestroyTwice(c *gc.C) {
269
info := s.writeEnv(c, "cache-1", "fake-uuid", "fake-server", "tester", "secret")
271
err := info.Destroy()
272
c.Assert(err, jc.ErrorIsNil)
274
c.Assert(err, gc.ErrorMatches, "model info has already been removed")
277
func (s *cacheFileInterfaceSuite) TestDestroyKeepsSharedData(c *gc.C) {
278
info := s.writeEnv(c, "cache-1", "fake-uuid1", "fake-server", "tester", "secret")
279
s.writeEnv(c, "cache-2", "fake-uuid2", "fake-server", "tester", "secret")
281
err := info.Destroy()
282
c.Assert(err, jc.ErrorIsNil)
284
cache := s.readCacheFile(c)
285
c.Assert(cache.Server, gc.HasLen, 0)
286
c.Assert(cache.ServerData, gc.HasLen, 1)
287
c.Assert(cache.Environment, gc.HasLen, 1)
290
func (s *cacheFileInterfaceSuite) TestDestroyServerRemovesEnvironments(c *gc.C) {
291
// Bit more setup with this test.
292
// Create three server references, to two different systems, so we have
293
// one system through two different users.
294
info := s.writeEnv(c, "cache-1", "fake-server", "fake-server", "tester", "secret")
295
s.writeEnv(c, "cache-2", "fake-server", "fake-server", "other", "secret")
296
s.writeEnv(c, "cache-3", "fake-server2", "fake-server2", "tester", "secret")
298
// And a few environments on each server
299
s.writeEnv(c, "cache-4", "fake-env-1", "fake-server", "tester", "secret")
300
s.writeEnv(c, "cache-5", "fake-env-2", "fake-server", "other", "secret")
301
s.writeEnv(c, "cache-6", "fake-env-3", "fake-server2", "tester", "secret")
302
s.writeEnv(c, "cache-7", "fake-env-4", "fake-server2", "tester", "secret")
304
err := info.Destroy()
305
c.Assert(err, jc.ErrorIsNil)
307
cache := s.readCacheFile(c)
308
c.Assert(cache.Server, gc.HasLen, 1)
309
c.Assert(cache.ServerData, gc.HasLen, 1)
310
expected := []string{"cache-3", "cache-6", "cache-7"}
312
for name := range cache.Environment {
313
names = append(names, name)
315
c.Assert(names, jc.SameContents, expected)