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