2016-12-14 16:25:21 +00:00
|
|
|
package ipfscluster
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"testing"
|
|
|
|
|
2017-02-08 17:04:08 +00:00
|
|
|
"github.com/ipfs/ipfs-cluster/api"
|
2017-02-09 15:29:17 +00:00
|
|
|
"github.com/ipfs/ipfs-cluster/state/mapstate"
|
|
|
|
"github.com/ipfs/ipfs-cluster/test"
|
2017-02-08 17:04:08 +00:00
|
|
|
|
2017-01-25 11:14:39 +00:00
|
|
|
rpc "github.com/hsanjuan/go-libp2p-gorpc"
|
2016-12-16 11:40:28 +00:00
|
|
|
cid "github.com/ipfs/go-cid"
|
2016-12-14 16:25:21 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type mockComponent struct {
|
2016-12-23 18:35:37 +00:00
|
|
|
rpcClient *rpc.Client
|
2016-12-14 16:25:21 +00:00
|
|
|
returnError bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *mockComponent) Shutdown() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-12-23 18:35:37 +00:00
|
|
|
func (c *mockComponent) SetClient(client *rpc.Client) {
|
|
|
|
c.rpcClient = client
|
|
|
|
return
|
2016-12-14 16:25:21 +00:00
|
|
|
}
|
|
|
|
|
2016-12-28 15:25:24 +00:00
|
|
|
type mockAPI struct {
|
2016-12-14 16:25:21 +00:00
|
|
|
mockComponent
|
|
|
|
}
|
|
|
|
|
|
|
|
type mockConnector struct {
|
|
|
|
mockComponent
|
|
|
|
}
|
|
|
|
|
2017-02-08 17:04:08 +00:00
|
|
|
func (ipfs *mockConnector) ID() (api.IPFSID, error) {
|
2017-01-26 18:59:31 +00:00
|
|
|
if ipfs.returnError {
|
2017-02-08 17:04:08 +00:00
|
|
|
return api.IPFSID{}, errors.New("")
|
2017-01-26 18:59:31 +00:00
|
|
|
}
|
2017-02-08 17:04:08 +00:00
|
|
|
return api.IPFSID{
|
2017-02-09 15:29:17 +00:00
|
|
|
ID: test.TestPeerID1,
|
2017-01-26 18:59:31 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2016-12-14 16:25:21 +00:00
|
|
|
func (ipfs *mockConnector) Pin(c *cid.Cid) error {
|
|
|
|
if ipfs.returnError {
|
|
|
|
return errors.New("")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ipfs *mockConnector) Unpin(c *cid.Cid) error {
|
|
|
|
if ipfs.returnError {
|
|
|
|
return errors.New("")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-02-08 17:04:08 +00:00
|
|
|
func (ipfs *mockConnector) PinLsCid(c *cid.Cid) (api.IPFSPinStatus, error) {
|
2016-12-14 16:25:21 +00:00
|
|
|
if ipfs.returnError {
|
2017-02-08 17:04:08 +00:00
|
|
|
return api.IPFSPinStatusError, errors.New("")
|
2016-12-14 16:25:21 +00:00
|
|
|
}
|
2017-02-08 17:04:08 +00:00
|
|
|
return api.IPFSPinStatusRecursive, nil
|
2017-01-25 17:07:19 +00:00
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
func (ipfs *mockConnector) PinLs(filter string) (map[string]api.IPFSPinStatus, error) {
|
2017-01-25 17:07:19 +00:00
|
|
|
if ipfs.returnError {
|
|
|
|
return nil, errors.New("")
|
|
|
|
}
|
2017-02-08 17:04:08 +00:00
|
|
|
m := make(map[string]api.IPFSPinStatus)
|
2017-01-25 17:07:19 +00:00
|
|
|
return m, nil
|
2016-12-14 16:25:21 +00:00
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
func testingCluster(t *testing.T) (*Cluster, *mockAPI, *mockConnector, *mapstate.MapState, *MapPinTracker) {
|
2016-12-28 15:25:24 +00:00
|
|
|
api := &mockAPI{}
|
2016-12-14 16:25:21 +00:00
|
|
|
ipfs := &mockConnector{}
|
|
|
|
cfg := testingConfig()
|
2017-02-09 15:29:17 +00:00
|
|
|
st := mapstate.NewMapState()
|
2016-12-19 17:35:24 +00:00
|
|
|
tracker := NewMapPinTracker(cfg)
|
2016-12-14 16:25:21 +00:00
|
|
|
|
|
|
|
cl, err := NewCluster(
|
|
|
|
cfg,
|
|
|
|
api,
|
|
|
|
ipfs,
|
|
|
|
st,
|
|
|
|
tracker,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("cannot create cluster:", err)
|
|
|
|
}
|
2017-01-30 12:12:25 +00:00
|
|
|
<-cl.Ready()
|
2016-12-23 18:35:37 +00:00
|
|
|
return cl, api, ipfs, st, tracker
|
2016-12-14 16:25:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func testClusterShutdown(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
cl, _, _, _, _ := testingCluster(t)
|
2016-12-14 16:25:21 +00:00
|
|
|
err := cl.Shutdown()
|
|
|
|
if err != nil {
|
|
|
|
t.Error("cluster shutdown failed:", err)
|
|
|
|
}
|
2016-12-15 13:07:19 +00:00
|
|
|
cl.Shutdown()
|
2016-12-23 18:35:37 +00:00
|
|
|
cl, _, _, _, _ = testingCluster(t)
|
2016-12-14 16:25:21 +00:00
|
|
|
err = cl.Shutdown()
|
|
|
|
if err != nil {
|
|
|
|
t.Error("cluster shutdown failed:", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-20 18:51:13 +00:00
|
|
|
func TestClusterStateSync(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
cl, _, _, st, _ := testingCluster(t)
|
2016-12-14 17:04:49 +00:00
|
|
|
defer cleanRaft()
|
2016-12-14 16:25:21 +00:00
|
|
|
defer cl.Shutdown()
|
2016-12-20 18:51:13 +00:00
|
|
|
_, err := cl.StateSync()
|
2016-12-14 17:04:49 +00:00
|
|
|
if err == nil {
|
2017-02-08 17:04:08 +00:00
|
|
|
t.Fatal("expected an error as there is no state to sync")
|
2016-12-14 16:25:21 +00:00
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
c, _ := cid.Decode(test.TestCid1)
|
2016-12-14 16:25:21 +00:00
|
|
|
err = cl.Pin(c)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("pin should have worked:", err)
|
|
|
|
}
|
|
|
|
|
2016-12-20 18:51:13 +00:00
|
|
|
_, err = cl.StateSync()
|
2016-12-14 16:25:21 +00:00
|
|
|
if err != nil {
|
2016-12-14 17:04:49 +00:00
|
|
|
t.Fatal("sync after pinning should have worked:", err)
|
2016-12-14 16:25:21 +00:00
|
|
|
}
|
|
|
|
|
2016-12-14 17:04:49 +00:00
|
|
|
// Modify state on the side so the sync does not
|
|
|
|
// happen on an empty slide
|
|
|
|
st.RmPin(c)
|
2016-12-20 18:51:13 +00:00
|
|
|
_, err = cl.StateSync()
|
2016-12-14 17:04:49 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal("sync with recover should have worked:", err)
|
2016-12-14 16:25:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-24 15:19:23 +00:00
|
|
|
func TestClusterID(t *testing.T) {
|
|
|
|
cl, _, _, _, _ := testingCluster(t)
|
|
|
|
defer cleanRaft()
|
|
|
|
defer cl.Shutdown()
|
|
|
|
id := cl.ID()
|
|
|
|
if len(id.Addresses) == 0 {
|
|
|
|
t.Error("expected more addresses")
|
|
|
|
}
|
|
|
|
if id.ID == "" {
|
|
|
|
t.Error("expected a cluster ID")
|
|
|
|
}
|
|
|
|
if id.Version != Version {
|
|
|
|
t.Error("version should match current version")
|
|
|
|
}
|
2017-02-08 17:04:08 +00:00
|
|
|
//if id.PublicKey == nil {
|
|
|
|
// t.Error("publicKey should not be empty")
|
|
|
|
//}
|
2017-01-24 15:19:23 +00:00
|
|
|
}
|
|
|
|
|
2016-12-14 17:04:49 +00:00
|
|
|
func TestClusterPin(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
cl, _, _, _, _ := testingCluster(t)
|
2016-12-14 16:25:21 +00:00
|
|
|
defer cleanRaft()
|
|
|
|
defer cl.Shutdown()
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
c, _ := cid.Decode(test.TestCid1)
|
2016-12-14 16:25:21 +00:00
|
|
|
err := cl.Pin(c)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("pin should have worked:", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// test an error case
|
|
|
|
cl.consensus.Shutdown()
|
|
|
|
err = cl.Pin(c)
|
|
|
|
if err == nil {
|
|
|
|
t.Error("expected an error but things worked")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-14 17:04:49 +00:00
|
|
|
func TestClusterUnpin(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
cl, _, _, _, _ := testingCluster(t)
|
2016-12-14 16:25:21 +00:00
|
|
|
defer cleanRaft()
|
|
|
|
defer cl.Shutdown()
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
c, _ := cid.Decode(test.TestCid1)
|
2016-12-14 16:25:21 +00:00
|
|
|
err := cl.Unpin(c)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("pin should have worked:", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// test an error case
|
|
|
|
cl.consensus.Shutdown()
|
|
|
|
err = cl.Unpin(c)
|
|
|
|
if err == nil {
|
|
|
|
t.Error("expected an error but things worked")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-26 18:59:31 +00:00
|
|
|
func TestClusterPeers(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
cl, _, _, _, _ := testingCluster(t)
|
2016-12-14 16:25:21 +00:00
|
|
|
defer cleanRaft()
|
|
|
|
defer cl.Shutdown()
|
2017-01-26 18:59:31 +00:00
|
|
|
peers := cl.Peers()
|
|
|
|
if len(peers) != 1 {
|
|
|
|
t.Fatal("expected 1 peer")
|
|
|
|
}
|
|
|
|
if peers[0].ID != testingConfig().ID {
|
|
|
|
t.Error("bad member")
|
2016-12-14 16:25:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestVersion(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
cl, _, _, _, _ := testingCluster(t)
|
2016-12-14 16:25:21 +00:00
|
|
|
defer cleanRaft()
|
|
|
|
defer cl.Shutdown()
|
|
|
|
if cl.Version() != Version {
|
|
|
|
t.Error("bad Version()")
|
|
|
|
}
|
|
|
|
}
|