ipfs-cluster/ipfsmock_test.go
Hector Sanjuan f0c5350743 Get remote RPC requests working. First e2e tests.
License: MIT
Signed-off-by: Hector Sanjuan <hector@protocol.ai>
2016-12-16 22:00:08 +01:00

148 lines
2.6 KiB
Go

package ipfscluster
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"strconv"
"strings"
cid "github.com/ipfs/go-cid"
)
// This is an ipfs daemon mock which should sustain the functionality used by
// ipfscluster.
type ipfsMock struct {
server *httptest.Server
addr string
port int
pinMap *MapState
}
type mockPinResp struct {
Pins []string
}
type mockPinType struct {
Type string
}
type mockPinLsResp struct {
Keys map[string]mockPinType
}
type ipfsErr struct {
Code int
Message string
}
func newIpfsMock() *ipfsMock {
st := NewMapState()
m := &ipfsMock{
pinMap: st,
}
ts := httptest.NewServer(http.HandlerFunc(m.handler))
m.server = ts
url, _ := url.Parse(ts.URL)
h := strings.Split(url.Host, ":")
i, _ := strconv.Atoi(h[1])
m.port = i
m.addr = h[0]
return m
}
// FIXME: what if IPFS API changes?
func (m *ipfsMock) handler(w http.ResponseWriter, r *http.Request) {
p := r.URL.Path
endp := strings.TrimPrefix(p, "/api/v0/")
var cidStr string
switch endp {
case "pin/add":
query := r.URL.Query()
arg, ok := query["arg"]
if !ok || len(arg) != 1 {
goto ERROR
}
cidStr = arg[0]
if cidStr == errorCid {
goto ERROR
}
c, err := cid.Decode(cidStr)
if err != nil {
goto ERROR
}
m.pinMap.AddPin(c)
resp := mockPinResp{
Pins: []string{cidStr},
}
j, _ := json.Marshal(resp)
w.Write(j)
case "pin/rm":
query := r.URL.Query()
arg, ok := query["arg"]
if !ok || len(arg) != 1 {
goto ERROR
}
cidStr = arg[0]
c, err := cid.Decode(cidStr)
if err != nil {
goto ERROR
}
m.pinMap.RmPin(c)
resp := mockPinResp{
Pins: []string{cidStr},
}
j, _ := json.Marshal(resp)
w.Write(j)
case "pin/ls":
query := r.URL.Query()
arg, ok := query["arg"]
if !ok {
rMap := make(map[string]mockPinType)
pins := m.pinMap.ListPins()
for _, p := range pins {
rMap[p.String()] = mockPinType{"recursive"}
}
j, _ := json.Marshal(mockPinLsResp{rMap})
w.Write(j)
break
}
if len(arg) != 1 {
goto ERROR
}
cidStr = arg[0]
c, err := cid.Decode(cidStr)
if err != nil {
goto ERROR
}
ok = m.pinMap.HasPin(c)
if ok {
rMap := make(map[string]mockPinType)
rMap[cidStr] = mockPinType{"recursive"}
j, _ := json.Marshal(mockPinLsResp{rMap})
w.Write(j)
} else {
w.WriteHeader(http.StatusInternalServerError)
resp := ipfsErr{0, fmt.Sprintf("Path '%s' is not pinned", cidStr)}
j, _ := json.Marshal(resp)
w.Write(j)
}
default:
w.WriteHeader(http.StatusNotFound)
}
return
ERROR:
w.WriteHeader(http.StatusInternalServerError)
}
func (m *ipfsMock) Close() {
m.server.Close()
}