mirror of
https://github.com/ipfs/kubo.git
synced 2025-09-10 22:49:13 +08:00
236 lines
4.7 KiB
Go
236 lines
4.7 KiB
Go
package io
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"testing"
|
|
|
|
bs "github.com/jbenet/go-ipfs/blockservice"
|
|
imp "github.com/jbenet/go-ipfs/importer"
|
|
"github.com/jbenet/go-ipfs/importer/chunk"
|
|
mdag "github.com/jbenet/go-ipfs/merkledag"
|
|
ft "github.com/jbenet/go-ipfs/unixfs"
|
|
u "github.com/jbenet/go-ipfs/util"
|
|
|
|
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
|
|
logging "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-logging"
|
|
)
|
|
|
|
func getMockDagServ(t *testing.T) mdag.DAGService {
|
|
dstore := ds.NewMapDatastore()
|
|
bserv, err := bs.NewBlockService(dstore, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return mdag.NewDAGService(bserv)
|
|
}
|
|
|
|
func getNode(t *testing.T, dserv mdag.DAGService, size int64) ([]byte, *mdag.Node) {
|
|
in := io.LimitReader(u.NewTimeSeededRand(), size)
|
|
node, err := imp.BuildDagFromReader(in, dserv, nil, &chunk.SizeSplitter{500})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
dr, err := NewDagReader(node, dserv)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
b, err := ioutil.ReadAll(dr)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
return b, node
|
|
}
|
|
|
|
func testModWrite(t *testing.T, beg, size uint64, orig []byte, dm *DagModifier) []byte {
|
|
newdata := make([]byte, size)
|
|
r := u.NewTimeSeededRand()
|
|
r.Read(newdata)
|
|
|
|
if size+beg > uint64(len(orig)) {
|
|
orig = append(orig, make([]byte, (size+beg)-uint64(len(orig)))...)
|
|
}
|
|
copy(orig[beg:], newdata)
|
|
|
|
nmod, err := dm.WriteAt(newdata, uint64(beg))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if nmod != int(size) {
|
|
t.Fatalf("Mod length not correct! %d != %d", nmod, size)
|
|
}
|
|
|
|
nd, err := dm.GetNode()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
rd, err := NewDagReader(nd, dm.dagserv)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
after, err := ioutil.ReadAll(rd)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = arrComp(after, orig)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return orig
|
|
}
|
|
|
|
func TestDagModifierBasic(t *testing.T) {
|
|
logging.SetLevel(logging.CRITICAL, "blockservice")
|
|
logging.SetLevel(logging.CRITICAL, "merkledag")
|
|
dserv := getMockDagServ(t)
|
|
b, n := getNode(t, dserv, 50000)
|
|
|
|
dagmod, err := NewDagModifier(n, dserv, &chunk.SizeSplitter{Size: 512})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Within zero block
|
|
beg := uint64(15)
|
|
length := uint64(60)
|
|
|
|
t.Log("Testing mod within zero block")
|
|
b = testModWrite(t, beg, length, b, dagmod)
|
|
|
|
// Within bounds of existing file
|
|
beg = 1000
|
|
length = 4000
|
|
t.Log("Testing mod within bounds of existing file.")
|
|
b = testModWrite(t, beg, length, b, dagmod)
|
|
|
|
// Extend bounds
|
|
beg = 49500
|
|
length = 4000
|
|
|
|
t.Log("Testing mod that extends file.")
|
|
b = testModWrite(t, beg, length, b, dagmod)
|
|
|
|
// "Append"
|
|
beg = uint64(len(b))
|
|
length = 3000
|
|
b = testModWrite(t, beg, length, b, dagmod)
|
|
|
|
// Verify reported length
|
|
node, err := dagmod.GetNode()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
size, err := ft.DataSize(node.Data)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := uint64(50000 + 3500 + 3000)
|
|
if size != expected {
|
|
t.Fatalf("Final reported size is incorrect [%d != %d]", size, expected)
|
|
}
|
|
}
|
|
|
|
func TestMultiWrite(t *testing.T) {
|
|
dserv := getMockDagServ(t)
|
|
_, n := getNode(t, dserv, 0)
|
|
|
|
dagmod, err := NewDagModifier(n, dserv, &chunk.SizeSplitter{Size: 512})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
data := make([]byte, 4000)
|
|
u.NewTimeSeededRand().Read(data)
|
|
|
|
for i := 0; i < len(data); i++ {
|
|
n, err := dagmod.WriteAt(data[i:i+1], uint64(i))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if n != 1 {
|
|
t.Fatal("Somehow wrote the wrong number of bytes! (n != 1)")
|
|
}
|
|
}
|
|
nd, err := dagmod.GetNode()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
read, err := NewDagReader(nd, dserv)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rbuf, err := ioutil.ReadAll(read)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = arrComp(rbuf, data)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestMultiWriteCoal(t *testing.T) {
|
|
dserv := getMockDagServ(t)
|
|
_, n := getNode(t, dserv, 0)
|
|
|
|
dagmod, err := NewDagModifier(n, dserv, &chunk.SizeSplitter{Size: 512})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
data := make([]byte, 4000)
|
|
u.NewTimeSeededRand().Read(data)
|
|
|
|
for i := 0; i < len(data); i++ {
|
|
n, err := dagmod.WriteAt(data[:i+1], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if n != i+1 {
|
|
t.Fatal("Somehow wrote the wrong number of bytes! (n != 1)")
|
|
}
|
|
}
|
|
nd, err := dagmod.GetNode()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
read, err := NewDagReader(nd, dserv)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rbuf, err := ioutil.ReadAll(read)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = arrComp(rbuf, data)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func arrComp(a, b []byte) error {
|
|
if len(a) != len(b) {
|
|
return fmt.Errorf("Arrays differ in length. %d != %d", len(a), len(b))
|
|
}
|
|
for i, v := range a {
|
|
if v != b[i] {
|
|
return fmt.Errorf("Arrays differ at index: %d", i)
|
|
}
|
|
}
|
|
return nil
|
|
}
|