Select Git revision
server_test.go
Wolfgang Welz
authored and
GitHub
committed
*GetNextCandidate selection added * Recompile salt.proto * Refactor peer IDs completely * Recompile proto sources * WIP * renamed to sort * Return requested peers on request * Kepp track how ofter a managed peer was verified * sort adapted to the new peer * Query verified peers for new peers * WIP * Add manager tests * Add peering messages to protobuf * Make Salt methods consistent with Peer * Handle peering messages * WIP * Add To filed to PeersRequest * Add PeersRequest test * Adding PeersRequest benchmark * Move mpeer and helper functions to own file * Bump peer only once on reverification * WIP * * WIP * Increase buffer to prevent deadlocks * Remove unnecessary lock * Add peering request test * Make tests deterministic by triggering reverify * WIP * fixing concurrency issues * testManager improved * Don't send PeeringResponse for invalid salt * WIP * WIP * removed commented code * WIP * WIP * Neighbourhood manager (#11) * GetNextCandidate selection added * fixing concurrency issues * testManager improved * removed commented code * WIP * WIP * WIP * WIP * Make TestAdd pass in neighborhood_test `Add` should do nothing if the neighborhood list is full. * Improve TestSrvVerifyBoot * Upgrade to go 1.13 * Use testify instead of magiconair/properties * * WIP * WIP * WIP * WIP * Simulation (#14) * clear rejection filter after refreshing the public salt * clean rejection filter * Add mpeer test * gofmt test * Remove ineffactual assignments * Trigger panic when index is out of bound in deletePeer * Add selection test * Add TestGetFurtherest and TestGetPeerIndex * both salt updated at the same time and neighborhood dropped * Add node peering history for simulation * WIP * added sim visualization * removed root handler * added README * updated README * removed unused dependencies * Tidy go.mod * Work in progress * WIP * WIP * WIP * improved start button * WIP * added keyboard support for start * WIP * WIP * WIP * WIP * WIP * WIP * added input parameters * README updated * gif updated * figure updated * updated * updated gif * removed simulation metrics * updated * updated * Extract server from discovery and peering * Use golang/protobuf * Update README.md * Rename PeersRequest to DiscoveryRequest * Fixing typos * Move unused function to tests * The selection protocol depends on the discovery * Make tests more robust when using -race * Improve logging * Remove unnecessary arguments * Fix data races * added timeout for simulated network * added loop to animation * rename neighborhood to selection * adds initial salt and fixes simulation end * visualizer enabled by default * new parameter dropAll and improved python script * updated README * updated README * fix salt initialization * added blogpost link * Add badges to README * Add Travis CI for tests * Correct formating * Running golangci on Travis * Ignore return value of 'logger.Sync' * Remove unused functions * Add link to license * Move simnetwork to transport * Use the complete network protocol in simulations * Do not export selection/manager * Remove gRPC transport layer * Add UDP connection transport test * Implement the peer DB using Goshimmer database * Use the local GoShimmer version * Add support for a persistent database * Persist private key of local peer in database * Set TTL for bootstrap peers * Use GoShimmer events * Store the supported services in the local peer * Use most current GoShimmer git version as a dep * Switch to hive.go event package * Use correct module iotaledger/autopeering-sim * Provide dummy service in autopeering simulation * adds service support in the selection * adds peer discovered events * adds GetIncomingNeighbors and GetOutgoingNeighbors * fixes out of bound error in splitNodeKey * adds public IP support * fixes localhost * fixes localhost parsing * changes selection loop to 1s * switches from fmt.Println to log.Debug * increases maxKnown to 1000 and always triggers discovered peer * adds PeerDeleted event * moves PeerDeleted event into deletePeer * adds config paramters for the peer discovery * adds config parameters to neighbor selection * enable/disable inbound/outbound selection * Improve Godoc comments * modifies disabled outbound selection * fixes bug with disabling the selection * removes getMyIP() from server * removes some debugging logs * Introduce services - Each peer now comes with a set of services - Local peer is a proper peer - Services are exchanged during Pong and are available for all verified peers * fixes GetVerifiedPeer * adds gossip key to the service * removes debugging logs * Add test for GetVerifiedPeer * Fix main * Add localNetwork to Protocol * Add new but verified peers to the manager * changes configurable parameters * fixes DiscoveryRequest field sequence * Regenerate proto files * Cleanup parameters * Fix potential race condition * Reduce logging verbosity * Add test for selection+discover * Return net.Addr in Transport * Remove inbound/outbound switches completely * Improve logging * Fix peerdb logs * Fix peer updating * Make TestProtFull more robust * Make queryInterval a parameter * Improve loggind during querying * Trigger PeerDiscovered only for active peers * Cleanup protocol tests * Add discovery test on protocol level * Rename maxVerified to maxManaged * Increase default query interval * Improve discover benchmarks * Fix manager tests * Do not use bugged assert.Eventually * Fix linter warnings in server * Remove unused parameters * Make transport work on slices of bytes * Fix typo in comments * Fix linter warnings * UpdateService accepts two strings * Add test that services are received in discover * adds required services * Handle closed connections consistently * Code cleanup * fixes DropPeer * improves debug messages * Log errors during reverification * Log packet size * refactor: remove unused files * refactor: use internal autopeering package Co-authored-by: Angelo Capossele <angelocapossele@gmail.com> Co-authored-by:
jkrvivian <jkrvivian@gmail.com>
server_test.go 5.06 KiB
package server
import (
"log"
"testing"
"time"
"github.com/iotaledger/goshimmer/packages/autopeering/peer"
"github.com/iotaledger/goshimmer/packages/autopeering/salt"
"github.com/iotaledger/goshimmer/packages/autopeering/transport"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)
const graceTime = 5 * time.Millisecond
var logger *zap.SugaredLogger
func init() {
l, err := zap.NewDevelopment()
if err != nil {
log.Fatalf("cannot initialize logger: %v", err)
}
logger = l.Sugar()
}
const (
MPing MType = iota
MPong
)
type Message interface {
Type() MType
Marshal() []byte
}
type Ping struct{}
type Pong struct{}
func (m *Ping) Type() MType { return MPing }
func (m *Ping) Marshal() []byte { return append([]byte{}, byte(MPing)) }
func (m *Pong) Type() MType { return MPong }
func (m *Pong) Marshal() []byte { return append([]byte{}, byte(MPong)) }
func sendPong(args mock.Arguments) {
srv := args.Get(0).(*Server)
addr := args.Get(1).(string)
srv.Send(addr, new(Pong).Marshal())
}
var (
pingMock *mock.Mock
pongMock *mock.Mock
)
func setupTest() func(t *testing.T) {
pingMock = new(mock.Mock)
pongMock = new(mock.Mock)
return func(t *testing.T) {
pingMock.AssertExpectations(t)
pingMock = nil
pongMock.AssertExpectations(t)
pongMock = nil
}
}
func handle(s *Server, fromAddr string, fromID peer.ID, fromKey peer.PublicKey, data []byte) (bool, error) {
msg, err := unmarshal(data)
if err != nil {
return false, err
}
switch msg.Type() {
case MPing:
pingMock.Called(s, fromAddr, fromID, fromKey, data)
case MPong:
if s.IsExpectedReply(fromAddr, fromID, MPong, msg) {
pongMock.Called(s, fromAddr, fromID, fromKey, data)
}
default:
panic("unknown message type")
}
return true, nil
}
func unmarshal(data []byte) (Message, error) {
if len(data) != 1 {
return nil, ErrInvalidMessage
}
switch MType(data[0]) {
case MPing:
return new(Ping), nil
case MPong:
return new(Pong), nil
}
return nil, ErrInvalidMessage
}
func TestSrvEncodeDecodePing(t *testing.T) {
// create minimal server just containing the local peer
local, err := peer.NewLocal("dummy", "local", peer.NewMemoryDB(logger))
require.NoError(t, err)
s := &Server{local: local}
ping := new(Ping)
packet := s.encode(ping.Marshal())
data, key, err := decode(packet)
require.NoError(t, err)
msg, _ := unmarshal(data)
assert.Equal(t, local.ID(), key.ID())
assert.Equal(t, msg, ping)
}
func newTestServer(t require.TestingT, name string, trans transport.Transport, logger *zap.SugaredLogger) (*Server, func()) {
log := logger.Named(name)
db := peer.NewMemoryDB(log.Named("db"))
local, err := peer.NewLocal(trans.LocalAddr().Network(), trans.LocalAddr().String(), db)
require.NoError(t, err)
s, _ := salt.NewSalt(100 * time.Second)
local.SetPrivateSalt(s)
s, _ = salt.NewSalt(100 * time.Second)
local.SetPublicSalt(s)
srv := Listen(local, trans, logger.Named(name), HandlerFunc(handle))
teardown := func() {
srv.Close()
db.Close()
}
return srv, teardown
}
func sendPing(s *Server, p *peer.Peer) error {
ping := new(Ping)
isPong := func(msg interface{}) bool {
_, ok := msg.(*Pong)
return ok
}
errc := s.SendExpectingReply(p.Address(), p.ID(), ping.Marshal(), MPong, isPong)
return <-errc
}
func TestPingPong(t *testing.T) {
p2p := transport.P2P()
srvA, closeA := newTestServer(t, "A", p2p.A, logger)
defer closeA()
srvB, closeB := newTestServer(t, "B", p2p.B, logger)
defer closeB()
peerA := &srvA.Local().Peer
peerB := &srvB.Local().Peer
t.Run("A->B", func(t *testing.T) {
defer setupTest()(t)
// B expects valid ping from A and sends pong back
pingMock.On("handle", srvB, peerA.Address(), peerA.ID(), peerA.PublicKey(), mock.Anything).Run(sendPong).Once()
// A expects valid pong from B
pongMock.On("handle", srvA, peerB.Address(), peerB.ID(), peerB.PublicKey(), mock.Anything).Once()
assert.NoError(t, sendPing(srvA, peerB))
time.Sleep(graceTime)
})
t.Run("B->A", func(t *testing.T) {
defer setupTest()(t)
pingMock.On("handle", srvA, peerB.Address(), peerB.ID(), peerB.PublicKey(), mock.Anything).Run(sendPong).Once() // A expects valid ping from B and sends pong back
pongMock.On("handle", srvB, peerA.Address(), peerA.ID(), peerA.PublicKey(), mock.Anything).Once() // B expects valid pong from A
assert.NoError(t, sendPing(srvB, peerA))
time.Sleep(graceTime)
})
}
func TestSrvPingTimeout(t *testing.T) {
defer setupTest()(t)
p2p := transport.P2P()
srvA, closeA := newTestServer(t, "A", p2p.A, logger)
defer closeA()
srvB, closeB := newTestServer(t, "B", p2p.B, logger)
closeB()
peerB := &srvB.Local().Peer
assert.EqualError(t, sendPing(srvA, peerB), ErrTimeout.Error())
}
func TestUnexpectedPong(t *testing.T) {
defer setupTest()(t)
p2p := transport.P2P()
srvA, closeA := newTestServer(t, "A", p2p.A, logger)
defer closeA()
srvB, closeB := newTestServer(t, "B", p2p.B, logger)
defer closeB()
// there should never be a Ping.Handle
// there should never be a Pong.Handle
srvA.Send(srvB.LocalAddr(), new(Pong).Marshal())
}