github.com/gojuno/afero@v1.1.1/composite_test.go (about) 1 package afero 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "testing" 9 "time" 10 ) 11 12 var tempDirs []string 13 14 func NewTempOsBaseFs(t *testing.T) Fs { 15 name, err := TempDir(NewOsFs(), "", "") 16 if err != nil { 17 t.Error("error creating tempDir", err) 18 } 19 20 tempDirs = append(tempDirs, name) 21 22 return NewBasePathFs(NewOsFs(), name) 23 } 24 25 func CleanupTempDirs(t *testing.T) { 26 osfs := NewOsFs() 27 type ev struct { 28 path string 29 e error 30 } 31 32 errs := []ev{} 33 34 for _, x := range tempDirs { 35 err := osfs.RemoveAll(x) 36 if err != nil { 37 errs = append(errs, ev{path: x, e: err}) 38 } 39 } 40 41 for _, e := range errs { 42 fmt.Println("error removing tempDir", e.path, e.e) 43 } 44 45 if len(errs) > 0 { 46 t.Error("error cleaning up tempDirs") 47 } 48 tempDirs = []string{} 49 } 50 51 func TestUnionCreateExisting(t *testing.T) { 52 base := &MemMapFs{} 53 roBase := &ReadOnlyFs{source: base} 54 ufs := NewCopyOnWriteFs(roBase, &MemMapFs{}) 55 56 base.MkdirAll("/home/test", 0777) 57 fh, _ := base.Create("/home/test/file.txt") 58 fh.WriteString("This is a test") 59 fh.Close() 60 61 fh, err := ufs.OpenFile("/home/test/file.txt", os.O_RDWR, 0666) 62 if err != nil { 63 t.Errorf("Failed to open file r/w: %s", err) 64 } 65 66 _, err = fh.Write([]byte("####")) 67 if err != nil { 68 t.Errorf("Failed to write file: %s", err) 69 } 70 fh.Seek(0, 0) 71 data, err := ioutil.ReadAll(fh) 72 if err != nil { 73 t.Errorf("Failed to read file: %s", err) 74 } 75 if string(data) != "#### is a test" { 76 t.Errorf("Got wrong data") 77 } 78 fh.Close() 79 80 fh, _ = base.Open("/home/test/file.txt") 81 data, err = ioutil.ReadAll(fh) 82 if string(data) != "This is a test" { 83 t.Errorf("Got wrong data in base file") 84 } 85 fh.Close() 86 87 fh, err = ufs.Create("/home/test/file.txt") 88 switch err { 89 case nil: 90 if fi, _ := fh.Stat(); fi.Size() != 0 { 91 t.Errorf("Create did not truncate file") 92 } 93 fh.Close() 94 default: 95 t.Errorf("Create failed on existing file") 96 } 97 98 } 99 100 func TestUnionMergeReaddir(t *testing.T) { 101 base := &MemMapFs{} 102 roBase := &ReadOnlyFs{source: base} 103 104 ufs := &CopyOnWriteFs{base: roBase, layer: &MemMapFs{}} 105 106 base.MkdirAll("/home/test", 0777) 107 fh, _ := base.Create("/home/test/file.txt") 108 fh.WriteString("This is a test") 109 fh.Close() 110 111 fh, _ = ufs.Create("/home/test/file2.txt") 112 fh.WriteString("This is a test") 113 fh.Close() 114 115 fh, _ = ufs.Open("/home/test") 116 files, err := fh.Readdirnames(-1) 117 if err != nil { 118 t.Errorf("Readdirnames failed") 119 } 120 if len(files) != 2 { 121 t.Errorf("Got wrong number of files: %v", files) 122 } 123 } 124 125 func TestExistingDirectoryCollisionReaddir(t *testing.T) { 126 base := &MemMapFs{} 127 roBase := &ReadOnlyFs{source: base} 128 overlay := &MemMapFs{} 129 130 ufs := &CopyOnWriteFs{base: roBase, layer: overlay} 131 132 base.MkdirAll("/home/test", 0777) 133 fh, _ := base.Create("/home/test/file.txt") 134 fh.WriteString("This is a test") 135 fh.Close() 136 137 overlay.MkdirAll("home/test", 0777) 138 fh, _ = overlay.Create("/home/test/file2.txt") 139 fh.WriteString("This is a test") 140 fh.Close() 141 142 fh, _ = ufs.Create("/home/test/file3.txt") 143 fh.WriteString("This is a test") 144 fh.Close() 145 146 fh, _ = ufs.Open("/home/test") 147 files, err := fh.Readdirnames(-1) 148 if err != nil { 149 t.Errorf("Readdirnames failed") 150 } 151 if len(files) != 3 { 152 t.Errorf("Got wrong number of files in union: %v", files) 153 } 154 155 fh, _ = overlay.Open("/home/test") 156 files, err = fh.Readdirnames(-1) 157 if err != nil { 158 t.Errorf("Readdirnames failed") 159 } 160 if len(files) != 2 { 161 t.Errorf("Got wrong number of files in overlay: %v", files) 162 } 163 } 164 165 func TestNestedDirBaseReaddir(t *testing.T) { 166 base := &MemMapFs{} 167 roBase := &ReadOnlyFs{source: base} 168 overlay := &MemMapFs{} 169 170 ufs := &CopyOnWriteFs{base: roBase, layer: overlay} 171 172 base.MkdirAll("/home/test/foo/bar", 0777) 173 fh, _ := base.Create("/home/test/file.txt") 174 fh.WriteString("This is a test") 175 fh.Close() 176 177 fh, _ = base.Create("/home/test/foo/file2.txt") 178 fh.WriteString("This is a test") 179 fh.Close() 180 fh, _ = base.Create("/home/test/foo/bar/file3.txt") 181 fh.WriteString("This is a test") 182 fh.Close() 183 184 overlay.MkdirAll("/", 0777) 185 186 // Opening something only in the base 187 fh, _ = ufs.Open("/home/test/foo") 188 list, err := fh.Readdir(-1) 189 if err != nil { 190 t.Errorf("Readdir failed %s", err) 191 } 192 if len(list) != 2 { 193 for _, x := range list { 194 fmt.Println(x.Name()) 195 } 196 t.Errorf("Got wrong number of files in union: %v", len(list)) 197 } 198 } 199 200 func TestNestedDirOverlayReaddir(t *testing.T) { 201 base := &MemMapFs{} 202 roBase := &ReadOnlyFs{source: base} 203 overlay := &MemMapFs{} 204 205 ufs := &CopyOnWriteFs{base: roBase, layer: overlay} 206 207 base.MkdirAll("/", 0777) 208 overlay.MkdirAll("/home/test/foo/bar", 0777) 209 fh, _ := overlay.Create("/home/test/file.txt") 210 fh.WriteString("This is a test") 211 fh.Close() 212 fh, _ = overlay.Create("/home/test/foo/file2.txt") 213 fh.WriteString("This is a test") 214 fh.Close() 215 fh, _ = overlay.Create("/home/test/foo/bar/file3.txt") 216 fh.WriteString("This is a test") 217 fh.Close() 218 219 // Opening nested dir only in the overlay 220 fh, _ = ufs.Open("/home/test/foo") 221 list, err := fh.Readdir(-1) 222 if err != nil { 223 t.Errorf("Readdir failed %s", err) 224 } 225 if len(list) != 2 { 226 for _, x := range list { 227 fmt.Println(x.Name()) 228 } 229 t.Errorf("Got wrong number of files in union: %v", len(list)) 230 } 231 } 232 233 func TestNestedDirOverlayOsFsReaddir(t *testing.T) { 234 defer CleanupTempDirs(t) 235 base := NewTempOsBaseFs(t) 236 roBase := &ReadOnlyFs{source: base} 237 overlay := NewTempOsBaseFs(t) 238 239 ufs := &CopyOnWriteFs{base: roBase, layer: overlay} 240 241 base.MkdirAll("/", 0777) 242 overlay.MkdirAll("/home/test/foo/bar", 0777) 243 fh, _ := overlay.Create("/home/test/file.txt") 244 fh.WriteString("This is a test") 245 fh.Close() 246 fh, _ = overlay.Create("/home/test/foo/file2.txt") 247 fh.WriteString("This is a test") 248 fh.Close() 249 fh, _ = overlay.Create("/home/test/foo/bar/file3.txt") 250 fh.WriteString("This is a test") 251 fh.Close() 252 253 // Opening nested dir only in the overlay 254 fh, _ = ufs.Open("/home/test/foo") 255 list, err := fh.Readdir(-1) 256 fh.Close() 257 if err != nil { 258 t.Errorf("Readdir failed %s", err) 259 } 260 if len(list) != 2 { 261 for _, x := range list { 262 fmt.Println(x.Name()) 263 } 264 t.Errorf("Got wrong number of files in union: %v", len(list)) 265 } 266 } 267 268 func TestCopyOnWriteFsWithOsFs(t *testing.T) { 269 defer CleanupTempDirs(t) 270 base := NewTempOsBaseFs(t) 271 roBase := &ReadOnlyFs{source: base} 272 overlay := NewTempOsBaseFs(t) 273 274 ufs := &CopyOnWriteFs{base: roBase, layer: overlay} 275 276 base.MkdirAll("/home/test", 0777) 277 fh, _ := base.Create("/home/test/file.txt") 278 fh.WriteString("This is a test") 279 fh.Close() 280 281 overlay.MkdirAll("home/test", 0777) 282 fh, _ = overlay.Create("/home/test/file2.txt") 283 fh.WriteString("This is a test") 284 fh.Close() 285 286 fh, _ = ufs.Create("/home/test/file3.txt") 287 fh.WriteString("This is a test") 288 fh.Close() 289 290 fh, _ = ufs.Open("/home/test") 291 files, err := fh.Readdirnames(-1) 292 fh.Close() 293 if err != nil { 294 t.Errorf("Readdirnames failed") 295 } 296 if len(files) != 3 { 297 t.Errorf("Got wrong number of files in union: %v", files) 298 } 299 300 fh, _ = overlay.Open("/home/test") 301 files, err = fh.Readdirnames(-1) 302 fh.Close() 303 if err != nil { 304 t.Errorf("Readdirnames failed") 305 } 306 if len(files) != 2 { 307 t.Errorf("Got wrong number of files in overlay: %v", files) 308 } 309 } 310 311 func TestUnionCacheWrite(t *testing.T) { 312 base := &MemMapFs{} 313 layer := &MemMapFs{} 314 315 ufs := NewCacheOnReadFs(base, layer, 0) 316 317 base.Mkdir("/data", 0777) 318 319 fh, err := ufs.Create("/data/file.txt") 320 if err != nil { 321 t.Errorf("Failed to create file") 322 } 323 _, err = fh.Write([]byte("This is a test")) 324 if err != nil { 325 t.Errorf("Failed to write file") 326 } 327 328 fh.Seek(0, os.SEEK_SET) 329 buf := make([]byte, 4) 330 _, err = fh.Read(buf) 331 fh.Write([]byte(" IS A")) 332 fh.Close() 333 334 baseData, _ := ReadFile(base, "/data/file.txt") 335 layerData, _ := ReadFile(layer, "/data/file.txt") 336 if string(baseData) != string(layerData) { 337 t.Errorf("Different data: %s <=> %s", baseData, layerData) 338 } 339 } 340 341 func TestUnionCacheExpire(t *testing.T) { 342 base := &MemMapFs{} 343 layer := &MemMapFs{} 344 ufs := &CacheOnReadFs{base: base, layer: layer, cacheTime: 1 * time.Second} 345 346 base.Mkdir("/data", 0777) 347 348 fh, err := ufs.Create("/data/file.txt") 349 if err != nil { 350 t.Errorf("Failed to create file") 351 } 352 _, err = fh.Write([]byte("This is a test")) 353 if err != nil { 354 t.Errorf("Failed to write file") 355 } 356 fh.Close() 357 358 fh, _ = base.Create("/data/file.txt") 359 // sleep some time, so we really get a different time.Now() on write... 360 time.Sleep(2 * time.Second) 361 fh.WriteString("Another test") 362 fh.Close() 363 364 data, _ := ReadFile(ufs, "/data/file.txt") 365 if string(data) != "Another test" { 366 t.Errorf("cache time failed: <%s>", data) 367 } 368 } 369 370 func TestCacheOnReadFsNotInLayer(t *testing.T) { 371 base := NewMemMapFs() 372 layer := NewMemMapFs() 373 fs := NewCacheOnReadFs(base, layer, 0) 374 375 fh, err := base.Create("/file.txt") 376 if err != nil { 377 t.Fatal("unable to create file: ", err) 378 } 379 380 txt := []byte("This is a test") 381 fh.Write(txt) 382 fh.Close() 383 384 fh, err = fs.Open("/file.txt") 385 if err != nil { 386 t.Fatal("could not open file: ", err) 387 } 388 389 b, err := ReadAll(fh) 390 fh.Close() 391 392 if err != nil { 393 t.Fatal("could not read file: ", err) 394 } else if !bytes.Equal(txt, b) { 395 t.Fatalf("wanted file text %q, got %q", txt, b) 396 } 397 398 fh, err = layer.Open("/file.txt") 399 if err != nil { 400 t.Fatal("could not open file from layer: ", err) 401 } 402 fh.Close() 403 }