Commit fd4c4122 authored by Jeromy's avatar Jeromy

add test and locking fix

License: MIT
Signed-off-by: default avatarJeromy <jeromyj@gmail.com>
parent f548a404
......@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"os"
"path"
"sync"
"time"
......@@ -48,7 +49,7 @@ func NewDirectory(ctx context.Context, name string, node *dag.Node, parent child
}
// closeChild updates the child by the given name to the dag node 'nd'
// and changes its own dag node, then propogates the changes upward
// and changes its own dag node
func (d *Directory) closeChild(name string, nd *dag.Node) error {
mynd, err := d.closeChildUpdate(name, nd)
if err != nil {
......@@ -300,7 +301,7 @@ func (d *Directory) Unlink(name string) error {
return err
}
return d.parent.closeChild(d.name, d.node)
return nil
}
func (d *Directory) Flush() error {
......@@ -375,6 +376,16 @@ func (d *Directory) sync() error {
return nil
}
func (d *Directory) Path() string {
cur := d
var out string
for cur != nil {
out = path.Join(cur.name, out)
cur = cur.parent.(*Directory)
}
return out
}
func (d *Directory) GetNode() (*dag.Node, error) {
d.lock.Lock()
defer d.lock.Unlock()
......
......@@ -6,10 +6,12 @@ import (
"fmt"
"io"
"io/ioutil"
"math/rand"
"os"
"sort"
"testing"
randbo "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/dustin/randbo"
ds "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/ipfs/go-datastore"
dssync "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/ipfs/go-datastore/sync"
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
......@@ -474,3 +476,146 @@ func TestMfsFile(t *testing.T) {
t.Fatal(err)
}
}
func randomWalk(d *Directory, n int) (*Directory, error) {
for i := 0; i < n; i++ {
dirents, err := d.List()
if err != nil {
return nil, err
}
var childdirs []NodeListing
for _, child := range dirents {
if child.Type == int(TDir) {
childdirs = append(childdirs, child)
}
}
if len(childdirs) == 0 {
return d, nil
}
next := childdirs[rand.Intn(len(childdirs))].Name
nextD, err := d.Child(next)
if err != nil {
return nil, err
}
d = nextD.(*Directory)
}
return d, nil
}
func randomName() string {
set := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_"
length := rand.Intn(10) + 2
var out string
for i := 0; i < length; i++ {
j := rand.Intn(len(set))
out += set[j : j+1]
}
return out
}
func actorMakeFile(d *Directory) error {
d, err := randomWalk(d, rand.Intn(7))
if err != nil {
return err
}
name := randomName()
f, err := NewFile(name, &dag.Node{Data: ft.FilePBData(nil, 0)}, d, d.dserv)
if err != nil {
return err
}
r := io.LimitReader(randbo.New(), int64(77*rand.Intn(123)))
_, err = io.Copy(f, r)
if err != nil {
return err
}
err = f.Close()
if err != nil {
return err
}
return nil
}
func actorMkdir(d *Directory) error {
d, err := randomWalk(d, rand.Intn(7))
if err != nil {
return err
}
_, err = d.Mkdir(randomName())
if err != nil {
return err
}
return nil
}
func actorRemoveFile(d *Directory) error {
d, err := randomWalk(d, rand.Intn(7))
if err != nil {
return err
}
ents, err := d.List()
if err != nil {
return err
}
if len(ents) == 0 {
return nil
}
re := ents[rand.Intn(len(ents))]
return d.Unlink(re.Name)
}
func testActor(rt *Root, iterations int, errs chan error) {
d := rt.GetValue().(*Directory)
for i := 0; i < iterations; i++ {
switch rand.Intn(4) {
case 0:
if err := actorMkdir(d); err != nil {
errs <- err
return
}
case 1, 2:
if err := actorMakeFile(d); err != nil {
errs <- err
return
}
case 3:
if err := actorRemoveFile(d); err != nil {
errs <- err
return
}
}
}
errs <- nil
}
func TestMfsStress(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
_, rt := setupRoot(ctx, t)
numroutines := 2
errs := make(chan error)
for i := 0; i < numroutines; i++ {
go testActor(rt, 50, errs)
}
for i := 0; i < numroutines; i++ {
err := <-errs
if err != nil {
t.Fatal(err)
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment