diff --git a/pintracker/optracker/operationtracker.go b/pintracker/optracker/operationtracker.go index e469753a..43902264 100644 --- a/pintracker/optracker/operationtracker.go +++ b/pintracker/optracker/operationtracker.go @@ -103,14 +103,11 @@ func (opt *OperationTracker) SetError(c cid.Cid, err error) { return } - ph := op.Phase() - ty := op.Type() - - if ty == OperationRemote { + if ty := op.Type(); ty == OperationRemote { return } - if ph == PhaseDone || ph == PhaseError { + if ph := op.Phase(); ph == PhaseDone || ph == PhaseError { op.SetPhase(PhaseError) op.SetError(err) } diff --git a/pintracker/pintracker_test.go b/pintracker/pintracker_test.go index 637c6a8a..11ffa997 100644 --- a/pintracker/pintracker_test.go +++ b/pintracker/pintracker_test.go @@ -9,6 +9,8 @@ import ( "testing" "time" + peer "github.com/libp2p/go-libp2p-peer" + ipfscluster "github.com/ipfs/ipfs-cluster" "github.com/ipfs/ipfs-cluster/api" "github.com/ipfs/ipfs-cluster/pintracker/maptracker" @@ -17,7 +19,6 @@ import ( cid "github.com/ipfs/go-cid" rpc "github.com/libp2p/go-libp2p-gorpc" - peer "github.com/libp2p/go-libp2p-peer" ) var ( @@ -60,6 +61,9 @@ func (mock *mockService) IPFSPinLsCid(ctx context.Context, in api.PinSerial, out switch in.Cid { case test.TestCid1, test.TestCid2: *out = api.IPFSPinStatusRecursive + case test.TestCid4: + *out = api.IPFSPinStatusError + return errors.New("an ipfs error") default: *out = api.IPFSPinStatusUnpinned } @@ -85,94 +89,6 @@ func (mock *mockService) IPFSPinLs(ctx context.Context, in string, out *map[stri return nil } -func (mock *mockService) Status(ctx context.Context, in api.PinSerial, out *api.GlobalPinInfoSerial) error { - switch in.Cid { - case test.ErrorCid: - return test.ErrBadCid - case test.TestCid1: - c1, _ := cid.Decode(test.TestCid1) - *out = api.GlobalPinInfo{ - Cid: c1, - PeerMap: map[peer.ID]api.PinInfo{ - test.TestPeerID1: { - Cid: c1, - Peer: test.TestPeerID1, - Status: api.TrackerStatusPinned, - TS: time.Now(), - }, - }, - }.ToSerial() - // case test.TestSlowCid1: - // sc1 := test.MustDecodeCid(test.TestSlowCid1) - // *out = api.GlobalPinInfo{ - // Cid: sc1, - // PeerMap: map[peer.ID]api.PinInfo{ - // test.TestPeerID1: { - // Cid: sc1, - // Peer: test.TestPeerID1, - // Status: api.TrackerStatusPinned, - // TS: time.Now(), - // }, - // }, - // }.ToSerial() - } - return nil -} - -func (mock *mockService) StatusAll(ctx context.Context, in struct{}, out *[]api.GlobalPinInfoSerial) error { - c1, _ := cid.Decode(test.TestCid1) - c2, _ := cid.Decode(test.TestCid2) - c3, _ := cid.Decode(test.TestCid3) - slowC1 := test.MustDecodeCid(test.TestSlowCid1) - *out = ipfscluster.GlobalPinInfoSliceToSerial([]api.GlobalPinInfo{ - { - Cid: c1, - PeerMap: map[peer.ID]api.PinInfo{ - test.TestPeerID1: { - Cid: c1, - Peer: test.TestPeerID1, - Status: api.TrackerStatusPinned, - TS: time.Now(), - }, - }, - }, - { - Cid: c2, - PeerMap: map[peer.ID]api.PinInfo{ - test.TestPeerID1: { - Cid: c2, - Peer: test.TestPeerID1, - Status: api.TrackerStatusPinning, - TS: time.Now(), - }, - }, - }, - { - Cid: c3, - PeerMap: map[peer.ID]api.PinInfo{ - test.TestPeerID1: { - Cid: c3, - Peer: test.TestPeerID1, - Status: api.TrackerStatusPinError, - TS: time.Now(), - }, - }, - }, - { - Cid: slowC1, - PeerMap: map[peer.ID]api.PinInfo{ - test.TestPeerID1: { - Cid: slowC1, - Peer: test.TestPeerID1, - Status: api.TrackerStatusPinning, - TS: time.Now(), - }, - }, - }, - }) - return nil -} - func (mock *mockService) Pins(ctx context.Context, in struct{}, out *[]api.PinSerial) error { *out = []api.PinSerial{ api.PinWithOpts(test.MustDecodeCid(test.TestCid1), pinOpts).ToSerial(), @@ -1068,3 +984,49 @@ func TestTrackUntrackWithCancel(t *testing.T) { }) } } + +func TestPinTracker_RemoteIgnoresError(t *testing.T) { + testF := func(t *testing.T, pt ipfscluster.PinTracker) { + remoteCid := test.MustDecodeCid(test.TestCid4) + + remote := api.PinWithOpts(remoteCid, pinOpts) + remote.Allocations = []peer.ID{test.TestPeerID2} + remote.ReplicationFactorMin = 1 + remote.ReplicationFactorMax = 1 + + err := pt.Track(remote) + if err != nil { + t.Fatal(err) + } + + // Sync triggers IPFSPinLs which will return an error + // (see mock) + pi, err := pt.Sync(remoteCid) + if err != nil { + t.Fatal(err) + } + + if pi.Status != api.TrackerStatusRemote || pi.Error != "" { + t.Error("Remote pin should not be in error") + } + + pi = pt.Status(remoteCid) + if err != nil { + t.Fatal(err) + } + + if pi.Status != api.TrackerStatusRemote || pi.Error != "" { + t.Error("Remote pin should not be in error") + } + } + + t.Run("basic pintracker", func(t *testing.T) { + pt := testMapPinTracker(t) + testF(t, pt) + }) + + t.Run("stateless pintracker", func(t *testing.T) { + pt := testStatelessPinTracker(t) + testF(t, pt) + }) +}