ipfs-cluster/adder/adder_test.go
Hector Sanjuan 78b8f47c14 Fix: Wrap-in-directory
Usually we had wrap-in-directory enabled by default because otherwise
we had an error when adding single, non-directory files.

wrap-in-directory happens automatically when adding more than one file
so that was no problem. Thigns also worked when adding a folder and Wrap was
disabled. The only case was adding a single with wrap disabled (a default option).

This patches the ipfsadd/add.go file to remember the last added file so that
we can use it's Cid as the resulting root of the adding process without
having to fetch it from our dummy dagservice.

We have to pass this CID to our Finalize() functions, because it turns out that
in this case (single file without wrap-in-directory), the last block added to the DAG
is not the IPFS root (the ipfsadd/Adder adds the mfs root folder last always).

This was the case when wrap-in-directory was enabled by default.

License: MIT
Signed-off-by: Hector Sanjuan <code@hector.link>
2018-08-09 01:16:30 +02:00

130 lines
2.6 KiB
Go

package adder
import (
"context"
"mime/multipart"
"sync"
"testing"
"time"
"github.com/ipfs/ipfs-cluster/api"
"github.com/ipfs/ipfs-cluster/test"
cid "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format"
)
type mockCDagServ struct {
BaseDAGService
resultCids map[string]struct{}
}
func (dag *mockCDagServ) Add(ctx context.Context, node ipld.Node) error {
dag.resultCids[node.Cid().String()] = struct{}{}
return nil
}
func (dag *mockCDagServ) AddMany(ctx context.Context, nodes []ipld.Node) error {
for _, node := range nodes {
err := dag.Add(ctx, node)
if err != nil {
return err
}
}
return nil
}
func (dag *mockCDagServ) Finalize(ctx context.Context, root *cid.Cid) (*cid.Cid, error) {
return root, nil
}
func TestAdder(t *testing.T) {
sth := test.NewShardingTestHelper()
defer sth.Clean()
mr := sth.GetTreeMultiReader(t)
r := multipart.NewReader(mr, mr.Boundary())
p := api.DefaultAddParams()
expectedCids := test.ShardingDirCids[:]
dags := &mockCDagServ{
resultCids: make(map[string]struct{}),
}
adder := New(dags, p, nil)
root, err := adder.FromMultipart(context.Background(), r)
if err != nil {
t.Fatal(err)
}
if root.String() != test.ShardingDirBalancedRootCID {
t.Error("expected the right content root")
}
if len(expectedCids) != len(dags.resultCids) {
t.Fatal("unexpected number of blocks imported")
}
for _, c := range expectedCids {
_, ok := dags.resultCids[c]
if !ok {
t.Fatal("unexpected block emitted:", c)
}
}
}
func TestAdder_DoubleStart(t *testing.T) {
sth := test.NewShardingTestHelper()
defer sth.Clean()
f := sth.GetTreeSerialFile(t)
p := api.DefaultAddParams()
dags := &mockCDagServ{
resultCids: make(map[string]struct{}),
}
adder := New(dags, p, nil)
_, err := adder.FromFiles(context.Background(), f)
if err != nil {
t.Fatal(err)
}
f = sth.GetTreeSerialFile(t)
_, err = adder.FromFiles(context.Background(), f)
if err == nil {
t.Fatal("expected an error: cannot run importer twice")
}
}
func TestAdder_ContextCancelled(t *testing.T) {
sth := test.NewShardingTestHelper()
defer sth.Clean()
mr := sth.GetRandFileMultiReader(t, 50000) // 50 MB
r := multipart.NewReader(mr, mr.Boundary())
p := api.DefaultAddParams()
dags := &mockCDagServ{
resultCids: make(map[string]struct{}),
}
ctx, cancel := context.WithCancel(context.Background())
adder := New(dags, p, nil)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
_, err := adder.FromMultipart(ctx, r)
if err == nil {
t.Error("expected a context cancelled error")
}
t.Log(err)
}()
time.Sleep(200 * time.Millisecond)
cancel()
wg.Wait()
}