|
13 | 13 | # limitations under the License. |
14 | 14 |
|
15 | 15 | import sys |
| 16 | +import time |
16 | 17 |
|
17 | 18 | sys.path[0:0] = [""] |
18 | 19 |
|
19 | 20 | from bson.son import SON |
20 | | -from pymongo import CursorType, MongoClient, monitoring |
| 21 | +from pymongo import CursorType, monitoring |
21 | 22 | from pymongo.command_cursor import CommandCursor |
22 | 23 | from pymongo.errors import NotMasterError, OperationFailure |
23 | | -from test import unittest, IntegrationTest, client_context |
| 24 | +from test import unittest, IntegrationTest, client_context, client_knobs |
24 | 25 | from test.utils import single_client |
25 | 26 |
|
26 | 27 |
|
@@ -421,6 +422,39 @@ def test_exhaust(self): |
421 | 422 | 'ok': 1} |
422 | 423 | self.assertEqual(expected_result, succeeded.reply) |
423 | 424 |
|
| 425 | + def test_kill_cursors(self): |
| 426 | + with client_knobs(kill_cursor_frequency=0.01): |
| 427 | + self.client.pymongo_test.test.drop() |
| 428 | + self.client.pymongo_test.test.insert_many([{} for _ in range(10)]) |
| 429 | + cursor = self.client.pymongo_test.test.find().batch_size(5) |
| 430 | + next(cursor) |
| 431 | + cursor_id = cursor.cursor_id |
| 432 | + self.listener.results = {} |
| 433 | + cursor.close() |
| 434 | + time.sleep(2) |
| 435 | + results = self.listener.results |
| 436 | + started = results.get('started') |
| 437 | + succeeded = results.get('succeeded') |
| 438 | + self.assertIsNone(results.get('failed')) |
| 439 | + self.assertTrue( |
| 440 | + isinstance(started, monitoring.CommandStartedEvent)) |
| 441 | + # There could be more than one cursor_id here depending on |
| 442 | + # when the thread last ran. |
| 443 | + self.assertIn(cursor_id, started.command['cursors']) |
| 444 | + self.assertEqual('killCursors', started.command_name) |
| 445 | + self.assertEqual(cursor.address, started.connection_id) |
| 446 | + self.assertEqual('pymongo_test', started.database_name) |
| 447 | + self.assertTrue(isinstance(started.request_id, int)) |
| 448 | + self.assertTrue( |
| 449 | + isinstance(succeeded, monitoring.CommandSucceededEvent)) |
| 450 | + self.assertTrue(isinstance(succeeded.duration_micros, int)) |
| 451 | + self.assertEqual('killCursors', succeeded.command_name) |
| 452 | + self.assertTrue(isinstance(succeeded.request_id, int)) |
| 453 | + self.assertEqual(cursor.address, succeeded.connection_id) |
| 454 | + # There could be more than one cursor_id here depending on |
| 455 | + # when the thread last ran. |
| 456 | + self.assertIn(cursor_id, succeeded.reply['cursorsUnknown']) |
| 457 | + |
424 | 458 |
|
425 | 459 | if __name__ == "__main__": |
426 | 460 | unittest.main() |
0 commit comments