Skip to content

Commit

Permalink
fix(http): better testing framework
Browse files Browse the repository at this point in the history
  • Loading branch information
rvagg committed May 4, 2023
1 parent 55a7b7f commit c812ef7
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 399 deletions.
6 changes: 6 additions & 0 deletions pkg/internal/testutil/mockclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ func (mc *MockClient) VerifyRetrievalsReceived(ctx context.Context, t *testing.T
require.ElementsMatch(t, expectedRetrievals, retrievals)
}

func (mc *MockClient) VerifyRetrievalsServed(ctx context.Context, t *testing.T, expectedServed []RemoteStats) {
}

func (mc *MockClient) VerifyRetrievalsCompleted(ctx context.Context, t *testing.T, expectedRetrievals []peer.ID) {
}

func (mc *MockClient) VerifyReceivedRetrievalFrom(ctx context.Context, t *testing.T, p peer.ID) ClientRetrievalRequest {
for {
select {
Expand Down
34 changes: 30 additions & 4 deletions pkg/internal/testutil/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/benbjohnson/clock"
"github.com/filecoin-project/lassie/pkg/types"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/stretchr/testify/require"
)
Expand All @@ -15,17 +16,40 @@ type ExpectedActionsAtTime struct {
AfterStart time.Duration
ReceivedConnections []peer.ID
ReceivedRetrievals []peer.ID
ServedRetrievals []RemoteStats
CompletedRetrievals []peer.ID
CandidatesDiscovered []DiscoveredCandidate
ExpectedEvents []types.RetrievalEvent
}

type RemoteStats struct {
Peer peer.ID
Root cid.Cid
ByteCount uint64
Blocks []cid.Cid
}

type RetrievalVerifier struct {
ExpectedSequence []ExpectedActionsAtTime
}

type RunRetrieval func(cb func(types.RetrievalEvent)) (*types.RetrievalStats, error)

func (rv RetrievalVerifier) RunWithVerification(ctx context.Context, t *testing.T, clock *clock.Mock, mockClient *MockClient, mockCandidateFinder *MockCandidateFinder, runRetrievals []RunRetrieval) []types.RetrievalResult {
type VerifierClient interface {
VerifyConnectionsReceived(ctx context.Context, t *testing.T, expectedConnections []peer.ID)
VerifyRetrievalsReceived(ctx context.Context, t *testing.T, expectedRetrievals []peer.ID)
VerifyRetrievalsServed(ctx context.Context, t *testing.T, expectedServed []RemoteStats)
VerifyRetrievalsCompleted(ctx context.Context, t *testing.T, expectedRetrievals []peer.ID)
}

func (rv RetrievalVerifier) RunWithVerification(ctx context.Context,
t *testing.T,
clock *clock.Mock,
client VerifierClient,
mockCandidateFinder *MockCandidateFinder,
runRetrievals []RunRetrieval,
) []types.RetrievalResult {

resultChan := make(chan types.RetrievalResult, len(runRetrievals))
asyncCollectingEventsListener := NewAsyncCollectingEventsListener(ctx)
for _, runRetrieval := range runRetrievals {
Expand All @@ -44,9 +68,11 @@ func (rv RetrievalVerifier) RunWithVerification(ctx context.Context, t *testing.
if mockCandidateFinder != nil {
mockCandidateFinder.VerifyCandidatesDiscovered(ctx, t, expectedActionsAtTime.CandidatesDiscovered)
}
if mockClient != nil {
mockClient.VerifyConnectionsReceived(ctx, t, expectedActionsAtTime.ReceivedConnections)
mockClient.VerifyRetrievalsReceived(ctx, t, expectedActionsAtTime.ReceivedRetrievals)
if client != nil {
client.VerifyConnectionsReceived(ctx, t, expectedActionsAtTime.ReceivedConnections)
client.VerifyRetrievalsReceived(ctx, t, expectedActionsAtTime.ReceivedRetrievals)
client.VerifyRetrievalsServed(ctx, t, expectedActionsAtTime.ServedRetrievals)
client.VerifyRetrievalsCompleted(ctx, t, expectedActionsAtTime.CompletedRetrievals)
}
}
results := make([]types.RetrievalResult, 0, len(runRetrievals))
Expand Down
4 changes: 2 additions & 2 deletions pkg/retriever/bitswapretriever_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ func TestBitswapRetriever(t *testing.T) {
clock.Set(time.Now())
retrievalResult := make(chan types.RetrievalResult, 1)
go func() {
stats, err := retrieval1.RetrieveFromAsyncCandidates(makeAsyncCandidates(t, spreadCandidates(expectedCandidates[rid1])))
stats, err := retrieval1.RetrieveFromAsyncCandidates(makeAsyncCandidates(t, expectedCandidates[rid1]))
retrievalResult <- types.RetrievalResult{Stats: stats, Err: err}
}()
if len(expectedCandidates[rid1]) > 0 {
Expand Down Expand Up @@ -384,7 +384,7 @@ func TestBitswapRetriever(t *testing.T) {
clock.Set(time.Now())
unlockExchange = make(chan struct{})
go func() {
stats, err := retrieval2.RetrieveFromAsyncCandidates(makeAsyncCandidates(t, spreadCandidates(expectedCandidates[rid2])))
stats, err := retrieval2.RetrieveFromAsyncCandidates(makeAsyncCandidates(t, expectedCandidates[rid2]))
retrievalResult <- types.RetrievalResult{Stats: stats, Err: err}
}()
if len(expectedCandidates[rid2]) > 0 {
Expand Down
29 changes: 10 additions & 19 deletions pkg/retriever/graphsyncretriever_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ func TestRetrievalRacing(t *testing.T) {
Cid: cid.Undef,
RetrievalID: retrievalID,
LinkSystem: cidlink.DefaultLinkSystem(),
}, cb).RetrieveFromAsyncCandidates(makeAsyncCandidates(t, spreadCandidates(candidates)))
}, cb).RetrieveFromAsyncCandidates(makeAsyncCandidates(t, candidates))
}})
require.Len(t, results, 1)
stats, err := results[0].Stats, results[0].Err
Expand Down Expand Up @@ -650,22 +650,22 @@ func TestMultipleRetrievals(t *testing.T) {
Cid: cid1,
RetrievalID: retrievalID,
LinkSystem: cidlink.DefaultLinkSystem(),
}, cb).RetrieveFromAsyncCandidates(makeAsyncCandidates(t, spreadCandidates([]types.RetrievalCandidate{
}, cb).RetrieveFromAsyncCandidates(makeAsyncCandidates(t, []types.RetrievalCandidate{
types.NewRetrievalCandidate(peer.ID("foo"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{}),
types.NewRetrievalCandidate(peer.ID("bar"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{}),
types.NewRetrievalCandidate(peer.ID("baz"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{}),
})))
}))
},
func(cb func(types.RetrievalEvent)) (*types.RetrievalStats, error) {
return cfg.Retrieve(context.Background(), types.RetrievalRequest{
Cid: cid2,
RetrievalID: retrievalID,
LinkSystem: cidlink.DefaultLinkSystem(),
}, cb).RetrieveFromAsyncCandidates(makeAsyncCandidates(t, spreadCandidates([]types.RetrievalCandidate{
}, cb).RetrieveFromAsyncCandidates(makeAsyncCandidates(t, []types.RetrievalCandidate{
types.NewRetrievalCandidate(peer.ID("bang"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{}),
types.NewRetrievalCandidate(peer.ID("boom"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{}),
types.NewRetrievalCandidate(peer.ID("bing"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{}),
})))
}))
}})
require.Len(t, results, 2)
stats, err := results[0].Stats, results[0].Err
Expand Down Expand Up @@ -702,7 +702,7 @@ func TestRetrievalSelector(t *testing.T) {
LinkSystem: cidlink.DefaultLinkSystem(),
Selector: selector,
}, nil)
stats, err := retrieval.RetrieveFromAsyncCandidates(makeAsyncCandidates(t, [][]types.RetrievalCandidate{{types.NewRetrievalCandidate(peer.ID("foo"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{})}}))
stats, err := retrieval.RetrieveFromAsyncCandidates(makeAsyncCandidates(t, []types.RetrievalCandidate{types.NewRetrievalCandidate(peer.ID("foo"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{})}))
require.NoError(t, err)
require.NotNil(t, stats)
require.Equal(t, mockClient.GetRetrievalReturns()["foo"].ResultStats, stats)
Expand Down Expand Up @@ -797,13 +797,13 @@ func TestDuplicateRetreivals(t *testing.T) {
Cid: cid1,
RetrievalID: retrievalID,
LinkSystem: cidlink.DefaultLinkSystem(),
}, cb).RetrieveFromAsyncCandidates(makeAsyncCandidates(t, spreadCandidates([]types.RetrievalCandidate{
}, cb).RetrieveFromAsyncCandidates(makeAsyncCandidates(t, []types.RetrievalCandidate{
types.NewRetrievalCandidate(peer.ID("foo"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{PieceCID: cid.Cid{}, VerifiedDeal: false, FastRetrieval: false}),
types.NewRetrievalCandidate(peer.ID("baz"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{PieceCID: cid.Cid{}, VerifiedDeal: false, FastRetrieval: false}),
types.NewRetrievalCandidate(peer.ID("bar"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{PieceCID: cid.Cid{}, VerifiedDeal: false, FastRetrieval: false}),
types.NewRetrievalCandidate(peer.ID("bar"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{PieceCID: cid.Cid{}, VerifiedDeal: false, FastRetrieval: true}),
types.NewRetrievalCandidate(peer.ID("bar"), nil, cid.Undef, &metadata.GraphsyncFilecoinV1{PieceCID: cid.Cid{}, VerifiedDeal: true, FastRetrieval: false}),
})))
}))
},
})
require.Len(t, results, 1)
Expand All @@ -814,19 +814,10 @@ func TestDuplicateRetreivals(t *testing.T) {
require.Equal(t, mockClient.GetRetrievalReturns()["bar"].ResultStats, stats)
}

func spreadCandidates(cands []types.RetrievalCandidate) [][]types.RetrievalCandidate {
// make cands into an slice of slices of candidates where each subslice only has one of the candidates in it
out := make([][]types.RetrievalCandidate, 0)
for _, cand := range cands {
out = append(out, []types.RetrievalCandidate{cand})
}
return out
}

func makeAsyncCandidates(t *testing.T, candidates [][]types.RetrievalCandidate) types.InboundAsyncCandidates {
func makeAsyncCandidates(t *testing.T, candidates []types.RetrievalCandidate) types.InboundAsyncCandidates {
incoming, outgoing := types.MakeAsyncCandidates(len(candidates))
for _, candidate := range candidates {
err := outgoing.SendNext(context.Background(), candidate)
err := outgoing.SendNext(context.Background(), []types.RetrievalCandidate{candidate})
require.NoError(t, err)
}
close(outgoing)
Expand Down
Loading

0 comments on commit c812ef7

Please sign in to comment.