1
1
from contextlib import contextmanager
2
2
from typing import Any
3
+ from unittest import mock
3
4
4
5
import pytest
5
6
7
+ from quixstreams .state .rocksdb .partition import Marker
6
8
from quixstreams .state .rocksdb .timestamped import (
7
9
TimestampedPartitionTransaction ,
8
10
TimestampedStore ,
@@ -54,13 +56,8 @@ def test_get_last_ignore_deleted(
54
56
tx .set (timestamp = 9 , value = "value9-stored" , prefix = b"key" )
55
57
56
58
with transaction () as tx :
57
- tx .expire (timestamp = 10 , prefix = b"key" )
58
-
59
- # Message with timestamp 8 comes out of order after later messages
60
- # got expired in the same transaction.
61
- # TODO: Should we in this case "unexpire" the timestamp 9 message?
59
+ tx ._expire (timestamp = 10 , prefix = b"key" )
62
60
tx .set (timestamp = 8 , value = "value8-cached" , prefix = b"key" )
63
-
64
61
assert tx .get_last (timestamp = 10 , prefix = b"key" ) == "value8-cached"
65
62
66
63
@@ -136,13 +133,53 @@ def test_get_last_from_store_with_retention(
136
133
assert tx .get_last (timestamp = 10 , prefix = b"key" , retention = 4 ) == None
137
134
138
135
136
+ @mock .patch ("quixstreams.state.rocksdb.timestamped.EXPIRATION_COUNTER" , 1000 )
137
+ def test_get_last_from_cache_with_expire_call (
138
+ transaction : TimestampedPartitionTransaction ,
139
+ ):
140
+ with transaction () as tx :
141
+ tx .set (timestamp = 5 , value = "value1" , prefix = b"key" )
142
+ assert tx ._update_cache .get_updates_for_prefix (prefix = b"key" ) == {
143
+ b"key|\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x05 " : b'"value1"' ,
144
+ }
145
+
146
+ # Expiration counter is exhausted for this `get_last` call
147
+ # `_expire` method is called with `lower_bound_timestamp` = 10 - 4 = 6
148
+ # Everything below timestamp 6 gets expired.
149
+ assert tx .get_last (timestamp = 10 , prefix = b"key" , retention = 4 ) == None
150
+ assert tx ._update_cache .get_updates_for_prefix (prefix = b"key" ) == {}
151
+
152
+
153
+ @mock .patch ("quixstreams.state.rocksdb.timestamped.EXPIRATION_COUNTER" , 1000 )
154
+ def test_get_last_from_store_with_expire_call (
155
+ transaction : TimestampedPartitionTransaction ,
156
+ ):
157
+ key = b"key|\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x05 "
158
+
159
+ with transaction () as tx :
160
+ tx .set (timestamp = 5 , value = "value1" , prefix = b"key" )
161
+
162
+ with transaction () as tx :
163
+ assert tx ._partition .get (key ) == b'"value1"'
164
+ assert not tx ._update_cache .get_deletes ()
165
+
166
+ # Expiration counter is exhausted for this `get_last` call
167
+ # `_expire` method is called with `lower_bound_timestamp` = 10 - 4 = 6
168
+ # Everything belowe timestamp 6 gets expired.
169
+ assert tx .get_last (timestamp = 10 , prefix = b"key" , retention = 4 ) == None
170
+ assert key in tx ._update_cache .get_deletes ()
171
+
172
+ with transaction () as tx :
173
+ assert tx ._partition .get (key ) is Marker .UNDEFINED
174
+
175
+
139
176
def test_expire_cached (transaction : TimestampedPartitionTransaction ):
140
177
with transaction () as tx :
141
178
tx .set (timestamp = 1 , value = "value1" , prefix = b"key" )
142
179
tx .set (timestamp = 10 , value = "value10" , prefix = b"key" )
143
180
tx .set (timestamp = 11 , value = "value11" , prefix = b"key" )
144
181
145
- tx .expire (timestamp = 11 , prefix = b"key" )
182
+ tx ._expire (timestamp = 11 , prefix = b"key" )
146
183
147
184
assert tx .get_last (timestamp = 10 , prefix = b"key" ) == None
148
185
assert tx .get_last (timestamp = 11 , prefix = b"key" ) == "value11"
@@ -155,7 +192,7 @@ def test_expire_stored(transaction: TimestampedPartitionTransaction):
155
192
tx .set (timestamp = 11 , value = "value11" , prefix = b"key" )
156
193
157
194
with transaction () as tx :
158
- tx .expire (timestamp = 11 , prefix = b"key" )
195
+ tx ._expire (timestamp = 11 , prefix = b"key" )
159
196
160
197
assert tx .get_last (timestamp = 10 , prefix = b"key" ) == None
161
198
assert tx .get_last (timestamp = 11 , prefix = b"key" ) == "value11"
@@ -168,7 +205,7 @@ def test_expire_idempotent(transaction: TimestampedPartitionTransaction):
168
205
with transaction () as tx :
169
206
tx .set (timestamp = 10 , value = "value10" , prefix = b"key" )
170
207
171
- tx .expire (timestamp = 11 , prefix = b"key" )
172
- tx .expire (timestamp = 11 , prefix = b"key" )
208
+ tx ._expire (timestamp = 11 , prefix = b"key" )
209
+ tx ._expire (timestamp = 11 , prefix = b"key" )
173
210
174
211
assert tx .get_last (timestamp = 10 , prefix = b"key" ) == None
0 commit comments