2022-11-22 18:40:24 +00:00
|
|
|
{.used.}
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
import std/[sequtils, times], stew/results, testutils/unittests, chronos
|
2022-11-22 18:40:24 +00:00
|
|
|
import
|
2024-07-05 22:03:38 +00:00
|
|
|
waku/[
|
|
|
|
common/databases/db_sqlite,
|
|
|
|
waku_core,
|
|
|
|
waku_core/message/digest,
|
|
|
|
waku_archive,
|
|
|
|
waku_archive/driver/sqlite_driver,
|
|
|
|
waku_archive/retention_policy,
|
|
|
|
waku_archive/retention_policy/retention_policy_capacity,
|
|
|
|
waku_archive/retention_policy/retention_policy_size,
|
|
|
|
],
|
2023-11-27 17:33:27 +00:00
|
|
|
../waku_archive/archive_utils,
|
2023-04-05 14:01:51 +00:00
|
|
|
../testlib/wakucore
|
2022-11-22 18:40:24 +00:00
|
|
|
|
|
|
|
suite "Waku Archive - Retention policy":
|
|
|
|
test "capacity retention policy - windowed message deletion":
|
|
|
|
## Given
|
|
|
|
let
|
|
|
|
capacity = 100
|
2023-10-10 09:59:09 +00:00
|
|
|
excess = 60
|
2022-11-22 18:40:24 +00:00
|
|
|
|
2023-11-27 17:33:27 +00:00
|
|
|
let driver = newSqliteArchiveDriver()
|
2022-11-22 18:40:24 +00:00
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
let retentionPolicy: RetentionPolicy =
|
|
|
|
CapacityRetentionPolicy.new(capacity = capacity)
|
2023-10-10 09:59:09 +00:00
|
|
|
var putFutures = newSeq[Future[ArchiveDriverResult[void]]]()
|
2022-11-22 18:40:24 +00:00
|
|
|
|
|
|
|
## When
|
2024-03-15 23:08:47 +00:00
|
|
|
for i in 1 .. capacity + excess:
|
|
|
|
let msg = fakeWakuMessage(
|
|
|
|
payload = @[byte i], contentTopic = DefaultContentTopic, ts = Timestamp(i)
|
|
|
|
)
|
|
|
|
putFutures.add(
|
2024-07-12 16:19:12 +00:00
|
|
|
driver.put(computeMessageHash(DefaultPubsubTopic, msg), DefaultPubsubTopic, msg)
|
2024-03-15 23:08:47 +00:00
|
|
|
)
|
|
|
|
|
2023-10-10 09:59:09 +00:00
|
|
|
discard waitFor allFinished(putFutures)
|
2022-11-22 18:40:24 +00:00
|
|
|
|
2024-07-12 16:19:12 +00:00
|
|
|
let res = waitFor retentionPolicy.execute(driver)
|
|
|
|
assert res.isOk(), $res.error
|
2022-11-22 18:40:24 +00:00
|
|
|
|
|
|
|
## Then
|
2023-05-25 15:34:34 +00:00
|
|
|
let numMessages = (waitFor driver.getMessagesCount()).tryGet()
|
2022-11-22 18:40:24 +00:00
|
|
|
check:
|
|
|
|
# Expected number of messages is 120 because
|
|
|
|
# (capacity = 100) + (half of the overflow window = 15) + (5 messages added after after the last delete)
|
|
|
|
# the window size changes when changing `const maxStoreOverflow = 1.3 in sqlite_store
|
2023-10-10 09:59:09 +00:00
|
|
|
numMessages == 115
|
|
|
|
|
|
|
|
## Cleanup
|
|
|
|
(waitFor driver.close()).expect("driver to close")
|
2024-03-15 23:08:47 +00:00
|
|
|
|
2023-10-10 09:59:09 +00:00
|
|
|
test "size retention policy - windowed message deletion":
|
|
|
|
## Given
|
|
|
|
let
|
2023-11-24 14:43:47 +00:00
|
|
|
# in bytes
|
2024-03-15 23:08:47 +00:00
|
|
|
sizeLimit: int64 = 52428
|
2023-10-10 09:59:09 +00:00
|
|
|
excess = 325
|
|
|
|
|
2023-11-27 17:33:27 +00:00
|
|
|
let driver = newSqliteArchiveDriver()
|
2023-10-10 09:59:09 +00:00
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
let retentionPolicy: RetentionPolicy = SizeRetentionPolicy.new(size = sizeLimit)
|
2023-10-10 09:59:09 +00:00
|
|
|
var putFutures = newSeq[Future[ArchiveDriverResult[void]]]()
|
|
|
|
|
|
|
|
# make sure that the db is empty to before test begins
|
|
|
|
let storedMsg = (waitFor driver.getAllMessages()).tryGet()
|
|
|
|
# if there are messages in db, empty them
|
|
|
|
if storedMsg.len > 0:
|
|
|
|
let now = getNanosecondTime(getTime().toUnixFloat())
|
2024-03-15 23:08:47 +00:00
|
|
|
require (waitFor driver.deleteMessagesOlderThanTimestamp(ts = now)).isOk()
|
2023-10-10 09:59:09 +00:00
|
|
|
require (waitFor driver.performVacuum()).isOk()
|
|
|
|
|
|
|
|
## When
|
2023-11-22 16:32:56 +00:00
|
|
|
##
|
2023-10-10 09:59:09 +00:00
|
|
|
|
|
|
|
# create a number of messages so that the size of the DB overshoots
|
2024-03-15 23:08:47 +00:00
|
|
|
for i in 1 .. excess:
|
|
|
|
let msg = fakeWakuMessage(
|
|
|
|
payload = @[byte i], contentTopic = DefaultContentTopic, ts = Timestamp(i)
|
|
|
|
)
|
|
|
|
putFutures.add(
|
2024-07-12 16:19:12 +00:00
|
|
|
driver.put(computeMessageHash(DefaultPubsubTopic, msg), DefaultPubsubTopic, msg)
|
2024-03-15 23:08:47 +00:00
|
|
|
)
|
2023-10-10 09:59:09 +00:00
|
|
|
|
|
|
|
# waitFor is used to synchronously wait for the futures to complete.
|
|
|
|
discard waitFor allFinished(putFutures)
|
|
|
|
|
|
|
|
## Then
|
|
|
|
# calculate the current database size
|
2023-11-24 14:43:47 +00:00
|
|
|
let sizeDB = int64((waitFor driver.getDatabaseSize()).tryGet())
|
2023-11-21 10:27:50 +00:00
|
|
|
|
|
|
|
# NOTE: since vacuumin is done manually, this needs to be revisited if vacuuming done automatically
|
|
|
|
|
|
|
|
# get the rows count pre-deletion
|
|
|
|
let rowsCountBeforeDeletion = (waitFor driver.getMessagesCount()).tryGet()
|
2023-10-10 09:59:09 +00:00
|
|
|
|
2023-11-21 10:27:50 +00:00
|
|
|
# execute policy provided the current db size oveflows, results in rows deletion
|
2023-10-10 09:59:09 +00:00
|
|
|
require (sizeDB >= sizeLimit)
|
|
|
|
require (waitFor retentionPolicy.execute(driver)).isOk()
|
2024-03-15 23:08:47 +00:00
|
|
|
|
2023-11-24 14:43:47 +00:00
|
|
|
# get the number or rows from database
|
2023-11-21 10:27:50 +00:00
|
|
|
let rowCountAfterDeletion = (waitFor driver.getMessagesCount()).tryGet()
|
2023-10-10 09:59:09 +00:00
|
|
|
|
|
|
|
check:
|
|
|
|
# size of the database is used to check if the storage limit has been preserved
|
|
|
|
# check the current database size with the limitSize provided by the user
|
|
|
|
# it should be lower
|
2023-11-21 10:27:50 +00:00
|
|
|
rowCountAfterDeletion <= rowsCountBeforeDeletion
|
2022-11-22 18:40:24 +00:00
|
|
|
|
|
|
|
## Cleanup
|
2023-05-25 15:34:34 +00:00
|
|
|
(waitFor driver.close()).expect("driver to close")
|
2022-11-22 18:40:24 +00:00
|
|
|
|
|
|
|
test "store capacity should be limited":
|
|
|
|
## Given
|
|
|
|
const capacity = 5
|
|
|
|
const contentTopic = "test-content-topic"
|
|
|
|
|
|
|
|
let
|
2023-11-27 17:33:27 +00:00
|
|
|
driver = newSqliteArchiveDriver()
|
2024-03-15 23:08:47 +00:00
|
|
|
retentionPolicy: RetentionPolicy =
|
|
|
|
CapacityRetentionPolicy.new(capacity = capacity)
|
|
|
|
|
|
|
|
let messages =
|
|
|
|
@[
|
|
|
|
fakeWakuMessage(contentTopic = DefaultContentTopic, ts = ts(0)),
|
|
|
|
fakeWakuMessage(contentTopic = DefaultContentTopic, ts = ts(1)),
|
|
|
|
fakeWakuMessage(contentTopic = contentTopic, ts = ts(2)),
|
|
|
|
fakeWakuMessage(contentTopic = contentTopic, ts = ts(3)),
|
|
|
|
fakeWakuMessage(contentTopic = contentTopic, ts = ts(4)),
|
|
|
|
fakeWakuMessage(contentTopic = contentTopic, ts = ts(5)),
|
|
|
|
fakeWakuMessage(contentTopic = contentTopic, ts = ts(6)),
|
|
|
|
]
|
2022-11-22 18:40:24 +00:00
|
|
|
|
|
|
|
## When
|
|
|
|
for msg in messages:
|
2024-03-15 23:08:47 +00:00
|
|
|
require (
|
|
|
|
waitFor driver.put(
|
2024-07-12 16:19:12 +00:00
|
|
|
computeMessageHash(DefaultPubsubTopic, msg), DefaultPubsubTopic, msg
|
2024-03-15 23:08:47 +00:00
|
|
|
)
|
|
|
|
).isOk()
|
2023-05-25 15:34:34 +00:00
|
|
|
require (waitFor retentionPolicy.execute(driver)).isOk()
|
2022-11-22 18:40:24 +00:00
|
|
|
|
|
|
|
## Then
|
2023-05-25 15:34:34 +00:00
|
|
|
let storedMsg = (waitFor driver.getAllMessages()).tryGet()
|
2022-11-22 18:40:24 +00:00
|
|
|
check:
|
|
|
|
storedMsg.len == capacity
|
2024-03-15 23:08:47 +00:00
|
|
|
storedMsg.all do(item: auto) -> bool:
|
2024-07-12 16:19:12 +00:00
|
|
|
let (_, pubsubTopic, msg) = item
|
2024-03-15 23:08:47 +00:00
|
|
|
msg.contentTopic == contentTopic and pubsubTopic == DefaultPubsubTopic
|
2022-11-22 18:40:24 +00:00
|
|
|
|
|
|
|
## Cleanup
|
2023-05-25 15:34:34 +00:00
|
|
|
(waitFor driver.close()).expect("driver to close")
|