Skip to content

Commit f4d0583

Browse files
Add always_replay flag to test harness
1 parent b9baa13 commit f4d0583

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

python/restate/harness.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class RestateContainer(DockerContainer):
129129

130130
log_thread: typing.Optional[threading.Thread] = None
131131

132-
def __init__(self, image):
132+
def __init__(self, image, always_replay):
133133
super().__init__(image)
134134
self.with_exposed_ports(8080, 9070)
135135
self.with_env('RESTATE_LOG_FILTER', 'restate=info')
@@ -138,7 +138,10 @@ def __init__(self, image):
138138
self.with_env('RESTATE_SHUTDOWN_TIMEOUT', '10s')
139139
self.with_env('RESTATE_ROCKSDB_TOTAL_MEMORY_SIZE', '32 MB')
140140
self.with_env('RESTATE_WORKER__INVOKER__IN_MEMORY_QUEUE_LENGTH_LIMIT', '64')
141-
self.with_env('RESTATE_WORKER__INVOKER__INACTIVITY_TIMEOUT', '10m')
141+
if always_replay:
142+
self.with_env('RESTATE_WORKER__INVOKER__INACTIVITY_TIMEOUT', '0s')
143+
else:
144+
self.with_env('RESTATE_WORKER__INVOKER__INACTIVITY_TIMEOUT', '10m')
142145
self.with_env('RESTATE_WORKER__INVOKER__ABORT_TIMEOUT', '10m')
143146

144147
self.with_kwargs(extra_hosts={"host.docker.internal" : "host-gateway"})
@@ -188,6 +191,7 @@ class TestConfiguration:
188191
"""A configuration for running tests"""
189192
restate_image: str = "restatedev/restate:latest"
190193
stream_logs: bool = False
194+
always_replay: bool = False
191195

192196

193197
class RestateTestHarness:
@@ -207,7 +211,9 @@ def start(self):
207211
"""start the restate server and the sdk"""
208212
self.bind_address = TcpSocketBindAddress()
209213
self.server = AsgiServer(self.asgi_app, self.bind_address).start()
210-
self.restate = RestateContainer(image=self.config.restate_image) \
214+
self.restate = RestateContainer(
215+
image=self.config.restate_image,
216+
always_replay=self.config.always_replay) \
211217
.start(self.config.stream_logs)
212218
try:
213219
self._register_sdk()
@@ -256,10 +262,24 @@ def __exit__(self, exc_type, exc_value, traceback):
256262

257263
def test_harness(app,
258264
follow_logs: bool = False,
259-
restate_image: str = "restatedev/restate:latest") -> RestateTestHarness:
260-
"""create a test harness for running Restate SDKs"""
265+
restate_image: str = "restatedev/restate:latest",
266+
always_replay: bool = False) -> RestateTestHarness:
267+
"""
268+
Creates a test harness for running Restate services together with restate-server.
269+
270+
:param app: The application to be tested using the RestateTestHarness.
271+
:param follow_logs: Whether to stream logs for the test process (default is False).
272+
:param restate_image: The image name for the restate-server container
273+
(default is "restatedev/restate:latest").
274+
:param always_replay: When True, this forces restate-server to always replay
275+
on a suspension point. This is useful to hunt non deterministic bugs
276+
that might prevent your code to replay correctly (default is False).
277+
:return: An instance of RestateTestHarness initialized with the provided app and configuration.
278+
:rtype: RestateTestHarness
279+
"""
261280
config = TestConfiguration(
262281
restate_image=restate_image,
263282
stream_logs=follow_logs,
283+
always_replay=always_replay
264284
)
265285
return RestateTestHarness(app, config)

0 commit comments

Comments
 (0)