nwaku/tests/v2/test_waku_pagination.nim

342 lines
13 KiB
Nim

{.used.}
import
std/[algorithm, options],
testutils/unittests, nimcrypto/sha2,
libp2p/protobuf/minprotobuf,
../../waku/v2/protocol/waku_store/waku_store,
../test_helpers
proc createSampleList(s: int): seq[IndexedWakuMessage] =
## takes s as input and outputs a sequence with s amount of IndexedWakuMessage
var data {.noinit.}: array[32, byte]
for x in data.mitems: x = 1
for i in 0..<s:
result.add(IndexedWakuMessage(msg: WakuMessage(payload: @[byte i]), index: Index(receiverTime: float64(i), senderTime: float64(i), digest: MDigest[256](data: data)) ))
procSuite "pagination":
test "Index computation test":
let
wm = WakuMessage(payload: @[byte 1, 2, 3], timestamp: 2)
index = wm.computeIndex()
check:
# the fields of the index should be non-empty
len(index.digest.data) != 0
len(index.digest.data) == 32 # sha2 output length in bytes
index.receiverTime != 0 # the receiver timestamp should be a non-zero value
index.senderTime == 2
let
wm1 = WakuMessage(payload: @[byte 1, 2, 3], contentTopic: ContentTopic("/waku/2/default-content/proto"))
index1 = wm1.computeIndex()
wm2 = WakuMessage(payload: @[byte 1, 2, 3], contentTopic: ContentTopic("/waku/2/default-content/proto"))
index2 = wm2.computeIndex()
check:
# the digests of two identical WakuMessages must be the same
index1.digest == index2.digest
test "Index comparison, IndexedWakuMessage comparison, and Sorting tests":
var data1 {.noinit.}: array[32, byte]
for x in data1.mitems: x = 1
var data2 {.noinit.}: array[32, byte]
for x in data2.mitems: x = 2
var data3 {.noinit.}: array[32, byte]
for x in data3.mitems: x = 3
let
index1 = Index(receiverTime: 2, senderTime: 1, digest: MDigest[256](data: data1))
index2 = Index(receiverTime: 2, senderTime: 1, digest: MDigest[256](data: data2))
index3 = Index(receiverTime: 1, senderTime: 2, digest: MDigest[256](data: data3))
iwm1 = IndexedWakuMessage(index: index1)
iwm2 = IndexedWakuMessage(index: index2)
iwm3 = IndexedWakuMessage(index: index3)
check:
indexComparison(index1, index1) == 0
indexComparison(index1, index2) == -1
indexComparison(index2, index1) == 1
indexComparison(index1, index3) == -1
indexComparison(index3, index1) == 1
check:
indexedWakuMessageComparison(iwm1, iwm1) == 0
indexedWakuMessageComparison(iwm1, iwm2) == -1
indexedWakuMessageComparison(iwm2, iwm1) == 1
indexedWakuMessageComparison(iwm1, iwm3) == -1
indexedWakuMessageComparison(iwm3, iwm1) == 1
var sortingList = @[iwm3, iwm1, iwm2]
sortingList.sort(indexedWakuMessageComparison)
check:
sortingList[0] == iwm1
sortingList[1] == iwm2
sortingList[2] == iwm3
test "Find Index test":
let msgList = createSampleList(10)
check:
msgList.findIndex(msgList[3].index).get() == 3
msgList.findIndex(Index()).isNone == true
test "Forward pagination test":
var
msgList = createSampleList(10)
pagingInfo = PagingInfo(pageSize: 2, cursor: msgList[3].index, direction: PagingDirection.FORWARD)
# test for a normal pagination
var (data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data.len == 2
data == msgList[4..5]
newPagingInfo.cursor == msgList[5].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == pagingInfo.pageSize
error == HistoryResponseError.NONE
# test for an initial pagination request with an empty cursor
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.FORWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data.len == 2
data == msgList[0..1]
newPagingInfo.cursor == msgList[1].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 2
error == HistoryResponseError.NONE
# test for an initial pagination request with an empty cursor to fetch the entire history
pagingInfo = PagingInfo(pageSize: 13, direction: PagingDirection.FORWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data.len == 10
data == msgList[0..9]
newPagingInfo.cursor == msgList[9].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 10
error == HistoryResponseError.NONE
# test for an empty msgList
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.FORWARD)
(data, newPagingInfo, error) = paginate(@[], pagingInfo)
check:
data.len == 0
newPagingInfo.pageSize == 0
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.cursor == pagingInfo.cursor
error == HistoryResponseError.NONE
# test for a page size larger than the remaining messages
pagingInfo = PagingInfo(pageSize: 10, cursor: msgList[3].index, direction: PagingDirection.FORWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data.len == 6
data == msgList[4..9]
newPagingInfo.cursor == msgList[9].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 6
error == HistoryResponseError.NONE
# test for a page size larger than the maximum allowed page size
pagingInfo = PagingInfo(pageSize: MaxPageSize+1, cursor: msgList[3].index, direction: PagingDirection.FORWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
uint64(data.len) <= MaxPageSize
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize <= MaxPageSize
error == HistoryResponseError.NONE
# test for a cursor pointing to the end of the message list
pagingInfo = PagingInfo(pageSize: 10, cursor: msgList[9].index, direction: PagingDirection.FORWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data.len == 0
newPagingInfo.cursor == msgList[9].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 0
error == HistoryResponseError.NONE
# test for an invalid cursor
pagingInfo = PagingInfo(pageSize: 10, cursor: computeIndex(WakuMessage(payload: @[byte 10])), direction: PagingDirection.FORWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data.len == 0
newPagingInfo.cursor == pagingInfo.cursor
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 0
error == HistoryResponseError.INVALID_CURSOR
# test initial paging query over a message list with one message
var singleItemMsgList = msgList[0..0]
pagingInfo = PagingInfo(pageSize: 10, direction: PagingDirection.FORWARD)
(data, newPagingInfo, error) = paginate(singleItemMsgList, pagingInfo)
check:
data.len == 1
newPagingInfo.cursor == msgList[0].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 1
error == HistoryResponseError.NONE
# test pagination over a message list with one message
singleItemMsgList = msgList[0..0]
pagingInfo = PagingInfo(pageSize: 10, cursor: msgList[0].index, direction: PagingDirection.FORWARD)
(data, newPagingInfo, error) = paginate(singleItemMsgList, pagingInfo)
check:
data.len == 0
newPagingInfo.cursor == msgList[0].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 0
error == HistoryResponseError.NONE
test "Backward pagination test":
var
msgList = createSampleList(10)
pagingInfo = PagingInfo(pageSize: 2, cursor: msgList[3].index, direction: PagingDirection.BACKWARD)
# test for a normal pagination
var (data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data == msgList[1..2]
newPagingInfo.cursor == msgList[1].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == pagingInfo.pageSize
error == HistoryResponseError.NONE
# test for an empty msgList
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.BACKWARD)
(data, newPagingInfo, error) = paginate(@[], pagingInfo)
check:
data.len == 0
newPagingInfo.pageSize == 0
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.cursor == pagingInfo.cursor
error == HistoryResponseError.NONE
# test for an initial pagination request with an empty cursor
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.BACKWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data.len == 2
data == msgList[8..9]
newPagingInfo.cursor == msgList[8].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 2
error == HistoryResponseError.NONE
# test for an initial pagination request with an empty cursor to fetch the entire history
pagingInfo = PagingInfo(pageSize: 13, direction: PagingDirection.BACKWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data.len == 10
data == msgList[0..9]
newPagingInfo.cursor == msgList[0].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 10
error == HistoryResponseError.NONE
# test for a page size larger than the remaining messages
pagingInfo = PagingInfo(pageSize: 5, cursor: msgList[3].index, direction: PagingDirection.BACKWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data == msgList[0..2]
newPagingInfo.cursor == msgList[0].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 3
error == HistoryResponseError.NONE
# test for a page size larger than the Maximum allowed page size
pagingInfo = PagingInfo(pageSize: MaxPageSize+1, cursor: msgList[3].index, direction: PagingDirection.BACKWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
uint64(data.len) <= MaxPageSize
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize <= MaxPageSize
error == HistoryResponseError.NONE
# test for a cursor pointing to the begining of the message list
pagingInfo = PagingInfo(pageSize: 5, cursor: msgList[0].index, direction: PagingDirection.BACKWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data.len == 0
newPagingInfo.cursor == msgList[0].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 0
error == HistoryResponseError.NONE
# test for an invalid cursor
pagingInfo = PagingInfo(pageSize: 5, cursor: computeIndex(WakuMessage(payload: @[byte 10])), direction: PagingDirection.BACKWARD)
(data, newPagingInfo, error) = paginate(msgList, pagingInfo)
check:
data.len == 0
newPagingInfo.cursor == pagingInfo.cursor
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 0
error == HistoryResponseError.INVALID_CURSOR
# test initial paging query over a message list with one message
var singleItemMsgList = msgList[0..0]
pagingInfo = PagingInfo(pageSize: 10, direction: PagingDirection.BACKWARD)
(data, newPagingInfo, error) = paginate(singleItemMsgList, pagingInfo)
check:
data.len == 1
newPagingInfo.cursor == msgList[0].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 1
error == HistoryResponseError.NONE
# test paging query over a message list with one message
singleItemMsgList = msgList[0..0]
pagingInfo = PagingInfo(pageSize: 10, cursor: msgList[0].index, direction: PagingDirection.BACKWARD)
(data, newPagingInfo, error) = paginate(singleItemMsgList, pagingInfo)
check:
data.len == 0
newPagingInfo.cursor == msgList[0].index
newPagingInfo.direction == pagingInfo.direction
newPagingInfo.pageSize == 0
error == HistoryResponseError.NONE
suite "time-window history query":
test "Encode/Decode waku message with timestamp":
# test encoding and decoding of the timestamp field of a WakuMessage
# Encoding
let
version = 0'u32
payload = @[byte 0, 1, 2]
timestamp = float64(10)
msg = WakuMessage(payload: payload, version: version, timestamp: timestamp)
pb = msg.encode()
# Decoding
let
msgDecoded = WakuMessage.init(pb.buffer)
check:
msgDecoded.isOk()
let
timestampDecoded = msgDecoded.value.timestamp
check:
timestampDecoded == timestamp
test "Encode/Decode waku message without timestamp":
# test the encoding and decoding of a WakuMessage with an empty timestamp field
# Encoding
let
version = 0'u32
payload = @[byte 0, 1, 2]
msg = WakuMessage(payload: payload, version: version)
pb = msg.encode()
# Decoding
let
msgDecoded = WakuMessage.init(pb.buffer)
doAssert:
msgDecoded.isOk()
let
timestampDecoded = msgDecoded.value.timestamp
check:
timestampDecoded == float64(0)