Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(peer-connection-managenent): Functional Tests #2321

Merged
merged 7 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions tests/node/peer_manager/peer_store/test_migrations.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import std/[options], stew/results, testutils/unittests

import
../../../../waku/[node/peer_manager/peer_store/migrations],
../../waku_archive/archive_utils,
../../testlib/[simple_mock]

import std/[tables, strutils, os], stew/results, chronicles

import ../../../../waku/[common/databases/db_sqlite, common/databases/common]

suite "Migrations":
test "migrate ok":
# Given the db_sqlite.migrate function returns ok
let backup = db_sqlite.migrate
mock(db_sqlite.migrate):
proc mockedMigrate(
db: SqliteDatabase, targetVersion: int64, migrationsScriptsDir: string
): DatabaseResult[void] =
ok()

mockedMigrate

# When we call the migrate function
let migrationResult = migrations.migrate(newSqliteDatabase(), 1)

# Then we expect the result to be ok
check:
migrationResult == DatabaseResult[void].ok()

# Cleanup
mock(db_sqlite.migrate):
backup

test "migrate error":
# Given the db_sqlite.migrate function returns an error
let backup = db_sqlite.migrate
mock(db_sqlite.migrate):
proc mockedMigrate(
db: SqliteDatabase, targetVersion: int64, migrationsScriptsDir: string
): DatabaseResult[void] =
err("mock error")

mockedMigrate

# When we call the migrate function
let migrationResult = migrations.migrate(newSqliteDatabase(), 1)

# Then we expect the result to be an error
check:
migrationResult ==
DatabaseResult[void].err("failed to execute migration scripts: mock error")

# Cleanup
mock(db_sqlite.migrate):
backup
25 changes: 25 additions & 0 deletions tests/node/peer_manager/peer_store/test_peer_storage.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import stew/results, testutils/unittests

import
../../../../waku/node/peer_manager/peer_store/peer_storage,
../../../../waku/waku_core/peers

suite "PeerStorage":
var peerStorage {.threadvar.}: PeerStorage

setup:
peerStorage = PeerStorage()

suite "put":
test "unimplemented":
check:
peerStorage.put(nil) == PeerStorageResult[void].err("Unimplemented")

suite "getAll":
test "unimplemented":
let
emptyClosure =
proc(remotePeerInfo: RemotePeerInfo) =
discard
check:
peerStorage.getAll(emptyClosure) == PeerStorageResult[void].err("Unimplemented")
114 changes: 114 additions & 0 deletions tests/node/peer_manager/peer_store/test_waku_peer_storage.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import
std/[nativesockets, options, sequtils],
testutils/unittests,
libp2p/[multiaddress, peerid],
libp2p/crypto/crypto,
stew/shims/net,
eth/keys,
eth/p2p/discoveryv5/enr,
nimcrypto/utils

import
../../../../waku/waku_core/peers,
../../../../waku/node/peer_manager/peer_store/waku_peer_storage

proc `==`(a, b: RemotePeerInfo): bool =
let
comparisons =
@[
a.peerId == b.peerId,
a.addrs == b.addrs,
a.enr == b.enr,
a.protocols == b.protocols,
a.agent == b.agent,
a.protoVersion == b.protoVersion,
a.publicKey == b.publicKey,
a.connectedness == b.connectedness,
a.disconnectTime == b.disconnectTime,
a.origin == b.origin,
a.direction == b.direction,
a.lastFailedConn == b.lastFailedConn,
a.numberFailedConn == b.numberFailedConn
]

allIt(comparisons, it == true)

suite "Protobuf Serialisation":
let
privateKeyStr =
"08031279307702010104203E5B1FE9712E6C314942A750BD67485DE3C1EFE85B1BFB520AE8F9AE3DFA4A4CA00A06082A8648CE3D030107A14403420004DE3D300FA36AE0E8F5D530899D83ABAB44ABF3161F162A4BC901D8E6ECDA020E8B6D5F8DA30525E71D6851510C098E5C47C646A597FB4DCEC034E9F77C409E62"
publicKeyStr =
"0803125b3059301306072a8648ce3d020106082a8648ce3d03010703420004de3d300fa36ae0e8f5d530899d83abab44abf3161f162a4bc901d8e6ecda020e8b6d5f8da30525e71d6851510c098e5c47c646a597fb4dcec034e9f77c409e62"

var remotePeerInfo {.threadvar.}: RemotePeerInfo

setup:
let
port = Port(8080)
ipAddress = IpAddress(family: IPv4, address_v4: [192, 168, 0, 1])
multiAddress: MultiAddress =
MultiAddress.init(ipAddress, IpTransportProtocol.tcpProtocol, port)
encodedPeerIdStr = "16Uiu2HAmFccGe5iezmyRDQZuLPRP7FqpqXLjnocmMRk18pmTZs2j"

var peerId: PeerID
assert init(peerId, encodedPeerIdStr)

let
publicKey =
crypto.PublicKey.init(utils.fromHex(publicKeyStr)).expect("public key")
privateKey =
crypto.PrivateKey.init(utils.fromHex(privateKeyStr)).expect("private key")

remotePeerInfo = RemotePeerInfo.init(peerId, @[multiAddress])
remotePeerInfo.publicKey = publicKey

suite "encode":
test "simple":
# Given the expected bytes representation of a valid RemotePeerInfo
let
expectedBuffer: seq[byte] =
@[
10, 39, 0, 37, 8, 2, 18, 33, 3, 43, 246, 238, 219, 109, 147, 79, 129, 40,
145, 217, 209, 109, 105, 185, 186, 200, 180, 203, 72, 166, 220, 196, 232,
170, 74, 141, 125, 255, 112, 238, 204, 18, 8, 4, 192, 168, 0, 1, 6, 31, 144,
34, 95, 8, 3, 18, 91, 48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6,
8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 222, 61, 48, 15, 163, 106,
224, 232, 245, 213, 48, 137, 157, 131, 171, 171, 68, 171, 243, 22, 31, 22,
42, 75, 201, 1, 216, 230, 236, 218, 2, 14, 139, 109, 95, 141, 163, 5, 37,
231, 29, 104, 81, 81, 12, 9, 142, 92, 71, 198, 70, 165, 151, 251, 77, 206,
192, 52, 233, 247, 124, 64, 158, 98, 40, 0, 48, 0
]

# When converting a valid RemotePeerInfo to a ProtoBuffer
let encodedRemotePeerInfo = encode(remotePeerInfo).get()

# Then the encoded RemotePeerInfo should be equal to the expected bytes
check:
encodedRemotePeerInfo.buffer == expectedBuffer
encodedRemotePeerInfo.offset == 152
encodedRemotePeerInfo.length == 0
encodedRemotePeerInfo.maxSize == 4194304

suite "decode":
test "simple":
# Given the bytes representation of a valid RemotePeerInfo
let
buffer: seq[byte] =
@[
10, 39, 0, 37, 8, 2, 18, 33, 3, 43, 246, 238, 219, 109, 147, 79, 129, 40,
145, 217, 209, 109, 105, 185, 186, 200, 180, 203, 72, 166, 220, 196, 232,
170, 74, 141, 125, 255, 112, 238, 204, 18, 8, 4, 192, 168, 0, 1, 6, 31, 144,
34, 95, 8, 3, 18, 91, 48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6,
8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 222, 61, 48, 15, 163, 106,
224, 232, 245, 213, 48, 137, 157, 131, 171, 171, 68, 171, 243, 22, 31, 22,
42, 75, 201, 1, 216, 230, 236, 218, 2, 14, 139, 109, 95, 141, 163, 5, 37,
231, 29, 104, 81, 81, 12, 9, 142, 92, 71, 198, 70, 165, 151, 251, 77, 206,
192, 52, 233, 247, 124, 64, 158, 98, 40, 0, 48, 0
]

# When converting a valid buffer to RemotePeerInfo
let decodedRemotePeerInfo = RemotePeerInfo.decode(buffer).get()

# Then the decoded RemotePeerInfo should be equal to the original RemotePeerInfo
check:
decodedRemotePeerInfo == remotePeerInfo
3 changes: 3 additions & 0 deletions tests/testlib/sequtils.nim
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
proc toString*(bytes: seq[byte]): string =
cast[string](bytes)

proc toBytes*(str: string): seq[byte] =
cast[seq[byte]](str)
50 changes: 50 additions & 0 deletions tests/testlib/simple_mock.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Sourced from https://forum.nim-lang.org/t/9255#60617

import posix

type
Instr {.union.} = object
bytes: array[8, byte]
value: uint64

proc mockImpl(target, replacement: pointer) =
# YOLO who needs alignment
#doAssert (cast[ByteAddress](target) and ByteAddress(0x07)) == 0
var page = cast[pointer](cast[ByteAddress](target) and (not 0xfff))
doAssert mprotect(page, 4096, PROT_WRITE or PROT_EXEC) == 0
let rel = cast[ByteAddress](replacement) - cast[ByteAddress](target) - 5
var
instr =
Instr(
bytes: [
0xe9.byte,
(rel shr 0).byte,
(rel shr 8).byte,
(rel shr 16).byte,
(rel shr 24).byte,
0,
0,
0
]
)
cast[ptr uint64](target)[] = instr.value
doAssert mprotect(page, 4096, PROT_EXEC) == 0

# Note: Requires manual cleanup
# Usage Example:
# proc helloWorld(): string =
# "Hello, World!"
#
# echo helloWorld() # "Hello, World!"
#
# let backup = helloWorld
# mock(helloWorld):
# proc mockedHellWorld(): string =
# "Mocked Hello, World!"
# mockedMigrate
#
# echo helloWorld() # "Mocked Hello, World!"
#
# helloWorld = backup # Restore the original function
template mock*(target, replacement: untyped): untyped =
mockImpl(cast[pointer](target), cast[pointer](replacement))
Loading