@cryptotaxi247 / kubo / commits / fd4c4122d

add test and locking fix

License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>

Jeromy committed Dec 26, 2015 at 17:24 UTC fd4c4122d0a9cfab582b878759d1f5062d0f9982
2 files changed +158 -2
mfs/dir.go
+13 -2
@@ -4,6 +4,7 @@ import (
4 "errors"
5 "fmt"
6 "os"
7 + "path"
8 "sync"
9 "time"
10
@@ -48,7 +49,7 @@ func NewDirectory(ctx context.Context, name string, node *dag.Node, parent child
49 }
50
51 // closeChild updates the child by the given name to the dag node 'nd'
51 -// and changes its own dag node, then propogates the changes upward
52 +// and changes its own dag node
53 func (d *Directory) closeChild(name string, nd *dag.Node) error {
54 mynd, err := d.closeChildUpdate(name, nd)
55 if err != nil {
@@ -300,7 +301,7 @@ func (d *Directory) Unlink(name string) error {
301 return err
302 }
303
303 - return d.parent.closeChild(d.name, d.node)
304 + return nil
305 }
306
307 func (d *Directory) Flush() error {
@@ -375,6 +376,16 @@ func (d *Directory) sync() error {
376 return nil
377 }
378
379 +func (d *Directory) Path() string {
380 + cur := d
381 + var out string
382 + for cur != nil {
383 + out = path.Join(cur.name, out)
384 + cur = cur.parent.(*Directory)
385 + }
386 + return out
387 +}
388 +
389 func (d *Directory) GetNode() (*dag.Node, error) {
390 d.lock.Lock()
391 defer d.lock.Unlock()
mfs/mfs_test.go
+145
@@ -6,10 +6,12 @@ import (
6 "fmt"
7 "io"
8 "io/ioutil"
9 + "math/rand"
10 "os"
11 "sort"
12 "testing"
13
14 + randbo "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/dustin/randbo"
15 ds "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/ipfs/go-datastore"
16 dssync "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/ipfs/go-datastore/sync"
17 "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
@@ -474,3 +476,146 @@ func TestMfsFile(t *testing.T) {
476 t.Fatal(err)
477 }
478 }
479 +
480 +func randomWalk(d *Directory, n int) (*Directory, error) {
481 + for i := 0; i < n; i++ {
482 + dirents, err := d.List()
483 + if err != nil {
484 + return nil, err
485 + }
486 +
487 + var childdirs []NodeListing
488 + for _, child := range dirents {
489 + if child.Type == int(TDir) {
490 + childdirs = append(childdirs, child)
491 + }
492 + }
493 + if len(childdirs) == 0 {
494 + return d, nil
495 + }
496 +
497 + next := childdirs[rand.Intn(len(childdirs))].Name
498 +
499 + nextD, err := d.Child(next)
500 + if err != nil {
501 + return nil, err
502 + }
503 +
504 + d = nextD.(*Directory)
505 + }
506 + return d, nil
507 +}
508 +
509 +func randomName() string {
510 + set := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_"
511 + length := rand.Intn(10) + 2
512 + var out string
513 + for i := 0; i < length; i++ {
514 + j := rand.Intn(len(set))
515 + out += set[j : j+1]
516 + }
517 + return out
518 +}
519 +
520 +func actorMakeFile(d *Directory) error {
521 + d, err := randomWalk(d, rand.Intn(7))
522 + if err != nil {
523 + return err
524 + }
525 +
526 + name := randomName()
527 + f, err := NewFile(name, &dag.Node{Data: ft.FilePBData(nil, 0)}, d, d.dserv)
528 + if err != nil {
529 + return err
530 + }
531 +
532 + r := io.LimitReader(randbo.New(), int64(77*rand.Intn(123)))
533 + _, err = io.Copy(f, r)
534 + if err != nil {
535 + return err
536 + }
537 +
538 + err = f.Close()
539 + if err != nil {
540 + return err
541 + }
542 +
543 + return nil
544 +}
545 +func actorMkdir(d *Directory) error {
546 + d, err := randomWalk(d, rand.Intn(7))
547 + if err != nil {
548 + return err
549 + }
550 +
551 + _, err = d.Mkdir(randomName())
552 + if err != nil {
553 + return err
554 + }
555 +
556 + return nil
557 +}
558 +
559 +func actorRemoveFile(d *Directory) error {
560 + d, err := randomWalk(d, rand.Intn(7))
561 + if err != nil {
562 + return err
563 + }
564 +
565 + ents, err := d.List()
566 + if err != nil {
567 + return err
568 + }
569 +
570 + if len(ents) == 0 {
571 + return nil
572 + }
573 +
574 + re := ents[rand.Intn(len(ents))]
575 +
576 + return d.Unlink(re.Name)
577 +}
578 +
579 +func testActor(rt *Root, iterations int, errs chan error) {
580 + d := rt.GetValue().(*Directory)
581 + for i := 0; i < iterations; i++ {
582 + switch rand.Intn(4) {
583 + case 0:
584 + if err := actorMkdir(d); err != nil {
585 + errs <- err
586 + return
587 + }
588 + case 1, 2:
589 + if err := actorMakeFile(d); err != nil {
590 + errs <- err
591 + return
592 + }
593 + case 3:
594 + if err := actorRemoveFile(d); err != nil {
595 + errs <- err
596 + return
597 + }
598 + }
599 + }
600 + errs <- nil
601 +}
602 +
603 +func TestMfsStress(t *testing.T) {
604 + ctx, cancel := context.WithCancel(context.Background())
605 + defer cancel()
606 + _, rt := setupRoot(ctx, t)
607 +
608 + numroutines := 2
609 +
610 + errs := make(chan error)
611 + for i := 0; i < numroutines; i++ {
612 + go testActor(rt, 50, errs)
613 + }
614 +
615 + for i := 0; i < numroutines; i++ {
616 + err := <-errs
617 + if err != nil {
618 + t.Fatal(err)
619 + }
620 + }
621 +}