Support --local parameter for Status[Local] and Sync[Local] operations

This allows to call the Rest API's status and sync endpoints with a
"?local=true" parameter. This will trigger operations but only on the
local peer. Cluster *Local and RPC-*Local methods have been accordingly,
although they are aliases for the PinTracker methods (but otherwise they
would not be exposed in external APIs). ipfs-cluster-ctl has been updated to
support the new flag.

The rationaly behind this feature is that sometimes, a single cluster peer
(or the ipfs daemon in it) is misbehaving. The user then wants to Sync,
Recover, or see Status for that single peer. This is specially relevant
when working with big pinsets in larger clusters, as a Status() call will
be considerably more expensive when broadcasted everywhere.

Note that the Rest API keeps returning GlobalPinInfo objects even on local=true
calls. This ensures that the user always gets the same datatype from an endpoint.

License: MIT
Signed-off-by: Hector Sanjuan <code@hector.link>
This commit is contained in:
Hector Sanjuan 2017-12-01 12:56:26 +01:00
parent e824aea55e
commit 4922c95589
6 changed files with 356 additions and 120 deletions

View File

@ -426,46 +426,98 @@ func (api *API) allocationHandler(w http.ResponseWriter, r *http.Request) {
}
func (api *API) statusAllHandler(w http.ResponseWriter, r *http.Request) {
var pinInfos []types.GlobalPinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"StatusAll",
struct{}{},
&pinInfos)
sendResponse(w, err, pinInfos)
queryValues := r.URL.Query()
local := queryValues.Get("local")
if local == "true" {
var pinInfos []types.PinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"StatusAllLocal",
struct{}{},
&pinInfos)
sendResponse(w, err, pinInfosToGlobal(pinInfos))
} else {
var pinInfos []types.GlobalPinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"StatusAll",
struct{}{},
&pinInfos)
sendResponse(w, err, pinInfos)
}
}
func (api *API) statusHandler(w http.ResponseWriter, r *http.Request) {
queryValues := r.URL.Query()
local := queryValues.Get("local")
if c := parseCidOrError(w, r); c.Cid != "" {
var pinInfo types.GlobalPinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"Status",
c,
&pinInfo)
sendResponse(w, err, pinInfo)
if local == "true" {
var pinInfo types.PinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"StatusLocal",
c,
&pinInfo)
sendResponse(w, err, pinInfoToGlobal(pinInfo))
} else {
var pinInfo types.GlobalPinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"Status",
c,
&pinInfo)
sendResponse(w, err, pinInfo)
}
}
}
func (api *API) syncAllHandler(w http.ResponseWriter, r *http.Request) {
var pinInfos []types.GlobalPinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"SyncAll",
struct{}{},
&pinInfos)
sendResponse(w, err, pinInfos)
queryValues := r.URL.Query()
local := queryValues.Get("local")
if local == "true" {
var pinInfos []types.PinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"SyncAllLocal",
struct{}{},
&pinInfos)
sendResponse(w, err, pinInfosToGlobal(pinInfos))
} else {
var pinInfos []types.GlobalPinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"SyncAll",
struct{}{},
&pinInfos)
sendResponse(w, err, pinInfos)
}
}
func (api *API) syncHandler(w http.ResponseWriter, r *http.Request) {
queryValues := r.URL.Query()
local := queryValues.Get("local")
if c := parseCidOrError(w, r); c.Cid != "" {
var pinInfo types.GlobalPinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"Sync",
c,
&pinInfo)
sendResponse(w, err, pinInfo)
if local == "true" {
var pinInfo types.PinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"SyncLocal",
c,
&pinInfo)
sendResponse(w, err, pinInfoToGlobal(pinInfo))
} else {
var pinInfo types.GlobalPinInfoSerial
err := api.rpcClient.Call("",
"Cluster",
"Sync",
c,
&pinInfo)
sendResponse(w, err, pinInfo)
}
}
}
@ -479,21 +531,17 @@ func (api *API) recoverAllHandler(w http.ResponseWriter, r *http.Request) {
"RecoverAllLocal",
struct{}{},
&pinInfos)
sendResponse(w, err, pinInfos)
sendResponse(w, err, pinInfosToGlobal(pinInfos))
} else {
sendErrorResponse(w, 400, "only requests with parameter local=true are supported")
}
}
func (api *API) recoverHandler(w http.ResponseWriter, r *http.Request) {
queryValues := r.URL.Query()
local := queryValues.Get("local")
if c := parseCidOrError(w, r); c.Cid != "" {
queryValues := r.URL.Query()
local := queryValues.Get("local")
// Is it RESTful to return two different types
// depending on a flag? Should PinInfo
// be converted to a GlobalPinInfo ?
if local == "true" {
var pinInfo types.PinInfoSerial
err := api.rpcClient.Call("",
@ -501,7 +549,7 @@ func (api *API) recoverHandler(w http.ResponseWriter, r *http.Request) {
"RecoverLocal",
c,
&pinInfo)
sendResponse(w, err, pinInfo)
sendResponse(w, err, pinInfoToGlobal(pinInfo))
} else {
var pinInfo types.GlobalPinInfoSerial
err := api.rpcClient.Call("",
@ -548,6 +596,23 @@ func parsePidOrError(w http.ResponseWriter, r *http.Request) peer.ID {
return pid
}
func pinInfoToGlobal(pInfo types.PinInfoSerial) types.GlobalPinInfoSerial {
return types.GlobalPinInfoSerial{
Cid: pInfo.Cid,
PeerMap: map[string]types.PinInfoSerial{
pInfo.Peer: pInfo,
},
}
}
func pinInfosToGlobal(pInfos []types.PinInfoSerial) []types.GlobalPinInfoSerial {
gPInfos := make([]types.GlobalPinInfoSerial, len(pInfos), len(pInfos))
for i, p := range pInfos {
gPInfos[i] = pinInfoToGlobal(p)
}
return gPInfos
}
func sendResponse(w http.ResponseWriter, rpcErr error, resp interface{}) {
if checkRPCErr(w, rpcErr) {
sendJSONResponse(w, 200, resp)

View File

@ -232,7 +232,14 @@ func TestAPIStatusAllEndpoint(t *testing.T) {
if len(resp) != 3 ||
resp[0].Cid != test.TestCid1 ||
resp[1].PeerMap[test.TestPeerID1.Pretty()].Status != "pinning" {
t.Errorf("unexpected statusResp:\n %+v", resp)
t.Errorf("unexpected statusAll resp:\n %+v", resp)
}
// Test local=true
var resp2 []api.GlobalPinInfoSerial
makeGet(t, "/pins?local=true", &resp2)
if len(resp2) != 2 {
t.Errorf("unexpected statusAll+local resp:\n %+v", resp)
}
}
@ -253,6 +260,21 @@ func TestAPIStatusEndpoint(t *testing.T) {
if info.Status != "pinned" {
t.Error("expected different status")
}
// Test local=true
var resp2 api.GlobalPinInfoSerial
makeGet(t, "/pins/"+test.TestCid1+"?local=true", &resp2)
if resp2.Cid != test.TestCid1 {
t.Error("expected the same cid")
}
info, ok = resp2.PeerMap[test.TestPeerID2.Pretty()]
if !ok {
t.Fatal("expected info for test.TestPeerID2")
}
if info.Status != "pinned" {
t.Error("expected different status")
}
}
func TestAPISyncAllEndpoint(t *testing.T) {
@ -265,7 +287,15 @@ func TestAPISyncAllEndpoint(t *testing.T) {
if len(resp) != 3 ||
resp[0].Cid != test.TestCid1 ||
resp[1].PeerMap[test.TestPeerID1.Pretty()].Status != "pinning" {
t.Errorf("unexpected statusResp:\n %+v", resp)
t.Errorf("unexpected syncAll resp:\n %+v", resp)
}
// Test local=true
var resp2 []api.GlobalPinInfoSerial
makePost(t, "/pins/sync?local=true", []byte{}, &resp2)
if len(resp2) != 2 {
t.Errorf("unexpected syncAll+local resp:\n %+v", resp2)
}
}
@ -286,6 +316,21 @@ func TestAPISyncEndpoint(t *testing.T) {
if info.Status != "pinned" {
t.Error("expected different status")
}
// Test local=true
var resp2 api.GlobalPinInfoSerial
makePost(t, "/pins/"+test.TestCid1+"/sync?local=true", []byte{}, &resp2)
if resp2.Cid != test.TestCid1 {
t.Error("expected the same cid")
}
info, ok = resp2.PeerMap[test.TestPeerID2.Pretty()]
if !ok {
t.Fatal("expected info for test.TestPeerID2")
}
if info.Status != "pinned" {
t.Error("expected different status")
}
}
func TestAPIRecoverEndpoint(t *testing.T) {
@ -311,7 +356,7 @@ func TestAPIRecoverAllEndpoint(t *testing.T) {
rest := testAPI(t)
defer rest.Shutdown()
var resp []api.PinInfoSerial
var resp []api.GlobalPinInfoSerial
makePost(t, "/pins/recover?local=true", []byte{}, &resp)
if len(resp) != 0 {

View File

@ -835,20 +835,40 @@ func (c *Cluster) StateSync() ([]api.PinInfo, error) {
return infos, nil
}
// StatusAll returns the GlobalPinInfo for all tracked Cids. If an error
// happens, the slice will contain as much information as could be fetched.
// StatusAll returns the GlobalPinInfo for all tracked Cids in all peers.
// If an error happens, the slice will contain as much information as
// could be fetched from other peers.
func (c *Cluster) StatusAll() ([]api.GlobalPinInfo, error) {
return c.globalPinInfoSlice("TrackerStatusAll")
}
// Status returns the GlobalPinInfo for a given Cid. If an error happens,
// the GlobalPinInfo should contain as much information as could be fetched.
// StatusAllLocal returns the PinInfo for all the tracked Cids in this peer.
func (c *Cluster) StatusAllLocal() []api.PinInfo {
return c.tracker.StatusAll()
}
// Status returns the GlobalPinInfo for a given Cid as fetched from all
// current peers. If an error happens, the GlobalPinInfo should contain
// as much information as could be fetched from the other peers.
func (c *Cluster) Status(h *cid.Cid) (api.GlobalPinInfo, error) {
return c.globalPinInfoCid("TrackerStatus", h)
}
// StatusLocal returns this peer's PinInfo for a given Cid.
func (c *Cluster) StatusLocal(h *cid.Cid) api.PinInfo {
return c.tracker.Status(h)
}
// SyncAll triggers SyncAllLocal() operations in all cluster peers, making sure
// that the state of tracked items matches the state reported by the IPFS daemon
// and returning the results as GlobalPinInfo. If an error happens, the slice
// will contain as much information as could be fetched from the peers.
func (c *Cluster) SyncAll() ([]api.GlobalPinInfo, error) {
return c.globalPinInfoSlice("SyncAllLocal")
}
// SyncAllLocal makes sure that the current state for all tracked items
// matches the state reported by the IPFS daemon.
// in this peer matches the state reported by the IPFS daemon.
//
// SyncAllLocal returns the list of PinInfo that where updated because of
// the operation, along with those in error states.
@ -863,6 +883,12 @@ func (c *Cluster) SyncAllLocal() ([]api.PinInfo, error) {
return syncedItems, err
}
// Sync triggers a LocalSyncCid() operation for a given Cid
// in all cluster peers.
func (c *Cluster) Sync(h *cid.Cid) (api.GlobalPinInfo, error) {
return c.globalPinInfoCid("SyncLocal", h)
}
// SyncLocal performs a local sync operation for the given Cid. This will
// tell the tracker to verify the status of the Cid against the IPFS daemon.
// It returns the updated PinInfo for the Cid.
@ -878,23 +904,7 @@ func (c *Cluster) SyncLocal(h *cid.Cid) (api.PinInfo, error) {
return pInfo, err
}
// SyncAll triggers LocalSync() operations in all cluster peers.
func (c *Cluster) SyncAll() ([]api.GlobalPinInfo, error) {
return c.globalPinInfoSlice("SyncAllLocal")
}
// Sync triggers a LocalSyncCid() operation for a given Cid
// in all cluster peers.
func (c *Cluster) Sync(h *cid.Cid) (api.GlobalPinInfo, error) {
return c.globalPinInfoCid("SyncLocal", h)
}
// RecoverLocal triggers a recover operation for a given Cid.
func (c *Cluster) RecoverLocal(h *cid.Cid) (api.PinInfo, error) {
return c.tracker.Recover(h)
}
// RecoverAllLocal triggers a recover operation for all Cids tracked
// RecoverAllLocal triggers a RecoverLocal operation for all Cids tracked
// by this peer.
func (c *Cluster) RecoverAllLocal() ([]api.PinInfo, error) {
return c.tracker.RecoverAll()
@ -906,6 +916,12 @@ func (c *Cluster) Recover(h *cid.Cid) (api.GlobalPinInfo, error) {
return c.globalPinInfoCid("TrackerRecover", h)
}
// RecoverLocal triggers a recover operation for a given Cid in this peer only.
// It returns the updated PinInfo, after recovery.
func (c *Cluster) RecoverLocal(h *cid.Cid) (api.PinInfo, error) {
return c.tracker.Recover(h)
}
// Pins returns the list of Cids managed by Cluster and which are part
// of the current global state. This is the source of truth as to which
// pins are managed and their allocation, but does not indicate if

View File

@ -327,16 +327,27 @@ item.
The status of a CID may not be accurate. A manual sync can be triggered
with "sync".
When the --local flag is passed, it will only fetch the status from the
contacted cluster peer. By default, status will be fetched from all peers.
`,
ArgsUsage: "[CID]",
Flags: []cli.Flag{parseFlag(formatGPInfo)},
Flags: []cli.Flag{
parseFlag(formatGPInfo),
localFlag(),
},
Action: func(c *cli.Context) error {
local := "false"
if c.Bool("local") {
local = "true"
}
cidStr := c.Args().First()
if cidStr != "" {
_, err := cid.Decode(cidStr)
checkErr("parsing cid", err)
}
resp := request("GET", "/pins/"+cidStr, nil)
resp := request("GET", "/pins/"+cidStr+"?local="+local, nil)
formatResponse(c, resp)
return nil
},
@ -355,18 +366,28 @@ have changed status because of the sync or are in error state in some node,
therefore, the output should be empty if no operations were performed.
CIDs in error state may be manually recovered with "recover".
When the --local flag is passed, it will only trigger sync
operations on the contacted peer. By default, all peers will sync.
`,
ArgsUsage: "[CID]",
Flags: []cli.Flag{parseFlag(formatGPInfo)},
Flags: []cli.Flag{
parseFlag(formatGPInfo),
localFlag(),
},
Action: func(c *cli.Context) error {
local := "false"
if c.Bool("local") {
local = "true"
}
cidStr := c.Args().First()
var resp *http.Response
if cidStr != "" {
_, err := cid.Decode(cidStr)
checkErr("parsing cid", err)
resp = request("POST", "/pins/"+cidStr+"/sync", nil)
resp = request("POST", "/pins/"+cidStr+"/sync?local="+local, nil)
} else {
resp = request("POST", "/pins/sync", nil)
resp = request("POST", "/pins/sync?local="+local, nil)
}
formatResponse(c, resp)
return nil
@ -383,22 +404,18 @@ The command will wait for any operations to succeed and will return the status
of the item upon completion. Note that, when running on the full sets of tracked
CIDs (without argument), it may take considerable long time.
A --local flag must be passed. This will only trigger recover
operations on the contacted peer (and not on every peer).
When the --local flag is passed, it will only trigger recover
operations on the contacted peer (as opposed to on every peer).
`,
ArgsUsage: "[CID]",
Flags: []cli.Flag{
parseFlag(formatGPInfo),
cli.BoolFlag{
Name: "local",
Usage: "recover only on the contacted peer",
},
localFlag(),
},
Action: func(c *cli.Context) error {
local := "false"
if c.Bool("local") {
local = "true"
c.Set("parseAs", fmt.Sprintf("%d", formatPInfo))
}
cidStr := c.Args().First()
var resp *http.Response
@ -453,6 +470,13 @@ func parseFlag(t int) cli.IntFlag {
}
}
func localFlag() cli.BoolFlag {
return cli.BoolFlag{
Name: "local",
Usage: "run operation only on the contacted peer",
}
}
func walkCommands(cmds []cli.Command, parentHelpName string) {
for _, c := range cmds {
h := c.HelpName

View File

@ -108,6 +108,13 @@ func (rpcapi *RPCAPI) StatusAll(in struct{}, out *[]api.GlobalPinInfoSerial) err
return err
}
// StatusAllLocal runs Cluster.StatusAllLocal().
func (rpcapi *RPCAPI) StatusAllLocal(in struct{}, out *[]api.PinInfoSerial) error {
pinfos := rpcapi.c.StatusAllLocal()
*out = pinInfoSliceToSerial(pinfos)
return nil
}
// Status runs Cluster.Status().
func (rpcapi *RPCAPI) Status(in api.PinSerial, out *api.GlobalPinInfoSerial) error {
c := in.ToPin().Cid
@ -116,19 +123,12 @@ func (rpcapi *RPCAPI) Status(in api.PinSerial, out *api.GlobalPinInfoSerial) err
return err
}
// SyncAllLocal runs Cluster.SyncAllLocal().
func (rpcapi *RPCAPI) SyncAllLocal(in struct{}, out *[]api.PinInfoSerial) error {
pinfos, err := rpcapi.c.SyncAllLocal()
*out = pinInfoSliceToSerial(pinfos)
return err
}
// SyncLocal runs Cluster.SyncLocal().
func (rpcapi *RPCAPI) SyncLocal(in api.PinSerial, out *api.PinInfoSerial) error {
// StatusLocal runs Cluster.StatusLocal().
func (rpcapi *RPCAPI) StatusLocal(in api.PinSerial, out *api.PinInfoSerial) error {
c := in.ToPin().Cid
pinfo, err := rpcapi.c.SyncLocal(c)
pinfo := rpcapi.c.StatusLocal(c)
*out = pinfo.ToSerial()
return err
return nil
}
// SyncAll runs Cluster.SyncAll().
@ -138,6 +138,13 @@ func (rpcapi *RPCAPI) SyncAll(in struct{}, out *[]api.GlobalPinInfoSerial) error
return err
}
// SyncAllLocal runs Cluster.SyncAllLocal().
func (rpcapi *RPCAPI) SyncAllLocal(in struct{}, out *[]api.PinInfoSerial) error {
pinfos, err := rpcapi.c.SyncAllLocal()
*out = pinInfoSliceToSerial(pinfos)
return err
}
// Sync runs Cluster.Sync().
func (rpcapi *RPCAPI) Sync(in api.PinSerial, out *api.GlobalPinInfoSerial) error {
c := in.ToPin().Cid
@ -146,9 +153,17 @@ func (rpcapi *RPCAPI) Sync(in api.PinSerial, out *api.GlobalPinInfoSerial) error
return err
}
// StateSync runs Cluster.StateSync().
func (rpcapi *RPCAPI) StateSync(in struct{}, out *[]api.PinInfoSerial) error {
pinfos, err := rpcapi.c.StateSync()
// SyncLocal runs Cluster.SyncLocal().
func (rpcapi *RPCAPI) SyncLocal(in api.PinSerial, out *api.PinInfoSerial) error {
c := in.ToPin().Cid
pinfo, err := rpcapi.c.SyncLocal(c)
*out = pinfo.ToSerial()
return err
}
// RecoverAllLocal runs Cluster.RecoverAllLocal().
func (rpcapi *RPCAPI) RecoverAllLocal(in struct{}, out *[]api.PinInfoSerial) error {
pinfos, err := rpcapi.c.RecoverAllLocal()
*out = pinInfoSliceToSerial(pinfos)
return err
}
@ -169,9 +184,9 @@ func (rpcapi *RPCAPI) RecoverLocal(in api.PinSerial, out *api.PinInfoSerial) err
return err
}
// RecoverAllLocal runs Cluster.RecoverAllLocal().
func (rpcapi *RPCAPI) RecoverAllLocal(in struct{}, out *[]api.PinInfoSerial) error {
pinfos, err := rpcapi.c.RecoverAllLocal()
// StateSync runs Cluster.StateSync().
func (rpcapi *RPCAPI) StateSync(in struct{}, out *[]api.PinInfoSerial) error {
pinfos, err := rpcapi.c.StateSync()
*out = pinInfoSliceToSerial(pinfos)
return err
}
@ -205,6 +220,13 @@ func (rpcapi *RPCAPI) TrackerStatus(in api.PinSerial, out *api.PinInfoSerial) er
return nil
}
// TrackerRecoverAll runs PinTracker.RecoverAll().
func (rpcapi *RPCAPI) TrackerRecoverAll(in struct{}, out *[]api.PinInfoSerial) error {
pinfos, err := rpcapi.c.tracker.RecoverAll()
*out = pinInfoSliceToSerial(pinfos)
return err
}
// TrackerRecover runs PinTracker.Recover().
func (rpcapi *RPCAPI) TrackerRecover(in api.PinSerial, out *api.PinInfoSerial) error {
c := in.ToPin().Cid
@ -213,13 +235,6 @@ func (rpcapi *RPCAPI) TrackerRecover(in api.PinSerial, out *api.PinInfoSerial) e
return err
}
// TrackerRecoverAll runs PinTracker.RecoverAll().
func (rpcapi *RPCAPI) TrackerRecoverAll(in struct{}, out *[]api.PinInfoSerial) error {
pinfos, err := rpcapi.c.tracker.RecoverAll()
*out = pinInfoSliceToSerial(pinfos)
return err
}
/*
IPFS Connector component methods
*/

View File

@ -118,15 +118,6 @@ func (mock *mockService) PeerRemove(in peer.ID, out *struct{}) error {
return nil
}
// FIXME: dup from util.go
func globalPinInfoSliceToSerial(gpi []api.GlobalPinInfo) []api.GlobalPinInfoSerial {
gpis := make([]api.GlobalPinInfoSerial, len(gpi), len(gpi))
for i, v := range gpi {
gpis[i] = v.ToSerial()
}
return gpis
}
func (mock *mockService) StatusAll(in struct{}, out *[]api.GlobalPinInfoSerial) error {
c1, _ := cid.Decode(TestCid1)
c2, _ := cid.Decode(TestCid2)
@ -169,6 +160,10 @@ func (mock *mockService) StatusAll(in struct{}, out *[]api.GlobalPinInfoSerial)
return nil
}
func (mock *mockService) StatusAllLocal(in struct{}, out *[]api.PinInfoSerial) error {
return mock.TrackerStatusAll(in, out)
}
func (mock *mockService) Status(in api.PinSerial, out *api.GlobalPinInfoSerial) error {
if in.Cid == ErrorCid {
return ErrBadCid
@ -188,24 +183,95 @@ func (mock *mockService) Status(in api.PinSerial, out *api.GlobalPinInfoSerial)
return nil
}
func (mock *mockService) StatusLocal(in api.PinSerial, out *api.PinInfoSerial) error {
return mock.TrackerStatus(in, out)
}
func (mock *mockService) SyncAll(in struct{}, out *[]api.GlobalPinInfoSerial) error {
return mock.StatusAll(in, out)
}
func (mock *mockService) SyncAllLocal(in struct{}, out *[]api.PinInfoSerial) error {
return mock.StatusAllLocal(in, out)
}
func (mock *mockService) Sync(in api.PinSerial, out *api.GlobalPinInfoSerial) error {
return mock.Status(in, out)
}
func (mock *mockService) SyncLocal(in api.PinSerial, out *api.PinInfoSerial) error {
return mock.StatusLocal(in, out)
}
func (mock *mockService) StateSync(in struct{}, out *[]api.PinInfoSerial) error {
*out = make([]api.PinInfoSerial, 0, 0)
return nil
}
func (mock *mockService) RecoverAllLocal(in struct{}, out *[]api.PinInfoSerial) error {
return mock.TrackerRecoverAll(in, out)
}
func (mock *mockService) Recover(in api.PinSerial, out *api.GlobalPinInfoSerial) error {
return mock.Status(in, out)
}
func (mock *mockService) RecoverLocal(in api.PinSerial, out *api.PinInfoSerial) error {
return mock.TrackerRecover(in, out)
}
/* Tracker methods */
func (mock *mockService) Track(in api.PinSerial, out *struct{}) error {
return nil
}
func (mock *mockService) Untrack(in api.PinSerial, out *struct{}) error {
return nil
}
func (mock *mockService) TrackerStatusAll(in struct{}, out *[]api.PinInfoSerial) error {
c1, _ := cid.Decode(TestCid1)
c3, _ := cid.Decode(TestCid3)
*out = pinInfoSliceToSerial([]api.PinInfo{
{
Cid: c1,
Peer: TestPeerID1,
Status: api.TrackerStatusPinned,
TS: time.Now(),
},
{
Cid: c3,
Peer: TestPeerID1,
Status: api.TrackerStatusPinError,
TS: time.Now(),
},
})
return nil
}
func (mock *mockService) TrackerStatus(in api.PinSerial, out *api.PinInfoSerial) error {
if in.Cid == ErrorCid {
return ErrBadCid
}
c1, _ := cid.Decode(TestCid1)
*out = api.PinInfo{
Cid: c1,
Peer: TestPeerID2,
Status: api.TrackerStatusPinned,
TS: time.Now(),
}.ToSerial()
return nil
}
func (mock *mockService) TrackerRecoverAll(in struct{}, out *[]api.PinInfoSerial) error {
*out = make([]api.PinInfoSerial, 0, 0)
return nil
}
func (mock *mockService) TrackerRecover(in api.PinSerial, out *api.PinInfoSerial) error {
in2 := in.ToPin()
*out = api.PinInfo{
Cid: in2.Cid,
@ -216,19 +282,6 @@ func (mock *mockService) RecoverLocal(in api.PinSerial, out *api.PinInfoSerial)
return nil
}
func (mock *mockService) RecoverAllLocal(in struct{}, out *[]api.PinInfoSerial) error {
*out = make([]api.PinInfoSerial, 0, 0)
return nil
}
func (mock *mockService) Track(in api.PinSerial, out *struct{}) error {
return nil
}
func (mock *mockService) Untrack(in api.PinSerial, out *struct{}) error {
return nil
}
/* PeerManager methods */
func (mock *mockService) PeerManagerAddPeer(in api.MultiaddrSerial, out *struct{}) error {
@ -301,3 +354,21 @@ func (mock *mockService) ConsensusPeers(in struct{}, out *[]peer.ID) error {
*out = []peer.ID{TestPeerID1, TestPeerID2, TestPeerID3}
return nil
}
// FIXME: dup from util.go
func globalPinInfoSliceToSerial(gpi []api.GlobalPinInfo) []api.GlobalPinInfoSerial {
gpis := make([]api.GlobalPinInfoSerial, len(gpi), len(gpi))
for i, v := range gpi {
gpis[i] = v.ToSerial()
}
return gpis
}
// FIXME: dup from util.go
func pinInfoSliceToSerial(pi []api.PinInfo) []api.PinInfoSerial {
pis := make([]api.PinInfoSerial, len(pi), len(pi))
for i, v := range pi {
pis[i] = v.ToSerial()
}
return pis
}