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
+}