kaspad/infrastructure/network/addressmanager/addressmanager_test.go
Svarog a8a7e3dd9b
Add windows to the CI + fix errors when testing on Windows (#1674)
* Add windows to the CI

* Cast syscall.Stdin into an integer

* DataDir -> AppDir in service_windows.go

* Rename mempool-limits package to something non-main

* Close database after re-assigining to it

* Up rpcTimout to 10 seconds
2021-04-12 14:53:34 +03:00

375 lines
12 KiB
Go

// Copyright (c) 2013-2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package addressmanager
import (
"net"
"reflect"
"testing"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/infrastructure/config"
"github.com/kaspanet/kaspad/infrastructure/db/database/ldb"
"github.com/kaspanet/kaspad/util/mstime"
)
func newAddressManagerForTest(t *testing.T, testName string) (addressManager *AddressManager, teardown func()) {
cfg := config.DefaultConfig()
datadir := t.TempDir()
database, err := ldb.NewLevelDB(datadir, 8)
if err != nil {
t.Fatalf("%s: could not create a database: %s", testName, err)
}
addressManager, err = New(NewConfig(cfg), database)
if err != nil {
t.Fatalf("%s: error creating address manager: %s", testName, err)
}
return addressManager, func() {
database.Close()
}
}
func TestBestLocalAddress(t *testing.T) {
localAddrs := []appmessage.NetAddress{
{IP: net.ParseIP("192.168.0.100")},
{IP: net.ParseIP("::1")},
{IP: net.ParseIP("fe80::1")},
{IP: net.ParseIP("2001:470::1")},
}
var tests = []struct {
remoteAddr appmessage.NetAddress
want0 appmessage.NetAddress
want1 appmessage.NetAddress
want2 appmessage.NetAddress
want3 appmessage.NetAddress
}{
{
// Remote connection from public IPv4
appmessage.NetAddress{IP: net.ParseIP("204.124.8.1")},
appmessage.NetAddress{IP: net.IPv4zero},
appmessage.NetAddress{IP: net.IPv4zero},
appmessage.NetAddress{IP: net.ParseIP("204.124.8.100")},
appmessage.NetAddress{IP: net.ParseIP("fd87:d87e:eb43:25::1")},
},
{
// Remote connection from private IPv4
appmessage.NetAddress{IP: net.ParseIP("172.16.0.254")},
appmessage.NetAddress{IP: net.IPv4zero},
appmessage.NetAddress{IP: net.IPv4zero},
appmessage.NetAddress{IP: net.IPv4zero},
appmessage.NetAddress{IP: net.IPv4zero},
},
{
// Remote connection from public IPv6
appmessage.NetAddress{IP: net.ParseIP("2602:100:abcd::102")},
appmessage.NetAddress{IP: net.IPv6zero},
appmessage.NetAddress{IP: net.ParseIP("2001:470::1")},
appmessage.NetAddress{IP: net.ParseIP("2001:470::1")},
appmessage.NetAddress{IP: net.ParseIP("2001:470::1")},
},
}
amgr, teardown := newAddressManagerForTest(t, "TestGetBestLocalAddress")
defer teardown()
// Test against default when there's no address
for x, test := range tests {
got := amgr.BestLocalAddress(&test.remoteAddr)
if !test.want0.IP.Equal(got.IP) {
t.Errorf("TestGetBestLocalAddress test1 #%d failed for remote address %s: want %s got %s",
x, test.remoteAddr.IP, test.want1.IP, got.IP)
continue
}
}
for _, localAddr := range localAddrs {
amgr.localAddresses.addLocalNetAddress(&localAddr, InterfacePrio)
}
// Test against want1
for x, test := range tests {
got := amgr.BestLocalAddress(&test.remoteAddr)
if !test.want1.IP.Equal(got.IP) {
t.Errorf("TestGetBestLocalAddress test1 #%d failed for remote address %s: want %s got %s",
x, test.remoteAddr.IP, test.want1.IP, got.IP)
continue
}
}
// Add a public IP to the list of local addresses.
localAddr := appmessage.NetAddress{IP: net.ParseIP("204.124.8.100")}
amgr.localAddresses.addLocalNetAddress(&localAddr, InterfacePrio)
// Test against want2
for x, test := range tests {
got := amgr.BestLocalAddress(&test.remoteAddr)
if !test.want2.IP.Equal(got.IP) {
t.Errorf("TestGetBestLocalAddress test2 #%d failed for remote address %s: want %s got %s",
x, test.remoteAddr.IP, test.want2.IP, got.IP)
continue
}
}
}
func TestAddressManager(t *testing.T) {
addressManager, teardown := newAddressManagerForTest(t, "TestAddressManager")
defer teardown()
testAddress1 := &appmessage.NetAddress{IP: net.ParseIP("1.2.3.4"), Timestamp: mstime.Now()}
testAddress2 := &appmessage.NetAddress{IP: net.ParseIP("5.6.8.8"), Timestamp: mstime.Now()}
testAddress3 := &appmessage.NetAddress{IP: net.ParseIP("9.0.1.2"), Timestamp: mstime.Now()}
testAddresses := []*appmessage.NetAddress{testAddress1, testAddress2, testAddress3}
// Add a few addresses
err := addressManager.AddAddresses(testAddresses...)
if err != nil {
t.Fatalf("AddAddresses() failed: %s", err)
}
// Make sure that all the addresses are returned
addresses := addressManager.Addresses()
if len(testAddresses) != len(addresses) {
t.Fatalf("Unexpected amount of addresses returned from Addresses. "+
"Want: %d, got: %d", len(testAddresses), len(addresses))
}
for _, testAddress := range testAddresses {
found := false
for _, address := range addresses {
if reflect.DeepEqual(testAddress, address) {
found = true
break
}
}
if !found {
t.Fatalf("Address %s not returned from Addresses().", testAddress.IP)
}
}
// Remove an address
addressToRemove := testAddress2
err = addressManager.RemoveAddress(addressToRemove)
if err != nil {
t.Fatalf("RemoveAddress() failed: %s", err)
}
// Make sure that the removed address is not returned
addresses = addressManager.Addresses()
if len(addresses) != len(testAddresses)-1 {
t.Fatalf("Unexpected amount of addresses returned from Addresses(). "+
"Want: %d, got: %d", len(addresses), len(testAddresses)-1)
}
for _, address := range addresses {
if reflect.DeepEqual(addressToRemove, address) {
t.Fatalf("Removed addresses %s returned from Addresses()", addressToRemove.IP)
}
}
// Add that address back
err = addressManager.AddAddress(addressToRemove)
if err != nil {
t.Fatalf("AddAddress() failed: %s", err)
}
// Ban a different address
addressToBan := testAddress3
err = addressManager.Ban(addressToBan)
if err != nil {
t.Fatalf("Ban() failed: %s", err)
}
// Make sure that the banned address is not returned
addresses = addressManager.Addresses()
if len(addresses) != len(testAddresses)-1 {
t.Fatalf("Unexpected amount of addresses returned from Addresses(). "+
"Want: %d, got: %d", len(addresses), len(testAddresses)-1)
}
for _, address := range addresses {
if reflect.DeepEqual(addressToBan, address) {
t.Fatalf("Banned addresses %s returned from Addresses()", addressToBan.IP)
}
}
// Check that the address is banned
isBanned, err := addressManager.IsBanned(addressToBan)
if err != nil {
t.Fatalf("IsBanned() failed: %s", err)
}
if !isBanned {
t.Fatalf("Adderss %s is unexpectedly not banned", addressToBan.IP)
}
// Check that BannedAddresses() returns the banned address
bannedAddresses := addressManager.BannedAddresses()
if len(bannedAddresses) != 1 {
t.Fatalf("Unexpected amount of addresses returned from BannedAddresses(). "+
"Want: %d, got: %d", 1, len(bannedAddresses))
}
if !reflect.DeepEqual(addressToBan, bannedAddresses[0]) {
t.Fatalf("Banned address %s not returned from BannedAddresses()", addressToBan.IP)
}
// Unban the address
err = addressManager.Unban(addressToBan)
if err != nil {
t.Fatalf("Unban() failed: %s", err)
}
// Check that BannedAddresses() not longer returns the banned address
bannedAddresses = addressManager.BannedAddresses()
if len(bannedAddresses) != 0 {
t.Fatalf("Unexpected amount of addresses returned from BannedAddresses(). "+
"Want: %d, got: %d", 0, len(bannedAddresses))
}
}
func TestRestoreAddressManager(t *testing.T) {
cfg := config.DefaultConfig()
// Create an empty database
datadir := t.TempDir()
database, err := ldb.NewLevelDB(datadir, 8)
if err != nil {
t.Fatalf("Could not create a database: %s", err)
}
defer database.Close()
// Create an addressManager with the empty database
addressManager, err := New(NewConfig(cfg), database)
if err != nil {
t.Fatalf("Error creating address manager: %s", err)
}
testAddress1 := &appmessage.NetAddress{IP: net.ParseIP("1.2.3.4"), Timestamp: mstime.Now()}
testAddress2 := &appmessage.NetAddress{IP: net.ParseIP("5.6.8.8"), Timestamp: mstime.Now()}
testAddress3 := &appmessage.NetAddress{IP: net.ParseIP("9.0.1.2"), Timestamp: mstime.Now()}
testAddresses := []*appmessage.NetAddress{testAddress1, testAddress2, testAddress3}
// Add some addresses
err = addressManager.AddAddresses(testAddresses...)
if err != nil {
t.Fatalf("AddAddresses() failed: %s", err)
}
// Ban one of the addresses
addressToBan := testAddress1
err = addressManager.Ban(addressToBan)
if err != nil {
t.Fatalf("Ban() failed: %s", err)
}
// Close the database
err = database.Close()
if err != nil {
t.Fatalf("Close() failed: %s", err)
}
// Reopen the database
database, err = ldb.NewLevelDB(datadir, 8)
if err != nil {
t.Fatalf("Could not create a database: %s", err)
}
defer database.Close()
// Recreate an addressManager with a the previous database
addressManager, err = New(NewConfig(cfg), database)
if err != nil {
t.Fatalf("Error creating address manager: %s", err)
}
// Make sure that Addresses() returns the correct addresses
addresses := addressManager.Addresses()
if len(addresses) != len(testAddresses)-1 {
t.Fatalf("Unexpected amount of addresses returned from Addresses(). "+
"Want: %d, got: %d", len(addresses), len(testAddresses)-1)
}
for _, address := range addresses {
if reflect.DeepEqual(addressToBan, address) {
t.Fatalf("Banned addresses %s returned from Addresses()", addressToBan.IP)
}
}
// Make sure that BannedAddresses() returns the correct addresses
bannedAddresses := addressManager.BannedAddresses()
if len(bannedAddresses) != 1 {
t.Fatalf("Unexpected amount of addresses returned from BannedAddresses(). "+
"Want: %d, got: %d", 1, len(bannedAddresses))
}
if !reflect.DeepEqual(addressToBan, bannedAddresses[0]) {
t.Fatalf("Banned address %s not returned from BannedAddresses()", addressToBan.IP)
}
}
func TestOverfillAddressManager(t *testing.T) {
addressManager, teardown := newAddressManagerForTest(t, "TestAddressManager")
defer teardown()
generateTestAddresses := func(amount int) []*appmessage.NetAddress {
testAddresses := make([]*appmessage.NetAddress, 0, amount)
for i := byte(0); i < 128; i++ {
for j := byte(0); j < 128; j++ {
testAddress := &appmessage.NetAddress{IP: net.IP{1, 2, i, j}, Timestamp: mstime.Now()}
testAddresses = append(testAddresses, testAddress)
if len(testAddresses) == amount {
break
}
}
if len(testAddresses) == amount {
break
}
}
return testAddresses
}
// Add a single test address to the address manager
testAddress := &appmessage.NetAddress{IP: net.IP{5, 6, 0, 0}, Timestamp: mstime.Now()}
err := addressManager.AddAddress(testAddress)
if err != nil {
t.Fatalf("AddAddress: %s", err)
}
// Add `maxAddresses-1` addresses to the address manager
addresses := generateTestAddresses(maxAddresses - 1)
err = addressManager.AddAddresses(addresses...)
if err != nil {
t.Fatalf("AddAddresses: %s", err)
}
// Make sure that it now contains exactly `maxAddresses` entries
returnedAddresses := addressManager.Addresses()
if len(returnedAddresses) != maxAddresses {
t.Fatalf("Unexpected address amount. Want: %d, got: %d", maxAddresses, len(returnedAddresses))
}
// Mark the first test address as a connection failure
err = addressManager.MarkConnectionFailure(testAddress)
if err != nil {
t.Fatalf("MarkConnectionFailure: %s", err)
}
// Add one more address to the address manager
err = addressManager.AddAddress(&appmessage.NetAddress{IP: net.IP{7, 8, 0, 0}, Timestamp: mstime.Now()})
if err != nil {
t.Fatalf("AddAddress: %s", err)
}
// Make sure that it now still contains exactly `maxAddresses` entries
returnedAddresses = addressManager.Addresses()
if len(returnedAddresses) != maxAddresses {
t.Fatalf("Unexpected address amount. Want: %d, got: %d", maxAddresses, len(returnedAddresses))
}
// Make sure that the first address is no longer in the
// connection manager
for _, address := range returnedAddresses {
if address.IP.Equal(testAddress.IP) {
t.Fatalf("Unexpectedly found testAddress returned addresses")
}
}
}