2018-07-17 11:35:23 +00:00
|
|
|
package local
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2018-07-19 14:27:23 +00:00
|
|
|
"errors"
|
2018-07-17 11:35:23 +00:00
|
|
|
"mime/multipart"
|
|
|
|
"sync"
|
|
|
|
"testing"
|
|
|
|
|
2018-08-07 18:01:02 +00:00
|
|
|
adder "github.com/ipfs/ipfs-cluster/adder"
|
2018-07-17 11:35:23 +00:00
|
|
|
"github.com/ipfs/ipfs-cluster/api"
|
|
|
|
"github.com/ipfs/ipfs-cluster/test"
|
|
|
|
|
2019-06-14 10:41:11 +00:00
|
|
|
peer "github.com/libp2p/go-libp2p-core/peer"
|
2018-12-06 18:59:05 +00:00
|
|
|
rpc "github.com/libp2p/go-libp2p-gorpc"
|
2018-07-17 11:35:23 +00:00
|
|
|
)
|
|
|
|
|
2019-05-04 20:36:10 +00:00
|
|
|
type testIPFSRPC struct {
|
2018-07-17 11:35:23 +00:00
|
|
|
blocks sync.Map
|
|
|
|
}
|
|
|
|
|
2019-05-04 20:36:10 +00:00
|
|
|
type testClusterRPC struct {
|
|
|
|
pins sync.Map
|
|
|
|
}
|
|
|
|
|
|
|
|
func (rpcs *testIPFSRPC) BlockPut(ctx context.Context, in *api.NodeWithMeta, out *struct{}) error {
|
2019-02-27 17:04:35 +00:00
|
|
|
rpcs.blocks.Store(in.Cid.String(), in)
|
2018-07-17 11:35:23 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-05-04 20:36:10 +00:00
|
|
|
func (rpcs *testClusterRPC) Pin(ctx context.Context, in *api.Pin, out *struct{}) error {
|
2019-02-27 17:04:35 +00:00
|
|
|
rpcs.pins.Store(in.Cid.String(), in)
|
2018-07-17 11:35:23 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-05-04 20:36:10 +00:00
|
|
|
func (rpcs *testClusterRPC) BlockAllocate(ctx context.Context, in *api.Pin, out *[]peer.ID) error {
|
2018-07-19 14:27:23 +00:00
|
|
|
if in.ReplicationFactorMin > 1 {
|
|
|
|
return errors.New("we can only replicate to 1 peer")
|
|
|
|
}
|
2019-02-27 17:04:35 +00:00
|
|
|
// it does not matter since we use host == nil for RPC, so it uses the
|
|
|
|
// local one in all cases.
|
2019-02-27 20:19:10 +00:00
|
|
|
*out = []peer.ID{test.PeerID1}
|
2018-07-19 14:27:23 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-08-07 18:01:02 +00:00
|
|
|
func TestAdd(t *testing.T) {
|
2018-07-17 11:35:23 +00:00
|
|
|
t.Run("balanced", func(t *testing.T) {
|
2019-05-04 20:36:10 +00:00
|
|
|
clusterRPC := &testClusterRPC{}
|
|
|
|
ipfsRPC := &testIPFSRPC{}
|
2018-07-17 11:35:23 +00:00
|
|
|
server := rpc.NewServer(nil, "mock")
|
2019-05-04 20:36:10 +00:00
|
|
|
err := server.RegisterName("Cluster", clusterRPC)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
err = server.RegisterName("IPFSConnector", ipfsRPC)
|
2018-07-17 11:35:23 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
client := rpc.NewClientWithServer(nil, "mock", server)
|
2018-08-07 18:01:02 +00:00
|
|
|
params := api.DefaultAddParams()
|
2018-08-09 01:01:19 +00:00
|
|
|
params.Wrap = true
|
2018-07-17 11:35:23 +00:00
|
|
|
|
2018-08-07 18:01:02 +00:00
|
|
|
dags := New(client, params.PinOptions)
|
2018-08-08 19:10:42 +00:00
|
|
|
add := adder.New(dags, params, nil)
|
2018-07-17 11:35:23 +00:00
|
|
|
|
2018-07-19 13:17:27 +00:00
|
|
|
sth := test.NewShardingTestHelper()
|
2018-08-09 08:21:22 +00:00
|
|
|
defer sth.Clean(t)
|
|
|
|
mr, closer := sth.GetTreeMultiReader(t)
|
|
|
|
defer closer.Close()
|
2018-07-17 11:35:23 +00:00
|
|
|
r := multipart.NewReader(mr, mr.Boundary())
|
2018-08-07 18:01:02 +00:00
|
|
|
|
2018-08-08 19:10:42 +00:00
|
|
|
rootCid, err := add.FromMultipart(context.Background(), r)
|
2018-07-17 11:35:23 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-08-09 01:01:19 +00:00
|
|
|
if rootCid.String() != test.ShardingDirBalancedRootCIDWrapped {
|
2018-12-17 12:44:06 +00:00
|
|
|
t.Fatal("bad root cid: ", rootCid)
|
2018-07-19 13:17:27 +00:00
|
|
|
}
|
|
|
|
|
2018-07-17 11:35:23 +00:00
|
|
|
expected := test.ShardingDirCids[:]
|
|
|
|
for _, c := range expected {
|
2019-05-04 20:36:10 +00:00
|
|
|
_, ok := ipfsRPC.blocks.Load(c)
|
2018-07-17 11:35:23 +00:00
|
|
|
if !ok {
|
2019-05-04 20:36:10 +00:00
|
|
|
t.Error("no IPFS.BlockPut for block", c)
|
2018-07-17 11:35:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 20:36:10 +00:00
|
|
|
_, ok := clusterRPC.pins.Load(test.ShardingDirBalancedRootCIDWrapped)
|
2018-07-17 11:35:23 +00:00
|
|
|
if !ok {
|
|
|
|
t.Error("the tree wasn't pinned")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("trickle", func(t *testing.T) {
|
2019-05-04 20:36:10 +00:00
|
|
|
clusterRPC := &testClusterRPC{}
|
|
|
|
ipfsRPC := &testIPFSRPC{}
|
2018-07-17 11:35:23 +00:00
|
|
|
server := rpc.NewServer(nil, "mock")
|
2019-05-04 20:36:10 +00:00
|
|
|
err := server.RegisterName("Cluster", clusterRPC)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
err = server.RegisterName("IPFSConnector", ipfsRPC)
|
2018-07-17 11:35:23 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
client := rpc.NewClientWithServer(nil, "mock", server)
|
2018-08-07 18:01:02 +00:00
|
|
|
params := api.DefaultAddParams()
|
|
|
|
params.Layout = "trickle"
|
|
|
|
|
|
|
|
dags := New(client, params.PinOptions)
|
2018-08-08 19:10:42 +00:00
|
|
|
add := adder.New(dags, params, nil)
|
2018-07-17 11:35:23 +00:00
|
|
|
|
2018-07-19 13:17:27 +00:00
|
|
|
sth := test.NewShardingTestHelper()
|
2018-08-09 08:21:22 +00:00
|
|
|
defer sth.Clean(t)
|
|
|
|
mr, closer := sth.GetTreeMultiReader(t)
|
|
|
|
defer closer.Close()
|
2018-07-17 11:35:23 +00:00
|
|
|
r := multipart.NewReader(mr, mr.Boundary())
|
|
|
|
|
2018-08-08 19:10:42 +00:00
|
|
|
rootCid, err := add.FromMultipart(context.Background(), r)
|
2018-07-17 11:35:23 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-07-19 13:17:27 +00:00
|
|
|
if rootCid.String() != test.ShardingDirTrickleRootCID {
|
|
|
|
t.Fatal("bad root cid")
|
|
|
|
}
|
|
|
|
|
2019-05-04 20:36:10 +00:00
|
|
|
_, ok := clusterRPC.pins.Load(test.ShardingDirTrickleRootCID)
|
2018-07-17 11:35:23 +00:00
|
|
|
if !ok {
|
|
|
|
t.Error("the tree wasn't pinned")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|