github.com/alanchchen/go-ethereum@v1.6.6-0.20170601190819-6171d01b1195/swarm/fuse/swarmfs_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // +build linux darwin freebsd 18 19 package fuse 20 21 import ( 22 "bytes" 23 "crypto/rand" 24 "github.com/ethereum/go-ethereum/swarm/api" 25 "github.com/ethereum/go-ethereum/swarm/storage" 26 "io" 27 "io/ioutil" 28 "os" 29 "path/filepath" 30 "testing" 31 ) 32 33 type fileInfo struct { 34 perm uint64 35 uid int 36 gid int 37 contents []byte 38 } 39 40 func testFuseFileSystem(t *testing.T, f func(*api.Api)) { 41 42 datadir, err := ioutil.TempDir("", "fuse") 43 if err != nil { 44 t.Fatalf("unable to create temp dir: %v", err) 45 } 46 os.RemoveAll(datadir) 47 48 dpa, err := storage.NewLocalDPA(datadir) 49 if err != nil { 50 return 51 } 52 api := api.NewApi(dpa, nil) 53 dpa.Start() 54 f(api) 55 dpa.Stop() 56 } 57 58 func createTestFilesAndUploadToSwarm(t *testing.T, api *api.Api, files map[string]fileInfo, uploadDir string) string { 59 60 os.RemoveAll(uploadDir) 61 62 for fname, finfo := range files { 63 actualPath := filepath.Join(uploadDir, fname) 64 filePath := filepath.Dir(actualPath) 65 66 err := os.MkdirAll(filePath, 0777) 67 if err != nil { 68 t.Fatalf("Error creating directory '%v' : %v", filePath, err) 69 } 70 71 fd, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(finfo.perm)) 72 if err1 != nil { 73 t.Fatalf("Error creating file %v: %v", actualPath, err1) 74 } 75 76 fd.Write(finfo.contents) 77 fd.Chown(finfo.uid, finfo.gid) 78 fd.Chmod(os.FileMode(finfo.perm)) 79 fd.Sync() 80 fd.Close() 81 } 82 83 bzzhash, err := api.Upload(uploadDir, "") 84 if err != nil { 85 t.Fatalf("Error uploading directory %v: %v", uploadDir, err) 86 } 87 88 return bzzhash 89 } 90 91 func mountDir(t *testing.T, api *api.Api, files map[string]fileInfo, bzzHash string, mountDir string) *SwarmFS { 92 93 // Test Mount 94 os.RemoveAll(mountDir) 95 os.MkdirAll(mountDir, 0777) 96 swarmfs := NewSwarmFS(api) 97 _, err := swarmfs.Mount(bzzHash, mountDir) 98 if isFUSEUnsupportedError(err) { 99 t.Skip("FUSE not supported:", err) 100 } else if err != nil { 101 t.Fatalf("Error mounting hash %v: %v", bzzHash, err) 102 } 103 104 found := false 105 mi := swarmfs.Listmounts() 106 for _, minfo := range mi { 107 if minfo.MountPoint == mountDir { 108 if minfo.StartManifest != bzzHash || 109 minfo.LatestManifest != bzzHash || 110 minfo.fuseConnection == nil { 111 t.Fatalf("Error mounting: exp(%s): act(%s)", bzzHash, minfo.StartManifest) 112 } 113 found = true 114 } 115 } 116 117 // Test listMounts 118 if found == false { 119 t.Fatalf("Error getting mounts information for %v: %v", mountDir, err) 120 } 121 122 // Check if file and their attributes are as expected 123 compareGeneratedFileWithFileInMount(t, files, mountDir) 124 125 return swarmfs 126 127 } 128 129 func compareGeneratedFileWithFileInMount(t *testing.T, files map[string]fileInfo, mountDir string) { 130 131 err := filepath.Walk(mountDir, func(path string, f os.FileInfo, err error) error { 132 if f.IsDir() { 133 return nil 134 } 135 fname := path[len(mountDir)+1:] 136 if _, ok := files[fname]; !ok { 137 t.Fatalf(" file %v present in mount dir and is not expected", fname) 138 } 139 return nil 140 }) 141 if err != nil { 142 t.Fatalf("Error walking dir %v", mountDir) 143 } 144 145 for fname, finfo := range files { 146 147 destinationFile := filepath.Join(mountDir, fname) 148 149 dfinfo, err := os.Stat(destinationFile) 150 if err != nil { 151 t.Fatalf("Destination file %v missing in mount: %v", fname, err) 152 } 153 154 if int64(len(finfo.contents)) != dfinfo.Size() { 155 t.Fatalf("file %v Size mismatch source (%v) vs destination(%v)", fname, int64(len(finfo.contents)), dfinfo.Size()) 156 } 157 158 if dfinfo.Mode().Perm().String() != "-rwx------" { 159 t.Fatalf("file %v Permission mismatch source (-rwx------) vs destination(%v)", fname, dfinfo.Mode().Perm()) 160 } 161 162 fileContents, err := ioutil.ReadFile(filepath.Join(mountDir, fname)) 163 if err != nil { 164 t.Fatalf("Could not readfile %v : %v", fname, err) 165 } 166 167 if bytes.Compare(fileContents, finfo.contents) != 0 { 168 t.Fatalf("File %v contents mismatch: %v , %v", fname, fileContents, finfo.contents) 169 170 } 171 172 // TODO: check uid and gid 173 } 174 } 175 176 func checkFile(t *testing.T, testMountDir, fname string, contents []byte) { 177 178 destinationFile := filepath.Join(testMountDir, fname) 179 dfinfo, err1 := os.Stat(destinationFile) 180 if err1 != nil { 181 t.Fatalf("Could not stat file %v", destinationFile) 182 } 183 if dfinfo.Size() != int64(len(contents)) { 184 t.Fatalf("Mismatch in size actual(%v) vs expected(%v)", dfinfo.Size(), int64(len(contents))) 185 } 186 187 fd, err2 := os.OpenFile(destinationFile, os.O_RDONLY, os.FileMode(0665)) 188 if err2 != nil { 189 t.Fatalf("Could not open file %v", destinationFile) 190 } 191 newcontent := make([]byte, len(contents)) 192 fd.Read(newcontent) 193 fd.Close() 194 195 if !bytes.Equal(contents, newcontent) { 196 t.Fatalf("File content mismatch expected (%v): received (%v) ", contents, newcontent) 197 } 198 } 199 200 func getRandomBtes(size int) []byte { 201 contents := make([]byte, size) 202 rand.Read(contents) 203 return contents 204 205 } 206 207 func IsDirEmpty(name string) bool { 208 f, err := os.Open(name) 209 if err != nil { 210 return false 211 } 212 defer f.Close() 213 214 _, err = f.Readdirnames(1) 215 if err == io.EOF { 216 return true 217 } 218 return false 219 } 220 221 func testMountListAndUnmount(api *api.Api, t *testing.T) { 222 223 files := make(map[string]fileInfo) 224 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "fuse-source") 225 testMountDir, _ := ioutil.TempDir(os.TempDir(), "fuse-dest") 226 227 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 228 files["2.txt"] = fileInfo{0711, 333, 444, getRandomBtes(10)} 229 files["3.txt"] = fileInfo{0622, 333, 444, getRandomBtes(100)} 230 files["4.txt"] = fileInfo{0533, 333, 444, getRandomBtes(1024)} 231 files["5.txt"] = fileInfo{0544, 333, 444, getRandomBtes(10)} 232 files["6.txt"] = fileInfo{0555, 333, 444, getRandomBtes(10)} 233 files["7.txt"] = fileInfo{0666, 333, 444, getRandomBtes(10)} 234 files["8.txt"] = fileInfo{0777, 333, 333, getRandomBtes(10)} 235 files["11.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)} 236 files["111.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)} 237 files["two/2.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)} 238 files["two/2/2.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)} 239 files["two/2./2.txt"] = fileInfo{0777, 444, 444, getRandomBtes(10)} 240 files["twice/2.txt"] = fileInfo{0777, 444, 333, getRandomBtes(200)} 241 files["one/two/three/four/five/six/seven/eight/nine/10.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10240)} 242 files["one/two/three/four/five/six/six"] = fileInfo{0777, 333, 444, getRandomBtes(10)} 243 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 244 245 swarmfs := mountDir(t, api, files, bzzHash, testMountDir) 246 defer swarmfs.Stop() 247 248 // Check unmount 249 _, err := swarmfs.Unmount(testMountDir) 250 if err != nil { 251 t.Fatalf("could not unmount %v", bzzHash) 252 } 253 if !IsDirEmpty(testMountDir) { 254 t.Fatalf("unmount didnt work for %v", testMountDir) 255 } 256 257 } 258 259 func testMaxMounts(api *api.Api, t *testing.T) { 260 261 files := make(map[string]fileInfo) 262 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 263 uploadDir1, _ := ioutil.TempDir(os.TempDir(), "max-upload1") 264 bzzHash1 := createTestFilesAndUploadToSwarm(t, api, files, uploadDir1) 265 mount1, _ := ioutil.TempDir(os.TempDir(), "max-mount1") 266 swarmfs1 := mountDir(t, api, files, bzzHash1, mount1) 267 defer swarmfs1.Stop() 268 269 files["2.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 270 uploadDir2, _ := ioutil.TempDir(os.TempDir(), "max-upload2") 271 bzzHash2 := createTestFilesAndUploadToSwarm(t, api, files, uploadDir2) 272 mount2, _ := ioutil.TempDir(os.TempDir(), "max-mount2") 273 swarmfs2 := mountDir(t, api, files, bzzHash2, mount2) 274 defer swarmfs2.Stop() 275 276 files["3.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 277 uploadDir3, _ := ioutil.TempDir(os.TempDir(), "max-upload3") 278 bzzHash3 := createTestFilesAndUploadToSwarm(t, api, files, uploadDir3) 279 mount3, _ := ioutil.TempDir(os.TempDir(), "max-mount3") 280 swarmfs3 := mountDir(t, api, files, bzzHash3, mount3) 281 defer swarmfs3.Stop() 282 283 files["4.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 284 uploadDir4, _ := ioutil.TempDir(os.TempDir(), "max-upload4") 285 bzzHash4 := createTestFilesAndUploadToSwarm(t, api, files, uploadDir4) 286 mount4, _ := ioutil.TempDir(os.TempDir(), "max-mount4") 287 swarmfs4 := mountDir(t, api, files, bzzHash4, mount4) 288 defer swarmfs4.Stop() 289 290 files["5.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 291 uploadDir5, _ := ioutil.TempDir(os.TempDir(), "max-upload5") 292 bzzHash5 := createTestFilesAndUploadToSwarm(t, api, files, uploadDir5) 293 mount5, _ := ioutil.TempDir(os.TempDir(), "max-mount5") 294 swarmfs5 := mountDir(t, api, files, bzzHash5, mount5) 295 defer swarmfs5.Stop() 296 297 files["6.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 298 uploadDir6, _ := ioutil.TempDir(os.TempDir(), "max-upload6") 299 bzzHash6 := createTestFilesAndUploadToSwarm(t, api, files, uploadDir6) 300 mount6, _ := ioutil.TempDir(os.TempDir(), "max-mount6") 301 302 os.RemoveAll(mount6) 303 os.MkdirAll(mount6, 0777) 304 _, err := swarmfs.Mount(bzzHash6, mount6) 305 if err == nil { 306 t.Fatalf("Error: Going beyond max mounts %v", bzzHash6) 307 } 308 309 } 310 311 func testReMounts(api *api.Api, t *testing.T) { 312 313 files := make(map[string]fileInfo) 314 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 315 uploadDir1, _ := ioutil.TempDir(os.TempDir(), "re-upload1") 316 bzzHash1 := createTestFilesAndUploadToSwarm(t, api, files, uploadDir1) 317 testMountDir1, _ := ioutil.TempDir(os.TempDir(), "re-mount1") 318 swarmfs := mountDir(t, api, files, bzzHash1, testMountDir1) 319 defer swarmfs.Stop() 320 321 uploadDir2, _ := ioutil.TempDir(os.TempDir(), "re-upload2") 322 bzzHash2 := createTestFilesAndUploadToSwarm(t, api, files, uploadDir2) 323 testMountDir2, _ := ioutil.TempDir(os.TempDir(), "re-mount2") 324 325 // try mounting the same hash second time 326 os.RemoveAll(testMountDir2) 327 os.MkdirAll(testMountDir2, 0777) 328 _, err := swarmfs.Mount(bzzHash1, testMountDir2) 329 if err != nil { 330 t.Fatalf("Error mounting hash %v", bzzHash1) 331 } 332 333 // mount a different hash in already mounted point 334 _, err = swarmfs.Mount(bzzHash2, testMountDir1) 335 if err == nil { 336 t.Fatalf("Error mounting hash %v", bzzHash2) 337 } 338 339 // mount nonexistent hash 340 _, err = swarmfs.Mount("0xfea11223344", testMountDir1) 341 if err == nil { 342 t.Fatalf("Error mounting hash %v", bzzHash2) 343 } 344 345 } 346 347 func testUnmount(api *api.Api, t *testing.T) { 348 349 files := make(map[string]fileInfo) 350 uploadDir, _ := ioutil.TempDir(os.TempDir(), "ex-upload") 351 testMountDir, _ := ioutil.TempDir(os.TempDir(), "ex-mount") 352 353 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 354 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, uploadDir) 355 356 swarmfs := mountDir(t, api, files, bzzHash, testMountDir) 357 defer swarmfs.Stop() 358 359 swarmfs.Unmount(testMountDir) 360 361 mi := swarmfs.Listmounts() 362 for _, minfo := range mi { 363 if minfo.MountPoint == testMountDir { 364 t.Fatalf("mount state not cleaned up in unmount case %v", testMountDir) 365 } 366 } 367 368 } 369 370 func testUnmountWhenResourceBusy(api *api.Api, t *testing.T) { 371 372 files := make(map[string]fileInfo) 373 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "ex-upload") 374 testMountDir, _ := ioutil.TempDir(os.TempDir(), "ex-mount") 375 376 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 377 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 378 379 swarmfs := mountDir(t, api, files, bzzHash, testMountDir) 380 defer swarmfs.Stop() 381 382 actualPath := filepath.Join(testMountDir, "2.txt") 383 d, err := os.OpenFile(actualPath, os.O_RDWR, os.FileMode(0700)) 384 d.Write(getRandomBtes(10)) 385 386 _, err = swarmfs.Unmount(testMountDir) 387 if err != nil { 388 t.Fatalf("could not unmount %v", bzzHash) 389 } 390 d.Close() 391 392 mi := swarmfs.Listmounts() 393 for _, minfo := range mi { 394 if minfo.MountPoint == testMountDir { 395 t.Fatalf("mount state not cleaned up in unmount case %v", testMountDir) 396 } 397 } 398 399 } 400 func testSeekInMultiChunkFile(api *api.Api, t *testing.T) { 401 402 files := make(map[string]fileInfo) 403 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "seek-upload") 404 testMountDir, _ := ioutil.TempDir(os.TempDir(), "seek-mount") 405 406 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10240)} 407 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 408 409 swarmfs := mountDir(t, api, files, bzzHash, testMountDir) 410 defer swarmfs.Stop() 411 412 // Create a new file seek the second chunk 413 actualPath := filepath.Join(testMountDir, "1.txt") 414 d, _ := os.OpenFile(actualPath, os.O_RDONLY, os.FileMode(0700)) 415 416 d.Seek(5000, 0) 417 418 contents := make([]byte, 1024) 419 d.Read(contents) 420 finfo := files["1.txt"] 421 422 if bytes.Compare(finfo.contents[:6024][5000:], contents) != 0 { 423 t.Fatalf("File seek contents mismatch") 424 } 425 d.Close() 426 427 } 428 429 func testCreateNewFile(api *api.Api, t *testing.T) { 430 431 files := make(map[string]fileInfo) 432 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "create-upload") 433 testMountDir, _ := ioutil.TempDir(os.TempDir(), "create-mount") 434 435 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 436 files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 437 files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 438 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 439 440 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 441 defer swarmfs1.Stop() 442 443 // Create a new file in the root dir and check 444 actualPath := filepath.Join(testMountDir, "2.txt") 445 d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) 446 if err1 != nil { 447 t.Fatalf("Could not create file %s : %v", actualPath, err1) 448 } 449 contents := make([]byte, 11) 450 rand.Read(contents) 451 d.Write(contents) 452 d.Close() 453 454 mi, err2 := swarmfs1.Unmount(testMountDir) 455 if err2 != nil { 456 t.Fatalf("Could not unmount %v", err2) 457 } 458 459 // mount again and see if things are okay 460 files["2.txt"] = fileInfo{0700, 333, 444, contents} 461 swarmfs2 := mountDir(t, api, files, mi.LatestManifest, testMountDir) 462 defer swarmfs2.Stop() 463 464 checkFile(t, testMountDir, "2.txt", contents) 465 466 } 467 468 func testCreateNewFileInsideDirectory(api *api.Api, t *testing.T) { 469 470 files := make(map[string]fileInfo) 471 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "createinsidedir-upload") 472 testMountDir, _ := ioutil.TempDir(os.TempDir(), "createinsidedir-mount") 473 474 files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 475 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 476 477 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 478 defer swarmfs1.Stop() 479 480 // Create a new file inside a existing dir and check 481 dirToCreate := filepath.Join(testMountDir, "one") 482 actualPath := filepath.Join(dirToCreate, "2.txt") 483 d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) 484 if err1 != nil { 485 t.Fatalf("Could not create file %s : %v", actualPath, err1) 486 } 487 contents := make([]byte, 11) 488 rand.Read(contents) 489 d.Write(contents) 490 d.Close() 491 492 mi, err2 := swarmfs1.Unmount(testMountDir) 493 if err2 != nil { 494 t.Fatalf("Could not unmount %v", err2) 495 } 496 497 // mount again and see if things are okay 498 files["one/2.txt"] = fileInfo{0700, 333, 444, contents} 499 swarmfs2 := mountDir(t, api, files, mi.LatestManifest, testMountDir) 500 defer swarmfs2.Stop() 501 502 checkFile(t, testMountDir, "one/2.txt", contents) 503 504 } 505 506 func testCreateNewFileInsideNewDirectory(api *api.Api, t *testing.T) { 507 508 files := make(map[string]fileInfo) 509 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "createinsidenewdir-upload") 510 testMountDir, _ := ioutil.TempDir(os.TempDir(), "createinsidenewdir-mount") 511 512 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 513 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 514 515 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 516 defer swarmfs1.Stop() 517 518 // Create a new file inside a existing dir and check 519 dirToCreate := filepath.Join(testMountDir, "one") 520 os.MkdirAll(dirToCreate, 0777) 521 actualPath := filepath.Join(dirToCreate, "2.txt") 522 d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) 523 if err1 != nil { 524 t.Fatalf("Could not create file %s : %v", actualPath, err1) 525 } 526 contents := make([]byte, 11) 527 rand.Read(contents) 528 d.Write(contents) 529 d.Close() 530 531 mi, err2 := swarmfs1.Unmount(testMountDir) 532 if err2 != nil { 533 t.Fatalf("Could not unmount %v", err2) 534 } 535 536 // mount again and see if things are okay 537 files["one/2.txt"] = fileInfo{0700, 333, 444, contents} 538 swarmfs2 := mountDir(t, api, files, mi.LatestManifest, testMountDir) 539 defer swarmfs2.Stop() 540 541 checkFile(t, testMountDir, "one/2.txt", contents) 542 543 } 544 545 func testRemoveExistingFile(api *api.Api, t *testing.T) { 546 547 files := make(map[string]fileInfo) 548 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "remove-upload") 549 testMountDir, _ := ioutil.TempDir(os.TempDir(), "remove-mount") 550 551 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 552 files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 553 files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 554 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 555 556 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 557 defer swarmfs1.Stop() 558 559 // Remove a file in the root dir and check 560 actualPath := filepath.Join(testMountDir, "five.txt") 561 os.Remove(actualPath) 562 563 mi, err2 := swarmfs1.Unmount(testMountDir) 564 if err2 != nil { 565 t.Fatalf("Could not unmount %v", err2) 566 } 567 568 // mount again and see if things are okay 569 delete(files, "five.txt") 570 swarmfs2 := mountDir(t, api, files, mi.LatestManifest, testMountDir) 571 defer swarmfs2.Stop() 572 573 } 574 575 func testRemoveExistingFileInsideADir(api *api.Api, t *testing.T) { 576 577 files := make(map[string]fileInfo) 578 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "remove-upload") 579 testMountDir, _ := ioutil.TempDir(os.TempDir(), "remove-mount") 580 581 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 582 files["one/five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 583 files["one/six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 584 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 585 586 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 587 defer swarmfs1.Stop() 588 589 // Remove a file in the root dir and check 590 actualPath := filepath.Join(testMountDir, "one/five.txt") 591 os.Remove(actualPath) 592 593 mi, err2 := swarmfs1.Unmount(testMountDir) 594 if err2 != nil { 595 t.Fatalf("Could not unmount %v", err2) 596 } 597 598 // mount again and see if things are okay 599 delete(files, "one/five.txt") 600 swarmfs2 := mountDir(t, api, files, mi.LatestManifest, testMountDir) 601 defer swarmfs2.Stop() 602 603 } 604 605 func testRemoveNewlyAddedFile(api *api.Api, t *testing.T) { 606 607 files := make(map[string]fileInfo) 608 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "removenew-upload") 609 testMountDir, _ := ioutil.TempDir(os.TempDir(), "removenew-mount") 610 611 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 612 files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 613 files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 614 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 615 616 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 617 defer swarmfs1.Stop() 618 619 // Adda a new file and remove it 620 dirToCreate := filepath.Join(testMountDir, "one") 621 os.MkdirAll(dirToCreate, os.FileMode(0665)) 622 actualPath := filepath.Join(dirToCreate, "2.txt") 623 d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) 624 if err1 != nil { 625 t.Fatalf("Could not create file %s : %v", actualPath, err1) 626 } 627 contents := make([]byte, 11) 628 rand.Read(contents) 629 d.Write(contents) 630 d.Close() 631 632 checkFile(t, testMountDir, "one/2.txt", contents) 633 634 os.Remove(actualPath) 635 636 mi, err2 := swarmfs1.Unmount(testMountDir) 637 if err2 != nil { 638 t.Fatalf("Could not unmount %v", err2) 639 } 640 641 // mount again and see if things are okay 642 swarmfs2 := mountDir(t, api, files, mi.LatestManifest, testMountDir) 643 defer swarmfs2.Stop() 644 645 if bzzHash != mi.LatestManifest { 646 t.Fatalf("same contents different hash orig(%v): new(%v)", bzzHash, mi.LatestManifest) 647 } 648 649 } 650 651 func testAddNewFileAndModifyContents(api *api.Api, t *testing.T) { 652 653 files := make(map[string]fileInfo) 654 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "modifyfile-upload") 655 testMountDir, _ := ioutil.TempDir(os.TempDir(), "modifyfile-mount") 656 657 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 658 files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 659 files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 660 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 661 662 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 663 defer swarmfs1.Stop() 664 665 // Create a new file in the root dir and check 666 actualPath := filepath.Join(testMountDir, "2.txt") 667 d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) 668 if err1 != nil { 669 t.Fatalf("Could not create file %s : %v", actualPath, err1) 670 } 671 line1 := []byte("Line 1") 672 rand.Read(line1) 673 d.Write(line1) 674 d.Close() 675 676 mi1, err2 := swarmfs1.Unmount(testMountDir) 677 if err2 != nil { 678 t.Fatalf("Could not unmount %v", err2) 679 } 680 681 // mount again and see if things are okay 682 files["2.txt"] = fileInfo{0700, 333, 444, line1} 683 swarmfs2 := mountDir(t, api, files, mi1.LatestManifest, testMountDir) 684 defer swarmfs2.Stop() 685 686 checkFile(t, testMountDir, "2.txt", line1) 687 688 mi2, err3 := swarmfs2.Unmount(testMountDir) 689 if err3 != nil { 690 t.Fatalf("Could not unmount %v", err3) 691 } 692 693 // mount again and modify 694 swarmfs3 := mountDir(t, api, files, mi2.LatestManifest, testMountDir) 695 defer swarmfs3.Stop() 696 697 fd, err4 := os.OpenFile(actualPath, os.O_RDWR|os.O_APPEND, os.FileMode(0665)) 698 if err4 != nil { 699 t.Fatalf("Could not create file %s : %v", actualPath, err4) 700 } 701 line2 := []byte("Line 2") 702 rand.Read(line2) 703 fd.Seek(int64(len(line1)), 0) 704 fd.Write(line2) 705 fd.Close() 706 707 mi3, err5 := swarmfs3.Unmount(testMountDir) 708 if err5 != nil { 709 t.Fatalf("Could not unmount %v", err5) 710 } 711 712 // mount again and see if things are okay 713 b := [][]byte{line1, line2} 714 line1and2 := bytes.Join(b, []byte("")) 715 files["2.txt"] = fileInfo{0700, 333, 444, line1and2} 716 swarmfs4 := mountDir(t, api, files, mi3.LatestManifest, testMountDir) 717 defer swarmfs4.Stop() 718 719 checkFile(t, testMountDir, "2.txt", line1and2) 720 721 } 722 723 func testRemoveEmptyDir(api *api.Api, t *testing.T) { 724 files := make(map[string]fileInfo) 725 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-upload") 726 testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-mount") 727 728 files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 729 files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 730 files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 731 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 732 733 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 734 defer swarmfs1.Stop() 735 736 os.MkdirAll(filepath.Join(testMountDir, "newdir"), 0777) 737 738 mi, err3 := swarmfs1.Unmount(testMountDir) 739 if err3 != nil { 740 t.Fatalf("Could not unmount %v", err3) 741 } 742 743 if bzzHash != mi.LatestManifest { 744 t.Fatalf("same contents different hash orig(%v): new(%v)", bzzHash, mi.LatestManifest) 745 } 746 747 } 748 749 func testRemoveDirWhichHasFiles(api *api.Api, t *testing.T) { 750 751 files := make(map[string]fileInfo) 752 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-upload") 753 testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-mount") 754 755 files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 756 files["two/five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 757 files["two/six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 758 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 759 760 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 761 defer swarmfs1.Stop() 762 763 dirPath := filepath.Join(testMountDir, "two") 764 os.RemoveAll(dirPath) 765 766 mi, err2 := swarmfs1.Unmount(testMountDir) 767 if err2 != nil { 768 t.Fatalf("Could not unmount %v ", err2) 769 } 770 771 // mount again and see if things are okay 772 delete(files, "two/five.txt") 773 delete(files, "two/six.txt") 774 775 swarmfs2 := mountDir(t, api, files, mi.LatestManifest, testMountDir) 776 defer swarmfs2.Stop() 777 778 } 779 780 func testRemoveDirWhichHasSubDirs(api *api.Api, t *testing.T) { 781 782 files := make(map[string]fileInfo) 783 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmsubdir-upload") 784 testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmsubdir-mount") 785 786 files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 787 files["two/three/2.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 788 files["two/three/3.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 789 files["two/four/5.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 790 files["two/four/6.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 791 files["two/four/six/7.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} 792 793 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 794 795 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 796 defer swarmfs1.Stop() 797 798 dirPath := filepath.Join(testMountDir, "two") 799 os.RemoveAll(dirPath) 800 801 mi, err2 := swarmfs1.Unmount(testMountDir) 802 if err2 != nil { 803 t.Fatalf("Could not unmount %v ", err2) 804 } 805 806 // mount again and see if things are okay 807 delete(files, "two/three/2.txt") 808 delete(files, "two/three/3.txt") 809 delete(files, "two/four/5.txt") 810 delete(files, "two/four/6.txt") 811 delete(files, "two/four/six/7.txt") 812 813 swarmfs2 := mountDir(t, api, files, mi.LatestManifest, testMountDir) 814 defer swarmfs2.Stop() 815 816 } 817 818 func testAppendFileContentsToEnd(api *api.Api, t *testing.T) { 819 820 files := make(map[string]fileInfo) 821 testUploadDir, _ := ioutil.TempDir(os.TempDir(), "appendlargefile-upload") 822 testMountDir, _ := ioutil.TempDir(os.TempDir(), "appendlargefile-mount") 823 824 line1 := make([]byte, 10) 825 rand.Read(line1) 826 files["1.txt"] = fileInfo{0700, 333, 444, line1} 827 bzzHash := createTestFilesAndUploadToSwarm(t, api, files, testUploadDir) 828 829 swarmfs1 := mountDir(t, api, files, bzzHash, testMountDir) 830 defer swarmfs1.Stop() 831 832 actualPath := filepath.Join(testMountDir, "1.txt") 833 fd, err4 := os.OpenFile(actualPath, os.O_RDWR|os.O_APPEND, os.FileMode(0665)) 834 if err4 != nil { 835 t.Fatalf("Could not create file %s : %v", actualPath, err4) 836 } 837 line2 := make([]byte, 5) 838 rand.Read(line2) 839 fd.Seek(int64(len(line1)), 0) 840 fd.Write(line2) 841 fd.Close() 842 843 mi1, err5 := swarmfs1.Unmount(testMountDir) 844 if err5 != nil { 845 t.Fatalf("Could not unmount %v ", err5) 846 } 847 848 // mount again and see if things are okay 849 b := [][]byte{line1, line2} 850 line1and2 := bytes.Join(b, []byte("")) 851 files["1.txt"] = fileInfo{0700, 333, 444, line1and2} 852 swarmfs2 := mountDir(t, api, files, mi1.LatestManifest, testMountDir) 853 defer swarmfs2.Stop() 854 855 checkFile(t, testMountDir, "1.txt", line1and2) 856 857 } 858 859 func TestSwarmFileSystem(t *testing.T) { 860 testFuseFileSystem(t, func(api *api.Api) { 861 862 testMountListAndUnmount(api, t) 863 864 testMaxMounts(api, t) 865 866 testReMounts(api, t) 867 868 testUnmount(api, t) 869 870 testUnmountWhenResourceBusy(api, t) 871 872 testSeekInMultiChunkFile(api, t) 873 874 testCreateNewFile(api, t) 875 876 testCreateNewFileInsideDirectory(api, t) 877 878 testCreateNewFileInsideNewDirectory(api, t) 879 880 testRemoveExistingFile(api, t) 881 882 testRemoveExistingFileInsideADir(api, t) 883 884 testRemoveNewlyAddedFile(api, t) 885 886 testAddNewFileAndModifyContents(api, t) 887 888 testRemoveEmptyDir(api, t) 889 890 testRemoveDirWhichHasFiles(api, t) 891 892 testRemoveDirWhichHasSubDirs(api, t) 893 894 testAppendFileContentsToEnd(api, t) 895 896 }) 897 }