nuked & revived router_info_test.go
-TestRouterInfoCapabilities() fails -TestRouterInfoVersion() fails
This commit is contained in:
@@ -1,34 +1,52 @@
|
||||
test-router-info-all: test-router-info-published test-router-info-addresses test-router-info-identity test-router-info-misc test-router-info-create test-router-info-10k
|
||||
test-router-info-all: test-router-info-creation test-router-info-published-date test-router-info-identity test-router-info-addresses test-router-info-serialization test-router-info-signature test-router-info-capabilities test-router-info-version test-router-info-good-version test-router-info-uncongested test-router-info-reachable test-router-info-10k
|
||||
|
||||
test-router-info-published:
|
||||
$(GO) test -v ./lib/common/router_info -run TestPublishedReturnsCorrectDate
|
||||
$(GO) test -v ./lib/common/router_info -run TestPublishedReturnsCorrectErrorWithPartialDate
|
||||
$(GO) test -v ./lib/common/router_info -run TestPublishedReturnsCorrectErrorWithInvalidData
|
||||
test-router-info-creation:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoCreation
|
||||
$(GO) test -v ./lib/common/router_info -run TestCreateRouterInfo
|
||||
|
||||
test-router-info-addresses:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterAddressCountReturnsCorrectCount
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterAddressCountReturnsCorrectErrorWithInvalidData
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterAddressesReturnsAddresses
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterAddressesReturnsAddressesWithMultiple
|
||||
test-router-info-published-date:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoPublishedDate
|
||||
|
||||
test-router-info-identity:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterIdentityIsCorrect
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoRouterIdentity
|
||||
|
||||
test-router-info-misc:
|
||||
$(GO) test -v ./lib/common/router_info -run TestPeerSizeIsZero
|
||||
$(GO) test -v ./lib/common/router_info -run TestOptionsAreCorrect
|
||||
$(GO) test -v ./lib/common/router_info -run TestSignatureIsCorrectSize
|
||||
test-router-info-addresses:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoAddresses
|
||||
|
||||
test-router-info-create:
|
||||
$(GO) test -v ./lib/common/router_info -run TestCreateRouterInfo
|
||||
test-router-info-serialization:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoSerialization
|
||||
|
||||
test-router-info-signature:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoSignature
|
||||
|
||||
test-router-info-capabilities:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoCapabilities
|
||||
|
||||
test-router-info-version:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoVersion
|
||||
|
||||
test-router-info-good-version:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoGoodVersion
|
||||
|
||||
test-router-info-uncongested:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoUnCongested
|
||||
|
||||
test-router-info-reachable:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoReachable
|
||||
|
||||
test-router-info-10k:
|
||||
$(GO) test -v ./lib/common/router_info -run Test10K
|
||||
|
||||
.PHONY: test-router-info-all \
|
||||
test-router-info-published \
|
||||
test-router-info-addresses \
|
||||
test-router-info-creation \
|
||||
test-router-info-published-date \
|
||||
test-router-info-identity \
|
||||
test-router-info-misc \
|
||||
test-router-info-create \
|
||||
test-router-info-addresses \
|
||||
test-router-info-serialization \
|
||||
test-router-info-signature \
|
||||
test-router-info-capabilities \
|
||||
test-router-info-version \
|
||||
test-router-info-good-version \
|
||||
test-router-info-uncongested \
|
||||
test-router-info-reachable \
|
||||
test-router-info-10k
|
@@ -2,208 +2,232 @@ package router_info
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
common "github.com/go-i2p/go-i2p/lib/common/data"
|
||||
"github.com/go-i2p/go-i2p/lib/common/router_address"
|
||||
"github.com/go-i2p/go-i2p/lib/common/certificate"
|
||||
"github.com/go-i2p/go-i2p/lib/common/data"
|
||||
"github.com/go-i2p/go-i2p/lib/common/router_identity"
|
||||
"github.com/go-i2p/go-i2p/lib/common/signature"
|
||||
"github.com/go-i2p/go-i2p/lib/crypto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/crypto/openpgp/elgamal"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/common/router_address"
|
||||
)
|
||||
|
||||
func buildRouterIdentity() router_identity.RouterIdentity {
|
||||
router_ident_data := make([]byte, 128+256)
|
||||
router_ident_data = append(router_ident_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00}...)
|
||||
return_data, _, _ := router_identity.ReadRouterIdentity(router_ident_data)
|
||||
return return_data
|
||||
}
|
||||
|
||||
func buildDate() []byte {
|
||||
date_data := []byte{0x00, 0x00, 0x00, 0x00, 0x05, 0x26, 0x5c, 0x00}
|
||||
return date_data
|
||||
}
|
||||
|
||||
func buildMapping() *common.Mapping {
|
||||
mapping, _ := common.GoMapToMapping(map[string]string{"host": "127.0.0.1", "port": "4567"})
|
||||
return mapping
|
||||
}
|
||||
|
||||
func buildRouterAddress(transport string) router_address.RouterAddress {
|
||||
router_address_bytes := []byte{0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
str, _ := common.ToI2PString(transport)
|
||||
router_address_bytes = append(router_address_bytes, []byte(str)...)
|
||||
router_address_bytes = append(router_address_bytes, buildMapping().Data()...)
|
||||
return_data, _, _ := router_address.ReadRouterAddress(router_address_bytes)
|
||||
return return_data
|
||||
}
|
||||
|
||||
func buildFullRouterInfo(rid ...[]byte) (RouterInfo, error) {
|
||||
var ri RouterInfo
|
||||
var err error
|
||||
if rid == nil || len(rid) == 0 {
|
||||
router_info_data := make([]byte, 0)
|
||||
router_info_data = append(router_info_data, buildRouterIdentity().KeysAndCert.Bytes()...)
|
||||
router_info_data = append(router_info_data, buildDate()...)
|
||||
router_info_data = append(router_info_data, 0x01)
|
||||
router_info_data = append(router_info_data, buildRouterAddress("foo").Bytes()...)
|
||||
router_info_data = append(router_info_data, 0x00)
|
||||
router_info_data = append(router_info_data, buildMapping().Data()...)
|
||||
router_info_data = append(router_info_data, make([]byte, 40)...)
|
||||
ri, _, err = ReadRouterInfo(router_info_data)
|
||||
} else {
|
||||
ri, _, err = ReadRouterInfo(rid[0])
|
||||
func generateTestRouterInfo(t *testing.T, publishedTime time.Time) (*RouterInfo, error) {
|
||||
// Step 1: Generate Signing Key Pair (Ed25519)
|
||||
var ed25519PrivKey crypto.Ed25519PrivateKey
|
||||
_, err := (&ed25519PrivKey).Generate()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate Ed25519 private key: %v", err)
|
||||
}
|
||||
return ri, err
|
||||
}
|
||||
|
||||
func TestPublishedReturnsCorrectDate(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info, _ := buildFullRouterInfo()
|
||||
date := router_info.Published()
|
||||
assert.Equal(int64(86400), date.Time().Unix(), "RouterInfo.Published() did not return correct date")
|
||||
}
|
||||
|
||||
func TestPublishedReturnsCorrectErrorWithPartialDate(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info, err := buildFullRouterInfo()
|
||||
assert.Nil(err)
|
||||
bytes, err := router_info.Bytes()
|
||||
router_info, err = buildFullRouterInfo(bytes[:387+4])
|
||||
//_ := router_info.Published()
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("error parsing date: not enough data", err.Error())
|
||||
ed25519PubKeyRaw, err := ed25519PrivKey.Public()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to derive Ed25519 public key: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublishedReturnsCorrectErrorWithInvalidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info, err := buildFullRouterInfo()
|
||||
if assert.Nil(err) {
|
||||
bytes, err := router_info.Bytes()
|
||||
router_info, err = buildFullRouterInfo(bytes[:56])
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("error parsing KeysAndCert: data is smaller than minimum valid size", err.Error())
|
||||
}
|
||||
} else {
|
||||
assert.Fail("error building router info")
|
||||
ed25519PubKey, ok := ed25519PubKeyRaw.(crypto.SigningPublicKey)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to assert Ed25519 public key to SigningPublicKey")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterAddressCountReturnsCorrectCount(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info, _ := buildFullRouterInfo()
|
||||
count := router_info.RouterAddressCount()
|
||||
assert.Equal(1, count, "RouterInfo.RouterAddressCount() did not return correct count")
|
||||
}
|
||||
|
||||
func TestRouterAddressCountReturnsCorrectErrorWithInvalidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info, err := buildFullRouterInfo()
|
||||
if assert.Nil(err) {
|
||||
bytes, err := router_info.Bytes()
|
||||
router_info, err = buildFullRouterInfo(bytes[:387+8])
|
||||
|
||||
count := router_info.RouterAddressCount()
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("error parsing router addresses: not enough data", err.Error())
|
||||
}
|
||||
assert.Equal(0, count)
|
||||
// Step 2: Generate Encryption Key Pair (ElGamal)
|
||||
var elgamalPrivKey elgamal.PrivateKey
|
||||
err = crypto.ElgamalGenerate(&elgamalPrivKey, rand.Reader)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate ElGamal private key: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterAddressesReturnsAddresses(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info, err := buildFullRouterInfo()
|
||||
router_addresses := router_info.RouterAddresses()
|
||||
assert.Nil(err)
|
||||
if assert.Equal(1, len(router_addresses)) {
|
||||
assert.Equal(
|
||||
0,
|
||||
bytes.Compare(
|
||||
[]byte(buildRouterAddress("foo").Bytes()),
|
||||
[]byte(router_addresses[0].Bytes()),
|
||||
),
|
||||
)
|
||||
// Convert ElGamal Private Key to crypto.ElgPrivateKey
|
||||
var elgPrivKey crypto.ElgPrivateKey
|
||||
xBytes := elgamalPrivKey.X.Bytes()
|
||||
if len(xBytes) > 256 {
|
||||
return nil, fmt.Errorf("ElGamal private key X too large")
|
||||
}
|
||||
}
|
||||
copy(elgPrivKey[256-len(xBytes):], xBytes)
|
||||
|
||||
func TestRouterAddressesReturnsAddressesWithMultiple(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info_data := make([]byte, 0)
|
||||
router_info_data = append(router_info_data, buildRouterIdentity().KeysAndCert.Bytes()...)
|
||||
router_info_data = append(router_info_data, buildDate()...)
|
||||
router_info_data = append(router_info_data, 0x03)
|
||||
router_info_data = append(router_info_data, buildRouterAddress("foo0").Bytes()...)
|
||||
router_info_data = append(router_info_data, buildRouterAddress("foo1").Bytes()...)
|
||||
router_info_data = append(router_info_data, buildRouterAddress("foo2").Bytes()...)
|
||||
router_info_data = append(router_info_data, 0x00)
|
||||
router_info_data = append(router_info_data, buildMapping().Data()...)
|
||||
router_info_data = append(router_info_data, make([]byte, 40)...)
|
||||
router_info, _, _ := ReadRouterInfo(router_info_data)
|
||||
|
||||
count := router_info.RouterAddressCount()
|
||||
if assert.Equal(3, count) {
|
||||
router_addresses := router_info.RouterAddresses()
|
||||
for i := 0; i < 3; i++ {
|
||||
assert.Equal(
|
||||
0,
|
||||
bytes.Compare(
|
||||
[]byte(buildRouterAddress(fmt.Sprintf("foo%d", i)).Bytes()),
|
||||
[]byte(router_addresses[i].Bytes()),
|
||||
),
|
||||
)
|
||||
}
|
||||
// Convert ElGamal Public Key to crypto.ElgPublicKey
|
||||
var elgPubKey crypto.ElgPublicKey
|
||||
yBytes := elgamalPrivKey.PublicKey.Y.Bytes()
|
||||
if len(yBytes) > 256 {
|
||||
return nil, fmt.Errorf("ElGamal public key Y too large")
|
||||
}
|
||||
copy(elgPubKey[256-len(yBytes):], yBytes)
|
||||
|
||||
// Ensure ElGamal Public Key implements crypto.PublicKey interface
|
||||
var _ crypto.PublicKey = elgPubKey
|
||||
|
||||
// Step 3: Create KeyCertificate specifying key types
|
||||
var payload bytes.Buffer
|
||||
|
||||
signingPublicKeyType, err := data.NewIntegerFromInt(7, 2)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create signing public key type integer: %v", err)
|
||||
}
|
||||
|
||||
cryptoPublicKeyType, err := data.NewIntegerFromInt(0, 2)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create crypto public key type integer: %v", err)
|
||||
}
|
||||
|
||||
// Write the bytes of the Integer instances to the payload
|
||||
payload.Write(*signingPublicKeyType)
|
||||
payload.Write(*cryptoPublicKeyType)
|
||||
|
||||
// Create KeyCertificate
|
||||
cert, err := certificate.NewCertificateWithType(certificate.CERT_KEY, payload.Bytes())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create new certificate: %v", err)
|
||||
}
|
||||
|
||||
// Step 4: Create RouterIdentity
|
||||
routerIdentity, err := router_identity.NewRouterIdentity(elgPubKey, ed25519PubKey, *cert, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create RouterIdentity: %v", err)
|
||||
}
|
||||
|
||||
// Step 5: Create RouterAddress
|
||||
options := map[string]string{}
|
||||
routerAddress, err := router_address.NewRouterAddress(3, <-time.After(1*time.Second), "NTCP2", options)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create RouterAddress: %v", err)
|
||||
}
|
||||
routerAddresses := []*router_address.RouterAddress{routerAddress}
|
||||
|
||||
// Step 6: Create RouterInfo
|
||||
routerInfo, err := NewRouterInfo(routerIdentity, publishedTime, routerAddresses, nil, &ed25519PrivKey, signature.SIGNATURE_TYPE_EDDSA_SHA512_ED25519)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create RouterInfo: %v", err)
|
||||
}
|
||||
|
||||
return routerInfo, nil
|
||||
}
|
||||
|
||||
func TestPeerSizeIsZero(t *testing.T) {
|
||||
// TestRouterInfoCreation verifies that a RouterInfo object can be created without errors.
|
||||
func TestRouterInfoCreation(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info, _ := buildFullRouterInfo()
|
||||
size := router_info.PeerSize()
|
||||
assert.Equal(0, size, "RouterInfo.PeerSize() did not return 0")
|
||||
// Use helper function to generate a RouterInfo
|
||||
publishedTime := time.Now()
|
||||
routerInfo, err := generateTestRouterInfo(t, publishedTime)
|
||||
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
assert.NotNil(routerInfo, "RouterInfo should not be nil")
|
||||
}
|
||||
|
||||
func TestOptionsAreCorrect(t *testing.T) {
|
||||
// TestRouterInfoPublishedDate verifies that the published date is correctly set and retrieved.
|
||||
func TestRouterInfoPublishedDate(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info, _ := buildFullRouterInfo()
|
||||
options := router_info.Options()
|
||||
assert.Equal(
|
||||
0,
|
||||
bytes.Compare(
|
||||
[]byte(buildMapping().Data()),
|
||||
[]byte(options.Data()),
|
||||
),
|
||||
)
|
||||
publishedTime := time.Unix(86400, 0) // 1 day since epoch
|
||||
routerInfo, err := generateTestRouterInfo(t, publishedTime)
|
||||
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
assert.Equal(publishedTime.Unix(), routerInfo.Published().Time().Unix(), "Published date should match the input date")
|
||||
}
|
||||
|
||||
func TestSignatureIsCorrectSize(t *testing.T) {
|
||||
// TestRouterInfoRouterIdentity verifies that the RouterIdentity is correctly set.
|
||||
func TestRouterInfoRouterIdentity(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info, _ := buildFullRouterInfo()
|
||||
signature := router_info.Signature()
|
||||
assert.Equal(40, len(signature))
|
||||
routerInfo, err := generateTestRouterInfo(t, time.Now())
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
|
||||
routerIdentity := routerInfo.RouterIdentity()
|
||||
assert.NotNil(routerIdentity, "RouterIdentity should not be nil")
|
||||
}
|
||||
|
||||
func TestRouterIdentityIsCorrect(t *testing.T) {
|
||||
// TestRouterInfoAddresses verifies that the RouterAddresses are correctly set and retrieved.
|
||||
func TestRouterInfoAddresses(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
router_info, _ := buildFullRouterInfo()
|
||||
router_identity := router_info.RouterIdentity()
|
||||
// assert.Nil(err)
|
||||
assert.Equal(
|
||||
0,
|
||||
bytes.Compare(
|
||||
[]byte(buildRouterIdentity().KeysAndCert.Bytes()),
|
||||
[]byte(router_identity.KeysAndCert.Bytes()),
|
||||
),
|
||||
)
|
||||
routerInfo, err := generateTestRouterInfo(t, time.Now())
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
|
||||
addresses := routerInfo.RouterAddresses()
|
||||
assert.NotNil(addresses, "RouterAddresses should not be nil")
|
||||
assert.Greater(len(addresses), 0, "RouterAddresses should have at least one address")
|
||||
}
|
||||
|
||||
// TestRouterInfoSerialization verifies that the RouterInfo can be serialized to bytes without error.
|
||||
func TestRouterInfoSerialization(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
routerInfo, err := generateTestRouterInfo(t, time.Now())
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
|
||||
bytes, err := routerInfo.Bytes()
|
||||
assert.Nil(err, "Serialization should not return an error")
|
||||
assert.NotNil(bytes, "Serialized bytes should not be nil")
|
||||
assert.Greater(len(bytes), 0, "Serialized bytes should have a length greater than zero")
|
||||
}
|
||||
|
||||
// TestRouterInfoSignature verifies that the signature is correctly set in the RouterInfo.
|
||||
func TestRouterInfoSignature(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
routerInfo, err := generateTestRouterInfo(t, time.Now())
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
|
||||
signature := routerInfo.Signature()
|
||||
assert.NotNil(signature, "Signature should not be nil")
|
||||
}
|
||||
|
||||
// TestRouterInfoCapabilities verifies the RouterCapabilities method functionality.
|
||||
func TestRouterInfoCapabilities(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
routerInfo, err := generateTestRouterInfo(t, time.Now())
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
|
||||
capabilities := routerInfo.RouterCapabilities()
|
||||
assert.NotEmpty(capabilities, "RouterCapabilities should not be empty")
|
||||
}
|
||||
|
||||
// TestRouterInfoVersion verifies the RouterVersion method functionality.
|
||||
func TestRouterInfoVersion(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
routerInfo, err := generateTestRouterInfo(t, time.Now())
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
|
||||
version := routerInfo.RouterVersion()
|
||||
assert.NotEmpty(version, "RouterVersion should not be empty")
|
||||
}
|
||||
|
||||
// TestRouterInfoGoodVersion verifies the GoodVersion method functionality.
|
||||
func TestRouterInfoGoodVersion(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
routerInfo, err := generateTestRouterInfo(t, time.Now())
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
|
||||
isGoodVersion := routerInfo.GoodVersion()
|
||||
assert.IsType(true, isGoodVersion, "GoodVersion should return a boolean")
|
||||
}
|
||||
|
||||
// TestRouterInfoUnCongested verifies the UnCongested method functionality.
|
||||
func TestRouterInfoUnCongested(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
routerInfo, err := generateTestRouterInfo(t, time.Now())
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
|
||||
isUncongested := routerInfo.UnCongested()
|
||||
assert.IsType(true, isUncongested, "UnCongested should return a boolean")
|
||||
}
|
||||
|
||||
// TestRouterInfoReachable verifies the Reachable method functionality.
|
||||
func TestRouterInfoReachable(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
routerInfo, err := generateTestRouterInfo(t, time.Now())
|
||||
assert.Nil(err, "RouterInfo creation should not return an error")
|
||||
|
||||
isReachable := routerInfo.Reachable()
|
||||
assert.IsType(true, isReachable, "Reachable should return a boolean")
|
||||
}
|
||||
|
Reference in New Issue
Block a user