|
36 | 36 | async_client_context,
|
37 | 37 | unittest,
|
38 | 38 | )
|
| 39 | +from test.asynchronous.helpers import client_knobs |
39 | 40 | from test.utils import (
|
40 | 41 | EventListener,
|
| 42 | + HeartbeatEventListener, |
41 | 43 | OvertCommandListener,
|
42 | 44 | async_wait_until,
|
43 | 45 | )
|
@@ -1135,12 +1137,10 @@ async def asyncSetUp(self):
|
1135 | 1137 | if "$clusterTime" not in (await async_client_context.hello):
|
1136 | 1138 | raise SkipTest("$clusterTime not supported")
|
1137 | 1139 |
|
| 1140 | + # Sessions prose test: 3) $clusterTime in commands |
1138 | 1141 | async def test_cluster_time(self):
|
1139 | 1142 | listener = SessionTestListener()
|
1140 |
| - # Prevent heartbeats from updating $clusterTime between operations. |
1141 |
| - client = await self.async_rs_or_single_client( |
1142 |
| - event_listeners=[listener], heartbeatFrequencyMS=999999 |
1143 |
| - ) |
| 1143 | + client = await self.async_rs_or_single_client(event_listeners=[listener]) |
1144 | 1144 | collection = client.pymongo_test.collection
|
1145 | 1145 | # Prepare for tests of find() and aggregate().
|
1146 | 1146 | await collection.insert_many([{} for _ in range(10)])
|
@@ -1219,6 +1219,40 @@ async def aggregate():
|
1219 | 1219 | f"{f.__name__} sent wrong $clusterTime with {event.command_name}",
|
1220 | 1220 | )
|
1221 | 1221 |
|
| 1222 | + # Sessions prose test: 20) Drivers do not gossip `$clusterTime` on SDAM commands |
| 1223 | + async def test_cluster_time_not_used_by_sdam(self): |
| 1224 | + heartbeat_listener = HeartbeatEventListener() |
| 1225 | + cmd_listener = OvertCommandListener() |
| 1226 | + with client_knobs(min_heartbeat_interval=0.01): |
| 1227 | + c1 = await self.async_single_client( |
| 1228 | + event_listeners=[heartbeat_listener, cmd_listener], heartbeatFrequencyMS=10 |
| 1229 | + ) |
| 1230 | + cluster_time = (await c1.admin.command({"ping": 1}))["$clusterTime"] |
| 1231 | + self.assertEqual(c1._topology.max_cluster_time(), cluster_time) |
| 1232 | + |
| 1233 | + # Advance the server's $clusterTime by performing an insert via another client. |
| 1234 | + await self.db.test.insert_one({"advance": "$clusterTime"}) |
| 1235 | + # Wait until the client C1 processes the next pair of SDAM heartbeat started + succeeded events. |
| 1236 | + heartbeat_listener.reset() |
| 1237 | + |
| 1238 | + async def next_heartbeat(): |
| 1239 | + events = heartbeat_listener.events |
| 1240 | + for i in range(len(events) - 1): |
| 1241 | + if isinstance(events[i], monitoring.ServerHeartbeatStartedEvent): |
| 1242 | + if isinstance(events[i + 1], monitoring.ServerHeartbeatSucceededEvent): |
| 1243 | + return True |
| 1244 | + return False |
| 1245 | + |
| 1246 | + await async_wait_until( |
| 1247 | + next_heartbeat, "never found pair of heartbeat started + succeeded events" |
| 1248 | + ) |
| 1249 | + # Assert that C1's max $clusterTime is still the same and has not been updated by SDAM. |
| 1250 | + cmd_listener.reset() |
| 1251 | + await c1.admin.command({"ping": 1}) |
| 1252 | + started = cmd_listener.started_events[0] |
| 1253 | + self.assertEqual(started.command_name, "ping") |
| 1254 | + self.assertEqual(started.command["$clusterTime"], cluster_time) |
| 1255 | + |
1222 | 1256 |
|
1223 | 1257 | if __name__ == "__main__":
|
1224 | 1258 | unittest.main()
|
0 commit comments