github.com/Altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/environs/filestorage/filestorage_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package filestorage_test 5 6 // The filestorage structs are used as stubs in tests. 7 // The tests defined herein are simple smoke tests for the 8 // required reader and writer functionality. 9 10 import ( 11 "bytes" 12 "io/ioutil" 13 "os" 14 "path/filepath" 15 "strings" 16 "testing" 17 18 "github.com/juju/errors" 19 jc "github.com/juju/testing/checkers" 20 "github.com/juju/utils" 21 gc "gopkg.in/check.v1" 22 23 "github.com/juju/juju/environs/filestorage" 24 "github.com/juju/juju/environs/storage" 25 ) 26 27 func TestPackage(t *testing.T) { 28 gc.TestingT(t) 29 } 30 31 type filestorageSuite struct { 32 dir string 33 reader storage.StorageReader 34 writer storage.StorageWriter 35 } 36 37 var _ = gc.Suite(&filestorageSuite{}) 38 39 func (s *filestorageSuite) SetUpTest(c *gc.C) { 40 s.dir = c.MkDir() 41 var err error 42 s.reader, err = filestorage.NewFileStorageReader(s.dir) 43 c.Assert(err, jc.ErrorIsNil) 44 s.writer, err = filestorage.NewFileStorageWriter(s.dir) 45 c.Assert(err, jc.ErrorIsNil) 46 } 47 48 func (s *filestorageSuite) createFile(c *gc.C, name string) (fullpath string, data []byte) { 49 fullpath = filepath.Join(s.dir, name) 50 dir := filepath.Dir(fullpath) 51 c.Assert(os.MkdirAll(dir, 0755), gc.IsNil) 52 data = []byte{1, 2, 3, 4, 5} 53 err := ioutil.WriteFile(fullpath, data, 0644) 54 c.Assert(err, jc.ErrorIsNil) 55 return fullpath, data 56 } 57 58 func (s *filestorageSuite) TestList(c *gc.C) { 59 names := []string{ 60 "a/b/c", 61 "a/bb", 62 "a/c", 63 "aa", 64 "b/c/d", 65 } 66 for _, name := range names { 67 s.createFile(c, name) 68 } 69 type test struct { 70 prefix string 71 expected []string 72 } 73 for i, test := range []test{ 74 {"a", []string{"a/b/c", "a/bb", "a/c", "aa"}}, 75 {"a/b", []string{"a/b/c", "a/bb"}}, 76 {"a/b/c", []string{"a/b/c"}}, 77 {"", names}, 78 } { 79 c.Logf("test %d: prefix=%q", i, test.prefix) 80 files, err := storage.List(s.reader, test.prefix) 81 c.Assert(err, jc.ErrorIsNil) 82 i := len(files) 83 j := len(test.expected) 84 c.Assert(i, gc.Equals, j) 85 for i := range files { 86 c.Assert(files[i], jc.SamePath, test.expected[i]) 87 } 88 } 89 } 90 91 func (s *filestorageSuite) TestListHidesTempDir(c *gc.C) { 92 err := s.writer.Put("test-write", bytes.NewReader(nil), 0) 93 c.Assert(err, jc.ErrorIsNil) 94 files, err := storage.List(s.reader, "") 95 c.Assert(err, jc.ErrorIsNil) 96 c.Check(files, gc.DeepEquals, []string{"test-write"}) 97 files, err = storage.List(s.reader, "no-such-directory") 98 c.Assert(err, jc.ErrorIsNil) 99 c.Check(files, gc.DeepEquals, []string(nil)) 100 // We also pretend the .tmp directory doesn't exist. If you call a 101 // directory that doesn't exist, we just return an empty list of 102 // strings, so we force the same behavior for '.tmp' 103 // we poke in a file so it would have something to return 104 s.createFile(c, ".tmp/test-file") 105 files, err = storage.List(s.reader, ".tmp") 106 c.Assert(err, jc.ErrorIsNil) 107 c.Check(files, gc.DeepEquals, []string(nil)) 108 // For consistency, we refuse all other possibilities as well 109 s.createFile(c, ".tmp/foo/bar") 110 files, err = storage.List(s.reader, ".tmp/foo") 111 c.Assert(err, jc.ErrorIsNil) 112 c.Check(files, gc.DeepEquals, []string(nil)) 113 s.createFile(c, ".tmpother/foo") 114 files, err = storage.List(s.reader, ".tmpother") 115 c.Assert(err, jc.ErrorIsNil) 116 c.Check(files, gc.DeepEquals, []string(nil)) 117 } 118 119 func (s *filestorageSuite) TestURL(c *gc.C) { 120 expectedpath, _ := s.createFile(c, "test-file") 121 _, file := filepath.Split(expectedpath) 122 url, err := s.reader.URL(file) 123 c.Assert(err, jc.ErrorIsNil) 124 c.Assert(url, gc.Equals, utils.MakeFileURL(expectedpath)) 125 } 126 127 func (s *filestorageSuite) TestGet(c *gc.C) { 128 expectedpath, data := s.createFile(c, "test-file") 129 _, file := filepath.Split(expectedpath) 130 rc, err := storage.Get(s.reader, file) 131 c.Assert(err, jc.ErrorIsNil) 132 defer rc.Close() 133 c.Assert(err, jc.ErrorIsNil) 134 b, err := ioutil.ReadAll(rc) 135 c.Assert(err, jc.ErrorIsNil) 136 c.Assert(b, gc.DeepEquals, data) 137 138 // Get on a non-existant path returns errors.NotFound 139 _, err = s.reader.Get("nowhere") 140 c.Assert(err, jc.Satisfies, errors.IsNotFound) 141 142 // Get on a directory returns errors.NotFound 143 s.createFile(c, "dir/file") 144 _, err = s.reader.Get("dir") 145 c.Assert(err, jc.Satisfies, errors.IsNotFound) 146 } 147 148 func (s *filestorageSuite) TestGetRefusesTemp(c *gc.C) { 149 s.createFile(c, ".tmp/test-file") 150 _, err := storage.Get(s.reader, ".tmp/test-file") 151 c.Check(err, gc.NotNil) 152 c.Check(err, jc.Satisfies, os.IsNotExist) 153 s.createFile(c, ".tmp/foo/test-file") 154 _, err = storage.Get(s.reader, ".tmp/foo/test-file") 155 c.Check(err, gc.NotNil) 156 c.Check(err, jc.Satisfies, os.IsNotExist) 157 } 158 159 func (s *filestorageSuite) TestPut(c *gc.C) { 160 data := []byte{1, 2, 3, 4, 5} 161 err := s.writer.Put("test-write", bytes.NewReader(data), int64(len(data))) 162 c.Assert(err, jc.ErrorIsNil) 163 b, err := ioutil.ReadFile(filepath.Join(s.dir, "test-write")) 164 c.Assert(err, jc.ErrorIsNil) 165 c.Assert(b, gc.DeepEquals, data) 166 } 167 168 func (s *filestorageSuite) TestPutRefusesTmp(c *gc.C) { 169 data := []byte{1, 2, 3, 4, 5} 170 err := s.writer.Put(".tmp/test-write", bytes.NewReader(data), int64(len(data))) 171 c.Assert(err, gc.NotNil) 172 c.Check(err, jc.Satisfies, os.IsPermission) 173 c.Check(*err.(*os.PathError), gc.Equals, os.PathError{ 174 Op: "Put", 175 Path: ".tmp/test-write", 176 Err: os.ErrPermission, 177 }) 178 _, err = ioutil.ReadFile(filepath.Join(s.dir, ".tmp", "test-write")) 179 c.Assert(err, jc.Satisfies, os.IsNotExist) 180 } 181 182 func (s *filestorageSuite) TestRemove(c *gc.C) { 183 expectedpath, _ := s.createFile(c, "test-file") 184 _, file := filepath.Split(expectedpath) 185 err := s.writer.Remove(file) 186 c.Assert(err, jc.ErrorIsNil) 187 _, err = ioutil.ReadFile(expectedpath) 188 c.Assert(err, gc.Not(gc.IsNil)) 189 } 190 191 func (s *filestorageSuite) TestRemoveAll(c *gc.C) { 192 expectedpath, _ := s.createFile(c, "test-file") 193 err := s.writer.RemoveAll() 194 c.Assert(err, jc.ErrorIsNil) 195 _, err = ioutil.ReadFile(expectedpath) 196 c.Assert(err, gc.Not(gc.IsNil)) 197 } 198 199 func (s *filestorageSuite) TestPutTmpDir(c *gc.C) { 200 // Put should create and clean up the temporary directory 201 err := s.writer.Put("test-write", bytes.NewReader(nil), 0) 202 c.Assert(err, jc.ErrorIsNil) 203 _, err = os.Stat(s.dir + "/.tmp") 204 c.Assert(err, jc.Satisfies, os.IsNotExist) 205 206 // To deal with recovering from hard failure, we 207 // don't care if the temporary directory already exists. It 208 // still removes it, though. 209 err = os.Mkdir(s.dir+"/.tmp", 0755) 210 c.Assert(err, jc.ErrorIsNil) 211 err = s.writer.Put("test-write", bytes.NewReader(nil), 0) 212 c.Assert(err, jc.ErrorIsNil) 213 _, err = os.Stat(s.dir + "/.tmp") 214 c.Assert(err, jc.Satisfies, os.IsNotExist) 215 } 216 217 func (s *filestorageSuite) TestPathRelativeToHome(c *gc.C) { 218 homeDir := utils.Home() 219 tempDir, err := ioutil.TempDir(homeDir, "") 220 c.Assert(err, jc.ErrorIsNil) 221 defer os.RemoveAll(tempDir) 222 dirName := strings.Replace(tempDir, homeDir, "", -1) 223 reader, err := filestorage.NewFileStorageReader(filepath.Join(utils.Home(), dirName)) 224 c.Assert(err, jc.ErrorIsNil) 225 url, err := reader.URL("") 226 c.Assert(err, jc.ErrorIsNil) 227 c.Assert(url, gc.Equals, utils.MakeFileURL(filepath.Join(homeDir, dirName))) 228 } 229 230 func (s *filestorageSuite) TestRelativePath(c *gc.C) { 231 dir := c.MkDir() 232 err := os.MkdirAll(filepath.Join(dir, "a", "b", "c"), os.ModePerm) 233 c.Assert(err, jc.ErrorIsNil) 234 cwd, err := os.Getwd() 235 c.Assert(err, jc.ErrorIsNil) 236 err = os.Chdir(filepath.Join(dir, "a", "b", "c")) 237 c.Assert(err, jc.ErrorIsNil) 238 defer os.Chdir(cwd) 239 reader, err := filestorage.NewFileStorageReader("../..") 240 c.Assert(err, jc.ErrorIsNil) 241 url, err := reader.URL("") 242 c.Assert(err, jc.ErrorIsNil) 243 c.Assert(url, gc.Equals, utils.MakeFileURL(dir)+"/a") 244 }