2016-12-08 16:24:38 +00:00
|
|
|
package ipfscluster
|
|
|
|
|
|
|
|
import (
|
2017-01-26 21:49:53 +00:00
|
|
|
"encoding/json"
|
2016-12-08 16:24:38 +00:00
|
|
|
"fmt"
|
2017-01-26 21:49:53 +00:00
|
|
|
"io/ioutil"
|
2016-12-08 16:24:38 +00:00
|
|
|
"net/http"
|
|
|
|
"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/test"
|
2017-02-08 17:04:08 +00:00
|
|
|
|
2016-12-16 11:40:28 +00:00
|
|
|
cid "github.com/ipfs/go-cid"
|
2017-01-23 17:38:59 +00:00
|
|
|
ma "github.com/multiformats/go-multiaddr"
|
2016-12-08 16:24:38 +00:00
|
|
|
)
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
func testIPFSConnectorConfig(mock *test.IpfsMock) *Config {
|
2016-12-14 14:31:50 +00:00
|
|
|
cfg := testingConfig()
|
2017-02-09 15:29:17 +00:00
|
|
|
addr, _ := ma.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d", mock.Addr, mock.Port))
|
2017-01-23 17:38:59 +00:00
|
|
|
cfg.IPFSNodeAddr = addr
|
2016-12-14 14:31:50 +00:00
|
|
|
return cfg
|
2016-12-08 16:24:38 +00:00
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
func testIPFSConnector(t *testing.T) (*IPFSHTTPConnector, *test.IpfsMock) {
|
|
|
|
mock := test.NewIpfsMock()
|
2016-12-16 16:22:37 +00:00
|
|
|
cfg := testIPFSConnectorConfig(mock)
|
2016-12-08 16:24:38 +00:00
|
|
|
|
|
|
|
ipfs, err := NewIPFSHTTPConnector(cfg)
|
|
|
|
if err != nil {
|
2016-12-08 18:04:28 +00:00
|
|
|
t.Fatal("creating an IPFSConnector should work: ", err)
|
2016-12-08 16:24:38 +00:00
|
|
|
}
|
2017-02-09 15:29:17 +00:00
|
|
|
ipfs.SetClient(test.NewMockRPCClient(t))
|
2016-12-16 16:22:37 +00:00
|
|
|
return ipfs, mock
|
2016-12-08 18:04:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestNewIPFSHTTPConnector(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
ipfs, mock := testIPFSConnector(t)
|
2016-12-16 16:22:37 +00:00
|
|
|
defer mock.Close()
|
2016-12-08 18:04:28 +00:00
|
|
|
defer ipfs.Shutdown()
|
|
|
|
}
|
2016-12-08 16:24:38 +00:00
|
|
|
|
2017-01-26 18:59:31 +00:00
|
|
|
func TestIPFSID(t *testing.T) {
|
|
|
|
ipfs, mock := testIPFSConnector(t)
|
|
|
|
defer ipfs.Shutdown()
|
|
|
|
id, err := ipfs.ID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-02-09 15:29:17 +00:00
|
|
|
if id.ID != test.TestPeerID1 {
|
2017-01-26 18:59:31 +00:00
|
|
|
t.Error("expected testPeerID")
|
|
|
|
}
|
|
|
|
if len(id.Addresses) != 1 {
|
|
|
|
t.Error("expected 1 address")
|
|
|
|
}
|
|
|
|
if id.Error != "" {
|
|
|
|
t.Error("expected no error")
|
|
|
|
}
|
|
|
|
mock.Close()
|
|
|
|
id, err = ipfs.ID()
|
|
|
|
if err == nil {
|
|
|
|
t.Error("expected an error")
|
|
|
|
}
|
|
|
|
if id.Error != err.Error() {
|
|
|
|
t.Error("error messages should match")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-15 13:07:19 +00:00
|
|
|
func TestIPFSPin(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
ipfs, mock := testIPFSConnector(t)
|
2016-12-16 16:22:37 +00:00
|
|
|
defer mock.Close()
|
2016-12-08 18:04:28 +00:00
|
|
|
defer ipfs.Shutdown()
|
2017-02-09 15:29:17 +00:00
|
|
|
c, _ := cid.Decode(test.TestCid1)
|
2016-12-08 18:04:28 +00:00
|
|
|
err := ipfs.Pin(c)
|
2016-12-08 16:24:38 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Error("expected success pinning cid")
|
|
|
|
}
|
2017-01-25 17:07:19 +00:00
|
|
|
pinSt, err := ipfs.PinLsCid(c)
|
2016-12-16 16:22:37 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal("expected success doing ls")
|
|
|
|
}
|
2017-01-25 17:07:19 +00:00
|
|
|
if !pinSt.IsPinned() {
|
2016-12-16 16:22:37 +00:00
|
|
|
t.Error("cid should have been pinned")
|
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
c2, _ := cid.Decode(test.ErrorCid)
|
2016-12-08 16:24:38 +00:00
|
|
|
err = ipfs.Pin(c2)
|
|
|
|
if err == nil {
|
|
|
|
t.Error("expected error pinning cid")
|
|
|
|
}
|
2016-12-08 18:04:28 +00:00
|
|
|
}
|
2016-12-08 16:24:38 +00:00
|
|
|
|
2016-12-15 13:07:19 +00:00
|
|
|
func TestIPFSUnpin(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
ipfs, mock := testIPFSConnector(t)
|
2016-12-16 16:22:37 +00:00
|
|
|
defer mock.Close()
|
2016-12-08 18:04:28 +00:00
|
|
|
defer ipfs.Shutdown()
|
2017-02-09 15:29:17 +00:00
|
|
|
c, _ := cid.Decode(test.TestCid1)
|
2016-12-08 18:04:28 +00:00
|
|
|
err := ipfs.Unpin(c)
|
2016-12-08 16:24:38 +00:00
|
|
|
if err != nil {
|
2016-12-16 16:22:37 +00:00
|
|
|
t.Error("expected success unpinning non-pinned cid")
|
2016-12-08 16:24:38 +00:00
|
|
|
}
|
2016-12-16 16:22:37 +00:00
|
|
|
ipfs.Pin(c)
|
|
|
|
err = ipfs.Unpin(c)
|
2016-12-08 16:24:38 +00:00
|
|
|
if err != nil {
|
2016-12-16 16:22:37 +00:00
|
|
|
t.Error("expected success unpinning pinned cid")
|
2016-12-08 16:24:38 +00:00
|
|
|
}
|
2016-12-08 18:04:28 +00:00
|
|
|
}
|
|
|
|
|
2017-01-25 17:07:19 +00:00
|
|
|
func TestIPFSPinLsCid(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
ipfs, mock := testIPFSConnector(t)
|
2016-12-16 16:22:37 +00:00
|
|
|
defer mock.Close()
|
2016-12-08 18:04:28 +00:00
|
|
|
defer ipfs.Shutdown()
|
2017-02-09 15:29:17 +00:00
|
|
|
c, _ := cid.Decode(test.TestCid1)
|
|
|
|
c2, _ := cid.Decode(test.TestCid2)
|
2016-12-08 16:24:38 +00:00
|
|
|
|
2016-12-16 16:22:37 +00:00
|
|
|
ipfs.Pin(c)
|
2017-01-25 17:07:19 +00:00
|
|
|
ips, err := ipfs.PinLsCid(c)
|
|
|
|
if err != nil || !ips.IsPinned() {
|
2016-12-08 16:24:38 +00:00
|
|
|
t.Error("c should appear pinned")
|
|
|
|
}
|
|
|
|
|
2017-01-25 17:07:19 +00:00
|
|
|
ips, err = ipfs.PinLsCid(c2)
|
2017-02-08 17:04:08 +00:00
|
|
|
if err != nil || ips != api.IPFSPinStatusUnpinned {
|
2016-12-08 16:24:38 +00:00
|
|
|
t.Error("c2 should appear unpinned")
|
|
|
|
}
|
2016-12-08 18:04:28 +00:00
|
|
|
}
|
|
|
|
|
2017-01-25 17:07:19 +00:00
|
|
|
func TestIPFSPinLs(t *testing.T) {
|
|
|
|
ipfs, mock := testIPFSConnector(t)
|
|
|
|
defer mock.Close()
|
|
|
|
defer ipfs.Shutdown()
|
2017-02-09 15:29:17 +00:00
|
|
|
c, _ := cid.Decode(test.TestCid1)
|
|
|
|
c2, _ := cid.Decode(test.TestCid2)
|
2017-01-25 17:07:19 +00:00
|
|
|
|
|
|
|
ipfs.Pin(c)
|
|
|
|
ipfs.Pin(c2)
|
2017-02-09 15:29:17 +00:00
|
|
|
ipsMap, err := ipfs.PinLs("")
|
2017-01-25 17:07:19 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Error("should not error")
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(ipsMap) != 2 {
|
|
|
|
t.Fatal("the map does not contain expected keys")
|
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
if !ipsMap[test.TestCid1].IsPinned() || !ipsMap[test.TestCid2].IsPinned() {
|
2017-01-25 17:07:19 +00:00
|
|
|
t.Error("c1 and c2 should appear pinned")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-26 21:49:53 +00:00
|
|
|
func TestIPFSProxyVersion(t *testing.T) {
|
|
|
|
// This makes sure default handler is used
|
|
|
|
|
|
|
|
ipfs, mock := testIPFSConnector(t)
|
|
|
|
defer mock.Close()
|
|
|
|
defer ipfs.Shutdown()
|
|
|
|
|
|
|
|
cfg := testingConfig()
|
|
|
|
host, _ := cfg.IPFSProxyAddr.ValueForProtocol(ma.P_IP4)
|
|
|
|
port, _ := cfg.IPFSProxyAddr.ValueForProtocol(ma.P_TCP)
|
|
|
|
res, err := http.Get(fmt.Sprintf("http://%s:%s/api/v0/version",
|
|
|
|
host,
|
|
|
|
port))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("should forward requests to ipfs host: ", err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
t.Error("the request should have succeeded")
|
|
|
|
}
|
|
|
|
|
|
|
|
defer res.Body.Close()
|
|
|
|
resBytes, _ := ioutil.ReadAll(res.Body)
|
|
|
|
|
|
|
|
var resp struct {
|
|
|
|
Version string
|
|
|
|
}
|
|
|
|
err = json.Unmarshal(resBytes, &resp)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if resp.Version != "m.o.c.k" {
|
|
|
|
t.Error("wrong version")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestIPFSProxyPin(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
ipfs, mock := testIPFSConnector(t)
|
2016-12-16 16:22:37 +00:00
|
|
|
defer mock.Close()
|
2016-12-08 18:04:28 +00:00
|
|
|
defer ipfs.Shutdown()
|
2016-12-08 16:24:38 +00:00
|
|
|
|
2016-12-16 16:22:37 +00:00
|
|
|
cfg := testingConfig()
|
2017-01-23 17:38:59 +00:00
|
|
|
host, _ := cfg.IPFSProxyAddr.ValueForProtocol(ma.P_IP4)
|
|
|
|
port, _ := cfg.IPFSProxyAddr.ValueForProtocol(ma.P_TCP)
|
2017-01-26 21:49:53 +00:00
|
|
|
res, err := http.Get(fmt.Sprintf("http://%s:%s/api/v0/pin/add?arg=%s",
|
2017-01-23 17:38:59 +00:00
|
|
|
host,
|
|
|
|
port,
|
2017-02-09 15:29:17 +00:00
|
|
|
test.TestCid1))
|
2016-12-08 16:24:38 +00:00
|
|
|
if err != nil {
|
2017-01-26 21:49:53 +00:00
|
|
|
t.Fatal("should have succeeded: ", err)
|
2016-12-08 16:24:38 +00:00
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
t.Error("the request should have succeeded")
|
|
|
|
}
|
2017-01-26 21:49:53 +00:00
|
|
|
resBytes, _ := ioutil.ReadAll(res.Body)
|
|
|
|
|
|
|
|
var resp ipfsPinOpResp
|
|
|
|
err = json.Unmarshal(resBytes, &resp)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
if len(resp.Pins) != 1 || resp.Pins[0] != test.TestCid1 {
|
2017-01-26 21:49:53 +00:00
|
|
|
t.Error("wrong response")
|
|
|
|
}
|
|
|
|
res.Body.Close()
|
|
|
|
|
|
|
|
// Try with a bad cid
|
|
|
|
res, err = http.Get(fmt.Sprintf("http://%s:%s/api/v0/pin/add?arg=%s",
|
|
|
|
host,
|
|
|
|
port,
|
2017-02-09 15:29:17 +00:00
|
|
|
test.ErrorCid))
|
2017-01-26 21:49:53 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal("request should work: ", err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusInternalServerError {
|
|
|
|
t.Error("the request should return with InternalServerError")
|
|
|
|
}
|
|
|
|
|
|
|
|
resBytes, _ = ioutil.ReadAll(res.Body)
|
|
|
|
var respErr ipfsError
|
|
|
|
err = json.Unmarshal(resBytes, &respErr)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
if respErr.Message != test.ErrBadCid.Error() {
|
2017-01-26 21:49:53 +00:00
|
|
|
t.Error("wrong response")
|
|
|
|
}
|
|
|
|
res.Body.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestIPFSProxyUnpin(t *testing.T) {
|
|
|
|
ipfs, mock := testIPFSConnector(t)
|
|
|
|
defer mock.Close()
|
|
|
|
defer ipfs.Shutdown()
|
|
|
|
|
|
|
|
cfg := testingConfig()
|
|
|
|
host, _ := cfg.IPFSProxyAddr.ValueForProtocol(ma.P_IP4)
|
|
|
|
port, _ := cfg.IPFSProxyAddr.ValueForProtocol(ma.P_TCP)
|
|
|
|
res, err := http.Get(fmt.Sprintf("http://%s:%s/api/v0/pin/rm?arg=%s",
|
|
|
|
host,
|
|
|
|
port,
|
2017-02-09 15:29:17 +00:00
|
|
|
test.TestCid1))
|
2017-01-26 21:49:53 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal("should have succeeded: ", err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
t.Error("the request should have succeeded")
|
|
|
|
}
|
|
|
|
|
|
|
|
resBytes, _ := ioutil.ReadAll(res.Body)
|
|
|
|
|
|
|
|
var resp ipfsPinOpResp
|
|
|
|
err = json.Unmarshal(resBytes, &resp)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
if len(resp.Pins) != 1 || resp.Pins[0] != test.TestCid1 {
|
2017-01-26 21:49:53 +00:00
|
|
|
t.Error("wrong response")
|
|
|
|
}
|
|
|
|
res.Body.Close()
|
|
|
|
|
|
|
|
// Try with a bad cid
|
|
|
|
res, err = http.Get(fmt.Sprintf("http://%s:%s/api/v0/pin/rm?arg=%s",
|
|
|
|
host,
|
|
|
|
port,
|
2017-02-09 15:29:17 +00:00
|
|
|
test.ErrorCid))
|
2017-01-26 21:49:53 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal("request should work: ", err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusInternalServerError {
|
|
|
|
t.Error("the request should return with InternalServerError")
|
|
|
|
}
|
|
|
|
|
|
|
|
resBytes, _ = ioutil.ReadAll(res.Body)
|
|
|
|
var respErr ipfsError
|
|
|
|
err = json.Unmarshal(resBytes, &respErr)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
if respErr.Message != test.ErrBadCid.Error() {
|
2017-01-26 21:49:53 +00:00
|
|
|
t.Error("wrong response")
|
|
|
|
}
|
|
|
|
res.Body.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestIPFSProxyPinLs(t *testing.T) {
|
|
|
|
ipfs, mock := testIPFSConnector(t)
|
|
|
|
defer mock.Close()
|
|
|
|
defer ipfs.Shutdown()
|
|
|
|
|
|
|
|
cfg := testingConfig()
|
|
|
|
host, _ := cfg.IPFSProxyAddr.ValueForProtocol(ma.P_IP4)
|
|
|
|
port, _ := cfg.IPFSProxyAddr.ValueForProtocol(ma.P_TCP)
|
|
|
|
res, err := http.Get(fmt.Sprintf("http://%s:%s/api/v0/pin/ls?arg=%s",
|
|
|
|
host,
|
|
|
|
port,
|
2017-02-09 15:29:17 +00:00
|
|
|
test.TestCid1))
|
2017-01-26 21:49:53 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal("should have succeeded: ", err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
t.Error("the request should have succeeded")
|
|
|
|
}
|
|
|
|
|
|
|
|
resBytes, _ := ioutil.ReadAll(res.Body)
|
|
|
|
|
|
|
|
var resp ipfsPinLsResp
|
|
|
|
err = json.Unmarshal(resBytes, &resp)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-02-09 15:29:17 +00:00
|
|
|
_, ok := resp.Keys[test.TestCid1]
|
2017-01-26 21:49:53 +00:00
|
|
|
if len(resp.Keys) != 1 || !ok {
|
|
|
|
t.Error("wrong response")
|
|
|
|
}
|
|
|
|
res.Body.Close()
|
|
|
|
|
|
|
|
res, err = http.Get(fmt.Sprintf("http://%s:%s/api/v0/pin/ls",
|
|
|
|
host,
|
|
|
|
port))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("should have succeeded: ", err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
t.Error("the request should have succeeded")
|
|
|
|
}
|
|
|
|
|
|
|
|
resBytes, _ = ioutil.ReadAll(res.Body)
|
|
|
|
err = json.Unmarshal(resBytes, &resp)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(resp.Keys) != 3 {
|
|
|
|
t.Error("wrong response")
|
|
|
|
}
|
|
|
|
res.Body.Close()
|
2016-12-08 18:04:28 +00:00
|
|
|
}
|
2016-12-08 16:24:38 +00:00
|
|
|
|
2016-12-15 13:07:19 +00:00
|
|
|
func TestIPFSShutdown(t *testing.T) {
|
2016-12-23 18:35:37 +00:00
|
|
|
ipfs, mock := testIPFSConnector(t)
|
2016-12-16 16:22:37 +00:00
|
|
|
defer mock.Close()
|
2016-12-08 16:24:38 +00:00
|
|
|
if err := ipfs.Shutdown(); err != nil {
|
|
|
|
t.Error("expected a clean shutdown")
|
|
|
|
}
|
2016-12-16 16:22:37 +00:00
|
|
|
if err := ipfs.Shutdown(); err != nil {
|
|
|
|
t.Error("expected a second clean shutdown")
|
|
|
|
}
|
2016-12-08 16:24:38 +00:00
|
|
|
}
|