Skip to content

Commit

Permalink
feat: add some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Nov 30, 2023
1 parent 6b5640d commit aff7675
Show file tree
Hide file tree
Showing 2 changed files with 303 additions and 1 deletion.
7 changes: 6 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ require (
github.com/libp2p/go-libp2p-kad-dht v0.25.1
github.com/libp2p/go-libp2p-record v0.2.0
github.com/multiformats/go-multibase v0.2.0
github.com/multiformats/go-multihash v0.2.3
github.com/stretchr/testify v1.8.4
github.com/urfave/cli/v2 v2.25.7
)

Expand All @@ -20,6 +22,7 @@ require (
github.com/containerd/cgroups v1.1.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
Expand Down Expand Up @@ -77,14 +80,14 @@ require (
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
github.com/multiformats/go-multicodec v0.9.0 // indirect
github.com/multiformats/go-multihash v0.2.3 // indirect
github.com/multiformats/go-multistream v0.5.0 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/onsi/ginkgo/v2 v2.13.1 // indirect
github.com/opencontainers/runtime-spec v1.1.0 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/polydawn/refmt v0.89.0 // indirect
github.com/prometheus/client_golang v1.17.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
Expand All @@ -98,6 +101,7 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/samber/lo v1.38.1 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opencensus.io v0.24.0 // indirect
Expand All @@ -119,5 +123,6 @@ require (
golang.org/x/tools v0.15.0 // indirect
gonum.org/v1/gonum v0.14.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.2.1 // indirect
)
297 changes: 297 additions & 0 deletions server_routers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
package main

import (
"context"
"crypto/rand"
"errors"
"testing"
"time"

"github.com/ipfs/boxo/ipns"
"github.com/ipfs/boxo/path"
"github.com/ipfs/boxo/routing/http/types"
"github.com/ipfs/boxo/routing/http/types/iter"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/routing"
mh "github.com/multiformats/go-multihash"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)

type mockRouter struct{ mock.Mock }

var _ router = &mockRouter{}

func (m *mockRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.Record], error) {
args := m.Called(ctx, key, limit)
if arg0 := args.Get(0); arg0 == nil {
return nil, args.Error(1)
}
return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1)
}

func (m *mockRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[*types.PeerRecord], error) {
args := m.Called(ctx, pid, limit)
if arg0 := args.Get(0); arg0 == nil {
return nil, args.Error(1)
}
return args.Get(0).(iter.ResultIter[*types.PeerRecord]), args.Error(1)
}

func (m *mockRouter) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) {
args := m.Called(ctx, name)
if arg0 := args.Get(0); arg0 == nil {
return nil, args.Error(1)
}
return args.Get(0).(*ipns.Record), args.Error(1)
}

func (m *mockRouter) PutIPNS(ctx context.Context, name ipns.Name, record *ipns.Record) error {
args := m.Called(ctx, name, record)
return args.Error(0)
}

func makeName(t *testing.T) (crypto.PrivKey, ipns.Name) {
sk, _, err := crypto.GenerateEd25519Key(rand.Reader)
require.NoError(t, err)

pid, err := peer.IDFromPrivateKey(sk)
require.NoError(t, err)

return sk, ipns.NameFromPeer(pid)
}

func makeIPNSRecord(t *testing.T, sk crypto.PrivKey, opts ...ipns.Option) (*ipns.Record, []byte) {
cid, err := cid.Decode("bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4")
require.NoError(t, err)

path := path.FromCid(cid)
eol := time.Now().Add(time.Hour * 48)
ttl := time.Second * 20

record, err := ipns.NewRecord(sk, path, 1, eol, ttl, opts...)
require.NoError(t, err)

rawRecord, err := ipns.MarshalRecord(record)
require.NoError(t, err)

return record, rawRecord
}

func TestGetIPNS(t *testing.T) {
t.Parallel()

sk, name := makeName(t)
rec, _ := makeIPNSRecord(t, sk)

t.Run("OK (Multiple Composable, One Fails, One OK)", func(t *testing.T) {
ctx := context.Background()

mr1 := &mockRouter{}
mr1.On("GetIPNS", mock.Anything, name).Return(rec, nil)

mr2 := &mockRouter{}
mr2.On("GetIPNS", mock.Anything, name).Return(nil, routing.ErrNotFound)

r := parallelRouter{
routers: []router{
composableRouter{
ipns: mr1,
},
composableRouter{
ipns: mr2,
},
},
}

getRec, err := r.GetIPNS(ctx, name)
require.NoError(t, err)
require.EqualValues(t, rec, getRec)
})

t.Run("OK (Multiple Parallel)", func(t *testing.T) {
ctx := context.Background()

mr1 := &mockRouter{}
mr1.On("GetIPNS", mock.Anything, name).Return(nil, routing.ErrNotFound)

mr2 := &mockRouter{}
mr2.On("GetIPNS", mock.Anything, name).Return(rec, nil)

r := parallelRouter{
routers: []router{
composableRouter{
ipns: parallelRouter{
routers: []router{mr1, mr2},
},
},
},
}

getRec, err := r.GetIPNS(ctx, name)
require.NoError(t, err)
require.EqualValues(t, rec, getRec)
})

t.Run("No Routers", func(t *testing.T) {
ctx := context.Background()

r := parallelRouter{
routers: []router{
composableRouter{
ipns: parallelRouter{},
},
},
}

_, err := r.GetIPNS(ctx, name)
require.ErrorIs(t, err, routing.ErrNotFound)
})
}

func TestPutIPNS(t *testing.T) {
t.Parallel()

sk, name := makeName(t)
rec, _ := makeIPNSRecord(t, sk)

t.Run("OK (Multiple Composable)", func(t *testing.T) {
ctx := context.Background()

mr1 := &mockRouter{}
mr1.On("PutIPNS", mock.Anything, name, rec).Return(nil)

mr2 := &mockRouter{}
mr2.On("PutIPNS", mock.Anything, name, rec).Return(nil)

r := parallelRouter{
routers: []router{
composableRouter{
ipns: mr1,
},
composableRouter{
ipns: mr2,
},
},
}

err := r.PutIPNS(ctx, name, rec)
require.NoError(t, err)

mr1.AssertExpectations(t)
mr2.AssertExpectations(t)
})

t.Run("OK (Multiple Parallel)", func(t *testing.T) {
ctx := context.Background()

mr1 := &mockRouter{}
mr1.On("PutIPNS", mock.Anything, name, rec).Return(nil)

mr2 := &mockRouter{}
mr2.On("PutIPNS", mock.Anything, name, rec).Return(nil)

r := parallelRouter{
routers: []router{
composableRouter{
ipns: parallelRouter{
routers: []router{mr1, mr2},
},
},
},
}

err := r.PutIPNS(ctx, name, rec)
require.NoError(t, err)

mr1.AssertExpectations(t)
mr2.AssertExpectations(t)
})

t.Run("Failure of a Single Router (Multiple Composable)", func(t *testing.T) {
ctx := context.Background()

mr1 := &mockRouter{}
mr1.On("PutIPNS", mock.Anything, name, rec).Return(errors.New("failed"))

mr2 := &mockRouter{}
mr2.On("PutIPNS", mock.Anything, name, rec).Return(nil)

r := parallelRouter{
routers: []router{
composableRouter{
ipns: mr1,
},
composableRouter{
ipns: mr2,
},
},
}

err := r.PutIPNS(ctx, name, rec)
require.ErrorContains(t, err, "failed")

mr1.AssertExpectations(t)
mr2.AssertExpectations(t)
})

t.Run("Failure of a Single Router (Multiple Parallel)", func(t *testing.T) {
ctx := context.Background()

mr1 := &mockRouter{}
mr1.On("PutIPNS", mock.Anything, name, mock.Anything).Return(errors.New("failed"))

mr2 := &mockRouter{}
mr2.On("PutIPNS", mock.Anything, name, mock.Anything).Return(nil)

r := parallelRouter{
routers: []router{
composableRouter{
ipns: parallelRouter{
routers: []router{mr1, mr2},
},
},
},
}

err := r.PutIPNS(ctx, name, rec)
require.ErrorContains(t, err, "failed")

mr1.AssertExpectations(t)
mr2.AssertExpectations(t)
})
}

func TestFindProviders(t *testing.T) {
t.Parallel()

t.Run("Basic", func(t *testing.T) {
prefix := cid.NewPrefixV1(cid.Raw, mh.SHA2_256)
c, _ := prefix.Sum([]byte("foo"))

ctx := context.Background()

d := parallelRouter{}
it, err := d.FindProviders(ctx, c, 10)

require.NoError(t, err)
require.False(t, it.Next())

mr1 := &mockRouter{}
mr1.On("FindProviders", mock.Anything, c, 10).Return(iter.ToResultIter(iter.FromSlice([]types.Record{})), nil)

d = parallelRouter{
routers: []router{
&composableRouter{
providers: mr1,
},
},
}

it, err = d.FindProviders(ctx, c, 10)
require.NoError(t, err)
require.False(t, it.Next())
})
}

0 comments on commit aff7675

Please sign in to comment.