Skip to content

Commit f44b31d

Browse files
committed
PYTHON-4579 Add prose test
1 parent d38d930 commit f44b31d

File tree

2 files changed

+74
-6
lines changed

2 files changed

+74
-6
lines changed

test/asynchronous/test_session.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@
3333
async_client_context,
3434
unittest,
3535
)
36+
from test.asynchronous.helpers import client_knobs
3637
from test.utils import (
3738
EventListener,
3839
ExceptionCatchingThread,
40+
HeartbeatEventListener,
3941
OvertCommandListener,
4042
async_wait_until,
4143
)
@@ -1133,12 +1135,10 @@ async def asyncSetUp(self):
11331135
if "$clusterTime" not in (await async_client_context.hello):
11341136
raise SkipTest("$clusterTime not supported")
11351137

1138+
# Sessions prose test: 3) $clusterTime in commands
11361139
async def test_cluster_time(self):
11371140
listener = SessionTestListener()
1138-
# Prevent heartbeats from updating $clusterTime between operations.
1139-
client = await self.async_rs_or_single_client(
1140-
event_listeners=[listener], heartbeatFrequencyMS=999999
1141-
)
1141+
client = await self.async_rs_or_single_client(event_listeners=[listener])
11421142
collection = client.pymongo_test.collection
11431143
# Prepare for tests of find() and aggregate().
11441144
await collection.insert_many([{} for _ in range(10)])
@@ -1217,6 +1217,40 @@ async def aggregate():
12171217
f"{f.__name__} sent wrong $clusterTime with {event.command_name}",
12181218
)
12191219

1220+
# Sessions prose test: 20) $clusterTime in commands
1221+
async def test_cluster_time_not_used_by_sdam(self):
1222+
heartbeat_listener = HeartbeatEventListener()
1223+
cmd_listener = OvertCommandListener()
1224+
with client_knobs(min_heartbeat_interval=0.01):
1225+
c1 = await self.async_single_client(
1226+
event_listeners=[heartbeat_listener, cmd_listener], heartbeatFrequencyMS=10
1227+
)
1228+
cluster_time = (await c1.admin.command({"ping": 1}))["$clusterTime"]
1229+
self.assertEqual(c1._topology.max_cluster_time(), cluster_time)
1230+
1231+
# Advance the server's $clusterTime by performing an insert via another client.
1232+
await self.db.test.insert_one({"advance": "$clusterTime"})
1233+
# Wait until the client C1 processes the next pair of SDAM heartbeat started + succeeded events.
1234+
heartbeat_listener.reset()
1235+
1236+
async def next_heartbeat():
1237+
events = heartbeat_listener.events
1238+
for i in range(len(events) - 1):
1239+
if isinstance(events[i], monitoring.ServerHeartbeatStartedEvent):
1240+
if isinstance(events[i + 1], monitoring.ServerHeartbeatSucceededEvent):
1241+
return True
1242+
return False
1243+
1244+
await async_wait_until(
1245+
next_heartbeat, "never found pair of heartbeat started + succeeded events"
1246+
)
1247+
# Assert that C1's max $clusterTime is still the same and has not been updated by SDAM.
1248+
cmd_listener.reset()
1249+
await c1.admin.command({"ping": 1})
1250+
started = cmd_listener.started_events[0]
1251+
self.assertEqual(started.command_name, "ping")
1252+
self.assertEqual(started.command["$clusterTime"], cluster_time)
1253+
12201254

12211255
if __name__ == "__main__":
12221256
unittest.main()

test/test_session.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@
3333
client_context,
3434
unittest,
3535
)
36+
from test.helpers import client_knobs
3637
from test.utils import (
3738
EventListener,
3839
ExceptionCatchingThread,
40+
HeartbeatEventListener,
3941
OvertCommandListener,
4042
wait_until,
4143
)
@@ -1119,10 +1121,10 @@ def setUp(self):
11191121
if "$clusterTime" not in (client_context.hello):
11201122
raise SkipTest("$clusterTime not supported")
11211123

1124+
# Sessions prose test: 3) $clusterTime in commands
11221125
def test_cluster_time(self):
11231126
listener = SessionTestListener()
1124-
# Prevent heartbeats from updating $clusterTime between operations.
1125-
client = self.rs_or_single_client(event_listeners=[listener], heartbeatFrequencyMS=999999)
1127+
client = self.rs_or_single_client(event_listeners=[listener])
11261128
collection = client.pymongo_test.collection
11271129
# Prepare for tests of find() and aggregate().
11281130
collection.insert_many([{} for _ in range(10)])
@@ -1201,6 +1203,38 @@ def aggregate():
12011203
f"{f.__name__} sent wrong $clusterTime with {event.command_name}",
12021204
)
12031205

1206+
# Sessions prose test: 20) $clusterTime in commands
1207+
def test_cluster_time_not_used_by_sdam(self):
1208+
heartbeat_listener = HeartbeatEventListener()
1209+
cmd_listener = OvertCommandListener()
1210+
with client_knobs(min_heartbeat_interval=0.01):
1211+
c1 = self.single_client(
1212+
event_listeners=[heartbeat_listener, cmd_listener], heartbeatFrequencyMS=10
1213+
)
1214+
cluster_time = (c1.admin.command({"ping": 1}))["$clusterTime"]
1215+
self.assertEqual(c1._topology.max_cluster_time(), cluster_time)
1216+
1217+
# Advance the server's $clusterTime by performing an insert via another client.
1218+
self.db.test.insert_one({"advance": "$clusterTime"})
1219+
# Wait until the client C1 processes the next pair of SDAM heartbeat started + succeeded events.
1220+
heartbeat_listener.reset()
1221+
1222+
def next_heartbeat():
1223+
events = heartbeat_listener.events
1224+
for i in range(len(events) - 1):
1225+
if isinstance(events[i], monitoring.ServerHeartbeatStartedEvent):
1226+
if isinstance(events[i + 1], monitoring.ServerHeartbeatSucceededEvent):
1227+
return True
1228+
return False
1229+
1230+
wait_until(next_heartbeat, "never found pair of heartbeat started + succeeded events")
1231+
# Assert that C1's max $clusterTime is still the same and has not been updated by SDAM.
1232+
cmd_listener.reset()
1233+
c1.admin.command({"ping": 1})
1234+
started = cmd_listener.started_events[0]
1235+
self.assertEqual(started.command_name, "ping")
1236+
self.assertEqual(started.command["$clusterTime"], cluster_time)
1237+
12041238

12051239
if __name__ == "__main__":
12061240
unittest.main()

0 commit comments

Comments
 (0)