func testInsert(t *testing.T, e *Editor, path, data string, create bool, experr string) {
	child := dag.NodeWithData([]byte(data))
	ck, err := e.tmp.Add(child)
	if err != nil {
		t.Fatal(err)
	}

	var c func() *dag.ProtoNode
	if create {
		c = func() *dag.ProtoNode {
			return &dag.ProtoNode{}
		}
	}

	err = e.InsertNodeAtPath(context.Background(), path, child, c)
	if experr != "" {
		var got string
		if err != nil {
			got = err.Error()
		}
		if got != experr {
			t.Fatalf("expected '%s' but got '%s'", experr, got)
		}
		return
	}

	if err != nil {
		t.Fatal(err, path, data, create, experr)
	}

	assertNodeAtPath(t, e.tmp, e.root, path, ck)
}
Exemple #2
0
func actorMakeFile(d *Directory) error {
	d, err := randomWalk(d, rand.Intn(7))
	if err != nil {
		return err
	}

	name := randomName()
	f, err := NewFile(name, dag.NodeWithData(ft.FilePBData(nil, 0)), d, d.dserv)
	if err != nil {
		return err
	}

	wfd, err := f.Open(OpenWriteOnly, true)
	if err != nil {
		return err
	}

	rread := rand.New(rand.NewSource(time.Now().UnixNano()))
	r := io.LimitReader(rread, int64(77*rand.Intn(123)))
	_, err = io.Copy(wfd, r)
	if err != nil {
		return err
	}

	err = wfd.Close()
	if err != nil {
		return err
	}

	return nil
}
func TestAddLink(t *testing.T) {
	ds := mdtest.Mock()
	fishnode := dag.NodeWithData([]byte("fishcakes!"))

	fk, err := ds.Add(fishnode)
	if err != nil {
		t.Fatal(err)
	}

	nd := new(dag.ProtoNode)
	nnode, err := addLink(context.Background(), ds, nd, "fish", fishnode)
	if err != nil {
		t.Fatal(err)
	}

	fnprime, err := nnode.GetLinkedNode(context.Background(), ds, "fish")
	if err != nil {
		t.Fatal(err)
	}

	fnpkey := fnprime.Cid()
	if !fnpkey.Equals(fk) {
		t.Fatal("wrong child node found!")
	}
}
Exemple #4
0
func newFan(t *testing.T, ds mdag.DAGService) node.Node {
	a := mdag.NodeWithData([]byte("/a"))
	addLink(t, ds, a, child(t, ds, a, "aa"))
	addLink(t, ds, a, child(t, ds, a, "ab"))
	addLink(t, ds, a, child(t, ds, a, "ac"))
	addLink(t, ds, a, child(t, ds, a, "ad"))
	return a
}
Exemple #5
0
// AddLink creates a unixfs symlink and returns its hash
func (s *Shell) AddLink(target string) (string, error) {
	d, _ := ft.SymlinkData(target)
	nd := dag.NodeWithData(d)
	c, err := s.node.DAG.Add(nd)
	if err != nil {
		return "", err
	}
	return c.String(), nil
}
func TestBadPBData(t *testing.T) {
	dserv := testu.GetDAGServ()
	ctx, closer := context.WithCancel(context.Background())
	defer closer()

	node := mdag.NodeWithData([]byte{42})
	_, err := NewDagReader(ctx, node, dserv)
	if err == nil {
		t.Fatal("excepted error, got nil")
	}
}
Exemple #7
0
func newLinkedList(t *testing.T, ds mdag.DAGService) node.Node {
	a := mdag.NodeWithData([]byte("/a"))
	aa := child(t, ds, a, "aa")
	aaa := child(t, ds, aa, "aaa")
	aaaa := child(t, ds, aaa, "aaaa")
	aaaaa := child(t, ds, aaaa, "aaaaa")
	addLink(t, ds, aaaa, aaaaa)
	addLink(t, ds, aaa, aaaa)
	addLink(t, ds, aa, aaa)
	addLink(t, ds, a, aa)
	return a
}
Exemple #8
0
func newBinaryTree(t *testing.T, ds mdag.DAGService) node.Node {
	a := mdag.NodeWithData([]byte("/a"))
	aa := child(t, ds, a, "aa")
	ab := child(t, ds, a, "ab")
	addLink(t, ds, aa, child(t, ds, aa, "aaa"))
	addLink(t, ds, aa, child(t, ds, aa, "aab"))
	addLink(t, ds, ab, child(t, ds, ab, "aba"))
	addLink(t, ds, ab, child(t, ds, ab, "abb"))
	addLink(t, ds, a, aa)
	addLink(t, ds, a, ab)
	return a
}
Exemple #9
0
func TestSet(t *testing.T) {
	ds := mdtest.Mock()
	limit := 10000 // 10000 reproduces the pinloss issue fairly reliably

	if os.Getenv("STRESS_IT_OUT_YO") != "" {
		limit = 10000000
	}
	var inputs []*cid.Cid
	for i := 0; i < limit; i++ {
		c, err := ds.Add(dag.NodeWithData([]byte(fmt.Sprint(i))))
		if err != nil {
			t.Fatal(err)
		}

		inputs = append(inputs, c)
	}

	out, err := storeSet(context.Background(), ds, inputs, ignoreCids)
	if err != nil {
		t.Fatal(err)
	}

	// weird wrapper node because loadSet expects us to pass an
	// object pointing to multiple named sets
	setroot := &dag.ProtoNode{}
	err = setroot.AddNodeLinkClean("foo", out)
	if err != nil {
		t.Fatal(err)
	}

	outset, err := loadSet(context.Background(), ds, setroot, "foo", ignoreCids)
	if err != nil {
		t.Fatal(err)
	}

	if len(outset) != limit {
		t.Fatal("got wrong number", len(outset), limit)
	}

	seen := cid.NewSet()
	for _, c := range outset {
		seen.Add(c)
	}

	for _, c := range inputs {
		if !seen.Has(c) {
			t.Fatalf("expected to have %s, didnt find it")
		}
	}
}
Exemple #10
0
func getFileHandle(r *mfs.Root, path string, create bool) (*mfs.File, error) {

	target, err := mfs.Lookup(r, path)
	switch err {
	case nil:
		fi, ok := target.(*mfs.File)
		if !ok {
			return nil, fmt.Errorf("%s was not a file", path)
		}
		return fi, nil

	case os.ErrNotExist:
		if !create {
			return nil, err
		}

		// if create is specified and the file doesnt exist, we create the file
		dirname, fname := gopath.Split(path)
		pdiri, err := mfs.Lookup(r, dirname)
		if err != nil {
			log.Error("lookupfail ", dirname)
			return nil, err
		}
		pdir, ok := pdiri.(*mfs.Directory)
		if !ok {
			return nil, fmt.Errorf("%s was not a directory", dirname)
		}

		nd := dag.NodeWithData(ft.FilePBData(nil, 0))
		err = pdir.AddChild(fname, nd)
		if err != nil {
			return nil, err
		}

		fsn, err := pdir.Child(fname)
		if err != nil {
			return nil, err
		}

		fi, ok := fsn.(*mfs.File)
		if !ok {
			return nil, errors.New("Expected *mfs.File, didnt get it. This is likely a race condition.")
		}
		return fi, nil

	default:
		return nil, err
	}
}
Exemple #11
0
func (adder *Adder) addFile(file files.File) error {
	err := adder.maybePauseForGC()
	if err != nil {
		return err
	}

	if file.IsDirectory() {
		return adder.addDir(file)
	}

	// case for symlink
	if s, ok := file.(*files.Symlink); ok {
		sdata, err := unixfs.SymlinkData(s.Target)
		if err != nil {
			return err
		}

		dagnode := dag.NodeWithData(sdata)
		_, err = adder.dagService.Add(dagnode)
		if err != nil {
			return err
		}

		return adder.addNode(dagnode, s.FileName())
	}

	// case for regular file
	// if the progress flag was specified, wrap the file so that we can send
	// progress updates to the client (over the output channel)
	var reader io.Reader = file
	if adder.Progress {
		rdr := &progressReader{file: file, out: adder.Out}
		if fi, ok := file.(files.FileInfo); ok {
			reader = &progressReader2{rdr, fi}
		} else {
			reader = rdr
		}
	}

	dagnode, err := adder.add(reader)
	if err != nil {
		return err
	}

	// patch it into the root
	return adder.addNode(dagnode, file.FileName())
}
func TestTypeFailures(t *testing.T) {
	dserv := testu.GetDAGServ()
	ctx, closer := context.WithCancel(context.Background())
	defer closer()

	node := unixfs.EmptyDirNode()
	if _, err := NewDagReader(ctx, node, dserv); err != ErrIsDir {
		t.Fatalf("excepted to get %v, got %v", ErrIsDir, err)
	}

	data, err := unixfs.SymlinkData("/somelink")
	if err != nil {
		t.Fatal(err)
	}
	node = mdag.NodeWithData(data)

	if _, err := NewDagReader(ctx, node, dserv); err != ErrCantReadSymlinks {
		t.Fatalf("excepted to get %v, got %v", ErrCantReadSymlinks, err)
	}
}
Exemple #13
0
func (dir *Directory) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) {
	// New 'empty' file
	nd := dag.NodeWithData(ft.FilePBData(nil, 0))
	err := dir.dir.AddChild(req.Name, nd)
	if err != nil {
		return nil, nil, err
	}

	child, err := dir.dir.Child(req.Name)
	if err != nil {
		return nil, nil, err
	}

	fi, ok := child.(*mfs.File)
	if !ok {
		return nil, nil, errors.New("child creation failed")
	}

	nodechild := &FileNode{fi: fi}

	var openflag int
	switch {
	case req.Flags.IsReadOnly():
		openflag = mfs.OpenReadOnly
	case req.Flags.IsWriteOnly():
		openflag = mfs.OpenWriteOnly
	case req.Flags.IsReadWrite():
		openflag = mfs.OpenReadWrite
	default:
		return nil, nil, errors.New("unsupported open mode")
	}

	fd, err := fi.Open(openflag, true)
	if err != nil {
		return nil, nil, err
	}

	return nodechild, &File{fi: fd}, nil
}
func TestMetadataNode(t *testing.T) {
	dserv := testu.GetDAGServ()
	rdata, rnode := testu.GetRandomNode(t, dserv, 512)
	_, err := dserv.Add(rnode)
	if err != nil {
		t.Fatal(err)
	}

	ctx, closer := context.WithCancel(context.Background())
	defer closer()

	data, err := unixfs.BytesForMetadata(&unixfs.Metadata{"text", 125})
	if err != nil {
		t.Fatal(err)
	}
	node := mdag.NodeWithData(data)

	_, err = NewDagReader(ctx, node, dserv)
	if err == nil {
		t.Fatal("expected an error")
	}
	if !strings.Contains(err.Error(), "incorrectly formatted") {
		t.Fatal("expected different error")
	}

	node.AddNodeLink("", rnode)

	reader, err := NewDagReader(ctx, node, dserv)
	if err != nil {
		t.Fatal(err)
	}
	readdata, err := ioutil.ReadAll(reader)
	if err != nil {
		t.Fatal(err)
	}
	if err := testu.ArrComp(rdata, readdata); err != nil {
		t.Fatal(err)
	}
}
Exemple #15
0
//TODO: hrm, maybe this interface could be better
func (s *Shell) PatchLink(root, npath, childhash string, create bool) (string, error) {
	p, err := path.ParsePath(root)
	if err != nil {
		return "", err
	}

	rootnd, err := core.Resolve(s.ctx, s.node, p)
	if err != nil {
		return "", err
	}

	childpath, err := path.ParsePath(childhash)
	if err != nil {
		return "", err
	}

	nnode, err := core.Resolve(s.ctx, s.node, childpath)
	if err != nil {
		return "", err
	}

	e := dagutils.NewDagEditor(rootnd, s.node.DAG)
	err = e.InsertNodeAtPath(s.ctx, npath, nnode, func() *dag.Node {
		return dag.NodeWithData(ft.FolderPBData())
	})
	if err != nil {
		return "", err
	}

	_, err = e.Finalize(s.node.DAG)
	if err != nil {
		return "", err
	}

	return e.GetNode().Key().B58String(), nil
}
Exemple #16
0
func child(t *testing.T, ds mdag.DAGService, a node.Node, name string) node.Node {
	return mdag.NodeWithData([]byte(string(a.(*mdag.ProtoNode).Data()) + "/" + name))
}
Exemple #17
0
func emptyDirNode() *dag.Node {
	return dag.NodeWithData(ft.FolderPBData())
}
Exemple #18
0
func TestFlushing(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	_, rt := setupRoot(ctx, t)

	dir := rt.GetValue().(*Directory)
	c := mkdirP(t, dir, "a/b/c")
	d := mkdirP(t, dir, "a/b/d")
	e := mkdirP(t, dir, "a/b/e")

	data := []byte("this is a test\n")
	nd1 := dag.NodeWithData(ft.FilePBData(data, uint64(len(data))))

	if err := c.AddChild("TEST", nd1); err != nil {
		t.Fatal(err)
	}
	if err := d.AddChild("TEST", nd1); err != nil {
		t.Fatal(err)
	}
	if err := e.AddChild("TEST", nd1); err != nil {
		t.Fatal(err)
	}
	if err := dir.AddChild("FILE", nd1); err != nil {
		t.Fatal(err)
	}

	if err := FlushPath(rt, "/a/b/c/TEST"); err != nil {
		t.Fatal(err)
	}

	if err := FlushPath(rt, "/a/b/d/TEST"); err != nil {
		t.Fatal(err)
	}

	if err := FlushPath(rt, "/a/b/e/TEST"); err != nil {
		t.Fatal(err)
	}

	if err := FlushPath(rt, "/FILE"); err != nil {
		t.Fatal(err)
	}

	rnd, err := dir.GetNode()
	if err != nil {
		t.Fatal(err)
	}

	pbrnd, ok := rnd.(*dag.ProtoNode)
	if !ok {
		t.Fatal(dag.ErrNotProtobuf)
	}

	fsnode, err := ft.FSNodeFromBytes(pbrnd.Data())
	if err != nil {
		t.Fatal(err)
	}

	if fsnode.Type != ft.TDirectory {
		t.Fatal("root wasnt a directory")
	}

	rnk := rnd.Cid()
	exp := "QmWMVyhTuyxUrXX3ynz171jq76yY3PktfY9Bxiph7b9ikr"
	if rnk.String() != exp {
		t.Fatalf("dag looks wrong, expected %s, but got %s", exp, rnk.String())
	}
}
Exemple #19
0
func TestFileDescriptors(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	ds, rt := setupRoot(ctx, t)
	dir := rt.GetValue().(*Directory)

	nd := dag.NodeWithData(ft.FilePBData(nil, 0))
	fi, err := NewFile("test", nd, dir, ds)
	if err != nil {
		t.Fatal(err)
	}

	// test read only
	rfd1, err := fi.Open(OpenReadOnly, false)
	if err != nil {
		t.Fatal(err)
	}

	err = rfd1.Truncate(0)
	if err == nil {
		t.Fatal("shouldnt be able to truncate readonly fd")
	}

	_, err = rfd1.Write([]byte{})
	if err == nil {
		t.Fatal("shouldnt be able to write to readonly fd")
	}

	_, err = rfd1.Read([]byte{})
	if err != nil {
		t.Fatalf("expected to be able to read from file: %s", err)
	}

	done := make(chan struct{})
	go func() {
		defer close(done)
		// can open second readonly file descriptor
		rfd2, err := fi.Open(OpenReadOnly, false)
		if err != nil {
			t.Error(err)
			return
		}

		rfd2.Close()
	}()

	select {
	case <-time.After(time.Second):
		t.Fatal("open second file descriptor failed")
	case <-done:
	}

	if t.Failed() {
		return
	}

	// test not being able to open for write until reader are closed
	done = make(chan struct{})
	go func() {
		defer close(done)
		wfd1, err := fi.Open(OpenWriteOnly, true)
		if err != nil {
			t.Error(err)
		}

		wfd1.Close()
	}()

	select {
	case <-time.After(time.Millisecond * 200):
	case <-done:
		if t.Failed() {
			return
		}

		t.Fatal("shouldnt have been able to open file for writing")
	}

	err = rfd1.Close()
	if err != nil {
		t.Fatal(err)
	}

	select {
	case <-time.After(time.Second):
		t.Fatal("should have been able to open write fd after closing read fd")
	case <-done:
	}

	wfd, err := fi.Open(OpenWriteOnly, true)
	if err != nil {
		t.Fatal(err)
	}

	_, err = wfd.Read([]byte{})
	if err == nil {
		t.Fatal("shouldnt have been able to read from write only filedescriptor")
	}

	_, err = wfd.Write([]byte{})
	if err != nil {
		t.Fatal(err)
	}
}
Exemple #20
0
func EmptyDirNode() *dag.ProtoNode {
	return dag.NodeWithData(FolderPBData())
}
Exemple #21
0
func child(t *testing.T, ds mdag.DAGService, a *mdag.Node, name string) *mdag.Node {
	return mdag.NodeWithData([]byte(string(a.Data()) + "/" + name))
}