2020-10-30 19:00:14 +00:00
|
|
|
{.used.}
|
2022-07-25 11:01:37 +00:00
|
|
|
|
2020-10-20 02:20:44 +00:00
|
|
|
import
|
2022-08-01 10:37:45 +00:00
|
|
|
std/[options, sequtils, times],
|
2022-07-25 11:01:37 +00:00
|
|
|
testutils/unittests,
|
|
|
|
nimcrypto/sha2,
|
|
|
|
libp2p/protobuf/minprotobuf
|
|
|
|
import
|
|
|
|
../../waku/v2/node/storage/message/waku_store_queue,
|
|
|
|
../../waku/v2/protocol/waku_store,
|
|
|
|
../../waku/v2/protocol/waku_message,
|
|
|
|
../../waku/v2/utils/time,
|
|
|
|
../../waku/v2/utils/pagination
|
2020-10-20 02:20:44 +00:00
|
|
|
|
2020-11-09 04:48:09 +00:00
|
|
|
|
2022-08-01 10:37:45 +00:00
|
|
|
const
|
2022-08-01 16:21:11 +00:00
|
|
|
DefaultPubsubTopic = "/waku/2/default-waku/proto"
|
|
|
|
DefaultContentTopic = ContentTopic("/waku/2/default-content/proto")
|
2022-08-01 10:37:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
proc getTestStoreQueue(numMessages: int): StoreQueueRef =
|
|
|
|
let testStoreQueue = StoreQueueRef.new(numMessages)
|
2022-02-17 10:00:45 +00:00
|
|
|
|
2020-11-09 04:48:09 +00:00
|
|
|
var data {.noinit.}: array[32, byte]
|
|
|
|
for x in data.mitems: x = 1
|
2022-02-17 10:00:45 +00:00
|
|
|
|
2022-08-01 10:37:45 +00:00
|
|
|
for i in 0..<numMessages:
|
|
|
|
let msg = IndexedWakuMessage(
|
|
|
|
msg: WakuMessage(payload: @[byte i]),
|
|
|
|
index: Index(
|
|
|
|
receiverTime: Timestamp(i),
|
|
|
|
senderTime: Timestamp(i),
|
|
|
|
digest: MDigest[256](data: data)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
discard testStoreQueue.add(msg)
|
2022-02-17 10:00:45 +00:00
|
|
|
|
|
|
|
return testStoreQueue
|
2020-11-09 04:48:09 +00:00
|
|
|
|
2022-08-01 10:37:45 +00:00
|
|
|
proc getTestTimestamp(): Timestamp =
|
|
|
|
let now = getNanosecondTime(epochTime())
|
|
|
|
Timestamp(now)
|
2020-10-20 02:20:44 +00:00
|
|
|
|
2022-08-01 10:37:45 +00:00
|
|
|
suite "Queue store - pagination":
|
2020-11-09 04:48:09 +00:00
|
|
|
test "Forward pagination test":
|
2022-09-27 19:10:11 +00:00
|
|
|
let
|
|
|
|
store = getTestStoreQueue(10)
|
|
|
|
indexList = toSeq(store.fwdIterator()).mapIt(it[0]) # Seq copy of the store queue indices for verification
|
|
|
|
msgList = toSeq(store.fwdIterator()).mapIt(it[1].msg) # Seq copy of the store queue messages for verification
|
|
|
|
|
|
|
|
var pagingInfo = PagingInfo(pageSize: 2, cursor: indexList[3].toPagingIndex(), direction: PagingDirection.FORWARD)
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for a normal pagination
|
2022-09-27 19:10:11 +00:00
|
|
|
var (data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 2
|
|
|
|
data == msgList[4..5]
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[5].toPagingIndex()
|
2020-11-09 04:48:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == pagingInfo.pageSize
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for an initial pagination request with an empty cursor
|
|
|
|
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.FORWARD)
|
2022-09-27 19:10:11 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 2
|
|
|
|
data == msgList[0..1]
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[1].toPagingIndex()
|
2020-11-09 04:48:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 2
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2021-04-12 17:29:09 +00:00
|
|
|
|
|
|
|
# test for an initial pagination request with an empty cursor to fetch the entire history
|
|
|
|
pagingInfo = PagingInfo(pageSize: 13, direction: PagingDirection.FORWARD)
|
2022-09-27 19:10:11 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2021-04-12 17:29:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 10
|
|
|
|
data == msgList[0..9]
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[9].toPagingIndex()
|
2021-04-12 17:29:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 10
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for an empty msgList
|
|
|
|
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.FORWARD)
|
2022-08-01 10:37:45 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(getTestStoreQueue(0), pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 0
|
|
|
|
newPagingInfo.pageSize == 0
|
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.cursor == pagingInfo.cursor
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for a page size larger than the remaining messages
|
2022-09-27 19:10:11 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: 10, cursor: indexList[3].toPagingIndex(), direction: PagingDirection.FORWARD)
|
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 6
|
|
|
|
data == msgList[4..9]
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[9].toPagingIndex()
|
2020-11-09 04:48:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 6
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for a page size larger than the maximum allowed page size
|
2022-09-27 19:10:11 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: MaxPageSize+1, cursor: indexList[3].toPagingIndex(), direction: PagingDirection.FORWARD)
|
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
2021-04-09 10:04:21 +00:00
|
|
|
uint64(data.len) <= MaxPageSize
|
2020-11-09 04:48:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize <= MaxPageSize
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
2021-07-13 19:01:21 +00:00
|
|
|
# test for a cursor pointing to the end of the message list
|
2022-09-27 19:10:11 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: 10, cursor: indexList[9].toPagingIndex(), direction: PagingDirection.FORWARD)
|
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 0
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[9].toPagingIndex()
|
2020-11-09 04:48:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 0
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for an invalid cursor
|
2022-09-27 19:10:11 +00:00
|
|
|
let index = PagingIndex.compute(WakuMessage(payload: @[byte 10]), getTestTimestamp(), DefaultPubsubTopic)
|
2022-08-01 10:37:45 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: 10, cursor: index, direction: PagingDirection.FORWARD)
|
2022-09-27 19:10:11 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 0
|
|
|
|
newPagingInfo.cursor == pagingInfo.cursor
|
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 0
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.INVALID_CURSOR
|
2021-04-12 17:29:09 +00:00
|
|
|
|
|
|
|
# test initial paging query over a message list with one message
|
2022-08-01 10:37:45 +00:00
|
|
|
var singleItemMsgList = getTestStoreQueue(1)
|
2021-04-12 17:29:09 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: 10, direction: PagingDirection.FORWARD)
|
2022-02-17 10:00:45 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(singleItemMsgList, pagingInfo)
|
2021-04-12 17:29:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 1
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[0].toPagingIndex()
|
2021-04-12 17:29:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 1
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2021-04-12 17:29:09 +00:00
|
|
|
|
|
|
|
# test pagination over a message list with one message
|
2022-08-01 10:37:45 +00:00
|
|
|
singleItemMsgList = getTestStoreQueue(1)
|
2022-09-27 19:10:11 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: 10, cursor: indexList[0].toPagingIndex(), direction: PagingDirection.FORWARD)
|
2022-02-17 10:00:45 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(singleItemMsgList, pagingInfo)
|
2021-04-12 17:29:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 0
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[0].toPagingIndex()
|
2021-04-12 17:29:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 0
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2021-04-12 17:29:09 +00:00
|
|
|
|
2020-11-09 04:48:09 +00:00
|
|
|
test "Backward pagination test":
|
2022-09-27 19:10:11 +00:00
|
|
|
let
|
|
|
|
store = getTestStoreQueue(10)
|
|
|
|
indexList = toSeq(store.fwdIterator()).mapIt(it[0]) # Seq copy of the store queue indices for verification
|
|
|
|
msgList = toSeq(store.fwdIterator()).mapIt(it[1].msg) # Seq copy of the store queue messages for verification
|
|
|
|
|
|
|
|
var pagingInfo = PagingInfo(pageSize: 2, cursor: indexList[3].toPagingIndex(), direction: PagingDirection.BACKWARD)
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for a normal pagination
|
2022-09-27 19:10:11 +00:00
|
|
|
var (data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data == msgList[1..2]
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[1].toPagingIndex()
|
2020-11-09 04:48:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == pagingInfo.pageSize
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for an empty msgList
|
|
|
|
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.BACKWARD)
|
2022-08-01 10:37:45 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(getTestStoreQueue(0), pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 0
|
|
|
|
newPagingInfo.pageSize == 0
|
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.cursor == pagingInfo.cursor
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for an initial pagination request with an empty cursor
|
|
|
|
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.BACKWARD)
|
2022-09-27 19:10:11 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 2
|
|
|
|
data == msgList[8..9]
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[8].toPagingIndex()
|
2020-11-09 04:48:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 2
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2021-04-12 17:29:09 +00:00
|
|
|
|
|
|
|
# test for an initial pagination request with an empty cursor to fetch the entire history
|
|
|
|
pagingInfo = PagingInfo(pageSize: 13, direction: PagingDirection.BACKWARD)
|
2022-09-27 19:10:11 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2021-04-12 17:29:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 10
|
|
|
|
data == msgList[0..9]
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[0].toPagingIndex()
|
2021-04-12 17:29:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 10
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for a page size larger than the remaining messages
|
2022-09-27 19:10:11 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: 5, cursor: indexList[3].toPagingIndex(), direction: PagingDirection.BACKWARD)
|
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data == msgList[0..2]
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[0].toPagingIndex()
|
2020-11-09 04:48:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 3
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for a page size larger than the Maximum allowed page size
|
2022-09-27 19:10:11 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: MaxPageSize+1, cursor: indexList[3].toPagingIndex(), direction: PagingDirection.BACKWARD)
|
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
2021-04-09 10:04:21 +00:00
|
|
|
uint64(data.len) <= MaxPageSize
|
2020-11-09 04:48:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize <= MaxPageSize
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for a cursor pointing to the begining of the message list
|
2022-09-27 19:10:11 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: 5, cursor: indexList[0].toPagingIndex(), direction: PagingDirection.BACKWARD)
|
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2021-04-09 10:04:21 +00:00
|
|
|
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 0
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[0].toPagingIndex()
|
2020-11-09 04:48:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 0
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2020-11-09 04:48:09 +00:00
|
|
|
|
|
|
|
# test for an invalid cursor
|
2022-09-27 19:10:11 +00:00
|
|
|
let index = PagingIndex.compute(WakuMessage(payload: @[byte 10]), getTestTimestamp(), DefaultPubsubTopic)
|
2022-08-01 10:37:45 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: 5, cursor: index, direction: PagingDirection.BACKWARD)
|
2022-09-27 19:10:11 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(store, pagingInfo)
|
2020-11-09 04:48:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 0
|
|
|
|
newPagingInfo.cursor == pagingInfo.cursor
|
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 0
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.INVALID_CURSOR
|
2021-04-12 17:29:09 +00:00
|
|
|
|
|
|
|
# test initial paging query over a message list with one message
|
2022-08-01 10:37:45 +00:00
|
|
|
var singleItemMsgList = getTestStoreQueue(1)
|
2021-04-12 17:29:09 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: 10, direction: PagingDirection.BACKWARD)
|
2022-02-17 10:00:45 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(singleItemMsgList, pagingInfo)
|
2021-04-12 17:29:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 1
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[0].toPagingIndex()
|
2021-04-12 17:29:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 1
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|
2021-04-12 17:29:09 +00:00
|
|
|
|
|
|
|
# test paging query over a message list with one message
|
2022-08-01 10:37:45 +00:00
|
|
|
singleItemMsgList = getTestStoreQueue(1)
|
2022-09-27 19:10:11 +00:00
|
|
|
pagingInfo = PagingInfo(pageSize: 10, cursor: indexList[0].toPagingIndex(), direction: PagingDirection.BACKWARD)
|
2022-02-17 10:00:45 +00:00
|
|
|
(data, newPagingInfo, error) = getPage(singleItemMsgList, pagingInfo)
|
2021-04-12 17:29:09 +00:00
|
|
|
check:
|
|
|
|
data.len == 0
|
2022-09-27 19:10:11 +00:00
|
|
|
newPagingInfo.cursor == indexList[0].toPagingIndex()
|
2021-04-12 17:29:09 +00:00
|
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
|
|
newPagingInfo.pageSize == 0
|
2021-07-13 19:01:21 +00:00
|
|
|
error == HistoryResponseError.NONE
|