Skip to content

Commit

Permalink
add tests for fetcher block
Browse files Browse the repository at this point in the history
  • Loading branch information
patrick-ogrady committed May 19, 2020
1 parent 5b5d5ad commit 8351885
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 2 deletions.
7 changes: 5 additions & 2 deletions fetcher/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package fetcher

import (
"context"
"errors"
"fmt"

"github.com/coinbase/rosetta-sdk-go/asserter"
Expand Down Expand Up @@ -227,7 +226,11 @@ func (f *Fetcher) BlockRetry(
}
}

return nil, errors.New("exhausted retries for block")
return nil, fmt.Errorf(
"%w: unable to fetch block %s",
ErrExhaustedRetries,
types.PrettyPrintStruct(blockIdentifier),
)
}

// addIndicies appends a range of indicies (from
Expand Down
141 changes: 141 additions & 0 deletions fetcher/block_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package fetcher

import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"

"github.com/coinbase/rosetta-sdk-go/asserter"
"github.com/coinbase/rosetta-sdk-go/types"

"github.com/stretchr/testify/assert"
)

var (
basicFullBlock = &types.Block{
BlockIdentifier: basicBlock,
ParentBlockIdentifier: &types.BlockIdentifier{
Index: 9,
Hash: "block 9",
},
Timestamp: 1582833600000,
}
)

func TestBlockRetry(t *testing.T) {
var tests = map[string]struct {
network *types.NetworkIdentifier
block *types.BlockIdentifier

errorsBeforeSuccess int
expectedBlock *types.Block
expectedError error

fetcherMaxRetries uint64
shouldCancel bool
}{
"no failures": {
network: basicNetwork,
block: basicBlock,
expectedBlock: basicFullBlock,
fetcherMaxRetries: 5,
},
"retry failures": {
network: basicNetwork,
block: basicBlock,
errorsBeforeSuccess: 2,
expectedBlock: basicFullBlock,
fetcherMaxRetries: 5,
},
"exhausted retries": {
network: basicNetwork,
block: basicBlock,
errorsBeforeSuccess: 2,
expectedError: ErrExhaustedRetries,
fetcherMaxRetries: 1,
},
"cancel context": {
network: basicNetwork,
block: basicBlock,
errorsBeforeSuccess: 6,
expectedError: context.Canceled,
fetcherMaxRetries: 5,
shouldCancel: true,
},
}

for name, test := range tests {
t.Run(name, func(t *testing.T) {
var (
tries = 0
assert = assert.New(t)
ctx, cancel = context.WithCancel(context.Background())
endpoint = "/block"
)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal("POST", r.Method)
assert.Equal(endpoint, r.URL.RequestURI())

expected := &types.BlockRequest{
NetworkIdentifier: test.network,
BlockIdentifier: types.ConstructPartialBlockIdentifier(test.block),
}
var blockRequest *types.BlockRequest
assert.NoError(json.NewDecoder(r.Body).Decode(&blockRequest))
assert.Equal(expected, blockRequest)

if test.shouldCancel {
cancel()
}

if tries < test.errorsBeforeSuccess {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(w, "{}")
tries++
return
}

w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
fmt.Fprintln(w, types.PrettyPrintStruct(
&types.BlockResponse{
Block: test.expectedBlock,
},
))
}))

defer ts.Close()
a, err := asserter.NewClientWithOptions(
basicNetwork,
&types.BlockIdentifier{
Index: 0,
Hash: "block 0",
},
basicNetworkOptions.Allow.OperationTypes,
basicNetworkOptions.Allow.OperationStatuses,
nil,
)
assert.NoError(err)

f := New(
ts.URL,
WithRetryElapsedTime(5*time.Second),
WithMaxRetries(test.fetcherMaxRetries),
WithAsserter(a),
)
block, err := f.BlockRetry(
ctx,
test.network,
types.ConstructPartialBlockIdentifier(test.block),
)
assert.Equal(test.expectedBlock, block)
assert.True(errors.Is(err, test.expectedError))
})
}
}

0 comments on commit 8351885

Please sign in to comment.