github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/environs/configstore/disk_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package configstore_test 5 6 import ( 7 "fmt" 8 "io/ioutil" 9 "os" 10 "path/filepath" 11 "runtime" 12 "strings" 13 14 "github.com/juju/errors" 15 jc "github.com/juju/testing/checkers" 16 gc "gopkg.in/check.v1" 17 18 "github.com/juju/juju/environs/configstore" 19 "github.com/juju/juju/testing" 20 ) 21 22 var _ = gc.Suite(&diskInterfaceSuite{}) 23 24 type diskInterfaceSuite struct { 25 interfaceSuite 26 dir string 27 } 28 29 func (s *diskInterfaceSuite) SetUpTest(c *gc.C) { 30 s.interfaceSuite.SetUpTest(c) 31 s.dir = c.MkDir() 32 s.NewStore = func(c *gc.C) configstore.Storage { 33 store, err := configstore.NewDisk(s.dir) 34 c.Assert(err, jc.ErrorIsNil) 35 return store 36 } 37 } 38 39 // storePath returns the path to the environment info 40 // for the named environment in the given directory. 41 // If envName is empty, it returns the path 42 // to the info files' containing directory. 43 func storePath(dir string, envName string) string { 44 path := filepath.Join(dir, "environments") 45 if envName != "" { 46 path = filepath.Join(path, envName+".jenv") 47 } 48 return path 49 } 50 51 func (s *diskInterfaceSuite) TearDownTest(c *gc.C) { 52 s.NewStore = nil 53 // Check that no stray temp files have been left behind 54 entries, err := ioutil.ReadDir(storePath(s.dir, "")) 55 c.Assert(err, jc.ErrorIsNil) 56 for _, entry := range entries { 57 if !strings.HasSuffix(entry.Name(), ".jenv") { 58 c.Errorf("found possible stray temp file %q", entry.Name()) 59 } 60 } 61 s.interfaceSuite.TearDownTest(c) 62 } 63 64 var _ = gc.Suite(&diskStoreSuite{}) 65 66 type diskStoreSuite struct { 67 testing.BaseSuite 68 } 69 70 func (*diskStoreSuite) TestNewDisk(c *gc.C) { 71 dir := c.MkDir() 72 store, err := configstore.NewDisk(filepath.Join(dir, "foo")) 73 c.Assert(err, jc.Satisfies, os.IsNotExist) 74 c.Assert(store, gc.IsNil) 75 76 store, err = configstore.NewDisk(filepath.Join(dir)) 77 c.Assert(err, jc.ErrorIsNil) 78 c.Assert(store, gc.NotNil) 79 } 80 81 var sampleInfo = ` 82 user: rog 83 password: guessit 84 state-servers: 85 - 10.0.0.1 86 - 127.0.0.1 87 server-hostnames: 88 - example.com 89 - kremvax.ru 90 ca-cert: 'first line 91 92 second line' 93 bootstrap-config: 94 secret: blah 95 arble: bletch 96 `[1:] 97 98 func (*diskStoreSuite) TestRead(c *gc.C) { 99 dir := c.MkDir() 100 err := os.Mkdir(storePath(dir, ""), 0700) 101 c.Assert(err, jc.ErrorIsNil) 102 err = ioutil.WriteFile(storePath(dir, "someenv"), []byte(sampleInfo), 0666) 103 c.Assert(err, jc.ErrorIsNil) 104 store, err := configstore.NewDisk(dir) 105 c.Assert(err, jc.ErrorIsNil) 106 info, err := store.ReadInfo("someenv") 107 c.Assert(err, jc.ErrorIsNil) 108 c.Assert(info.Initialized(), jc.IsTrue) 109 c.Assert(info.APICredentials(), gc.DeepEquals, configstore.APICredentials{ 110 User: "rog", 111 Password: "guessit", 112 }) 113 c.Assert(info.APIEndpoint(), gc.DeepEquals, configstore.APIEndpoint{ 114 Addresses: []string{"10.0.0.1", "127.0.0.1"}, 115 Hostnames: []string{"example.com", "kremvax.ru"}, 116 CACert: "first line\nsecond line", 117 }) 118 c.Assert(info.Location(), gc.Equals, fmt.Sprintf("file %q", filepath.Join(dir, "environments", "someenv.jenv"))) 119 c.Assert(info.BootstrapConfig(), gc.DeepEquals, map[string]interface{}{ 120 "secret": "blah", 121 "arble": "bletch", 122 }) 123 } 124 125 func (*diskStoreSuite) TestReadNotFound(c *gc.C) { 126 dir := c.MkDir() 127 store, err := configstore.NewDisk(dir) 128 c.Assert(err, jc.ErrorIsNil) 129 info, err := store.ReadInfo("someenv") 130 c.Assert(err, jc.Satisfies, errors.IsNotFound) 131 c.Assert(info, gc.IsNil) 132 } 133 134 func (*diskStoreSuite) TestWriteFails(c *gc.C) { 135 dir := c.MkDir() 136 store, err := configstore.NewDisk(dir) 137 c.Assert(err, jc.ErrorIsNil) 138 139 info := store.CreateInfo("someenv") 140 141 // Make the directory non-writable 142 err = os.Chmod(storePath(dir, ""), 0555) 143 c.Assert(err, jc.ErrorIsNil) 144 145 // Cannot use permissions properly on windows for now 146 if runtime.GOOS != "windows" { 147 err = info.Write() 148 c.Assert(err, gc.ErrorMatches, ".* permission denied") 149 } 150 151 // Make the directory writable again so that gocheck can clean it up. 152 err = os.Chmod(storePath(dir, ""), 0777) 153 c.Assert(err, jc.ErrorIsNil) 154 } 155 156 func (*diskStoreSuite) TestRenameFails(c *gc.C) { 157 if runtime.GOOS == "windows" { 158 c.Skip("issue 1403084: the way the error is checked doesn't work on windows") 159 } 160 dir := c.MkDir() 161 store, err := configstore.NewDisk(dir) 162 c.Assert(err, jc.ErrorIsNil) 163 164 // Replace the file by an directory which can't be renamed over. 165 path := storePath(dir, "someenv") 166 err = os.Mkdir(path, 0777) 167 c.Assert(err, jc.ErrorIsNil) 168 169 info := store.CreateInfo("someenv") 170 err = info.Write() 171 c.Assert(err, gc.ErrorMatches, "environment info already exists") 172 } 173 174 func (*diskStoreSuite) TestDestroyRemovesFiles(c *gc.C) { 175 dir := c.MkDir() 176 store, err := configstore.NewDisk(dir) 177 c.Assert(err, jc.ErrorIsNil) 178 179 info := store.CreateInfo("someenv") 180 err = info.Write() 181 c.Assert(err, jc.ErrorIsNil) 182 183 _, err = os.Stat(storePath(dir, "someenv")) 184 c.Assert(err, jc.ErrorIsNil) 185 186 err = info.Destroy() 187 c.Assert(err, jc.ErrorIsNil) 188 189 _, err = os.Stat(storePath(dir, "someenv")) 190 c.Assert(err, jc.Satisfies, os.IsNotExist) 191 192 err = info.Destroy() 193 c.Assert(err, gc.ErrorMatches, "environment info has already been removed") 194 } 195 196 func (*diskStoreSuite) TestWriteSmallerFile(c *gc.C) { 197 dir := c.MkDir() 198 store, err := configstore.NewDisk(dir) 199 c.Assert(err, jc.ErrorIsNil) 200 info := store.CreateInfo("someenv") 201 endpoint := configstore.APIEndpoint{ 202 Addresses: []string{"this", "is", "never", "validated", "here"}, 203 Hostnames: []string{"neither", "is", "this"}, 204 EnvironUUID: testing.EnvironmentTag.Id(), 205 } 206 info.SetAPIEndpoint(endpoint) 207 err = info.Write() 208 c.Assert(err, jc.ErrorIsNil) 209 210 newInfo, err := store.ReadInfo("someenv") 211 c.Assert(err, jc.ErrorIsNil) 212 // Now change the number of addresses to be shorter. 213 endpoint.Addresses = []string{"just one"} 214 endpoint.Hostnames = []string{"just this"} 215 newInfo.SetAPIEndpoint(endpoint) 216 err = newInfo.Write() 217 c.Assert(err, jc.ErrorIsNil) 218 219 // We should be able to read in in fine. 220 yaInfo, err := store.ReadInfo("someenv") 221 c.Assert(err, jc.ErrorIsNil) 222 c.Assert(yaInfo.APIEndpoint().Addresses, gc.DeepEquals, []string{"just one"}) 223 c.Assert(yaInfo.APIEndpoint().Hostnames, gc.DeepEquals, []string{"just this"}) 224 }