Skip to content

Commit 46d9cf9

Browse files
committed
PYTHON-1041 - Update monitoring spec tests to latest
Also fix a number of bugs in the test runner.
1 parent 4bad518 commit 46d9cf9

File tree

2 files changed

+137
-23
lines changed

2 files changed

+137
-23
lines changed

test/command_monitoring/find.json

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@
270270
},
271271
{
272272
"description": "A successful find event with a getmore and killcursors",
273+
"ignore_if_server_version_greater_than": "3.0",
273274
"operation": {
274275
"name": "find",
275276
"arguments": {
@@ -395,6 +396,108 @@
395396
}
396397
]
397398
},
399+
{
400+
"description": "A successful find event with a getmore and the server kills the cursor",
401+
"ignore_if_server_version_less_than": "3.1",
402+
"ignore_if_topology_type" : ["sharded"],
403+
"operation": {
404+
"name": "find",
405+
"arguments": {
406+
"filter": {
407+
"_id": {
408+
"$gte": 1
409+
}
410+
},
411+
"sort": {
412+
"_id": 1
413+
},
414+
"batchSize": 3,
415+
"limit": 4
416+
}
417+
},
418+
"expectations": [
419+
{
420+
"command_started_event": {
421+
"command": {
422+
"find": "test",
423+
"filter": {
424+
"_id": {
425+
"$gte": 1
426+
}
427+
},
428+
"sort": {
429+
"_id": 1
430+
},
431+
"batchSize": 3,
432+
"limit": 4
433+
},
434+
"command_name": "find",
435+
"database_name": "command-monitoring-tests"
436+
}
437+
},
438+
{
439+
"command_succeeded_event": {
440+
"reply": {
441+
"ok": 1,
442+
"cursor": {
443+
"id": {
444+
"$numberLong": "42"
445+
},
446+
"ns": "command-monitoring-tests.test",
447+
"firstBatch": [
448+
{
449+
"_id": 1,
450+
"x": 11
451+
},
452+
{
453+
"_id": 2,
454+
"x": 22
455+
},
456+
{
457+
"_id": 3,
458+
"x": 33
459+
}
460+
]
461+
}
462+
},
463+
"command_name": "find"
464+
}
465+
},
466+
{
467+
"command_started_event": {
468+
"command": {
469+
"getMore": {
470+
"$numberLong": "42"
471+
},
472+
"collection": "test",
473+
"batchSize": 1
474+
},
475+
"command_name": "getMore",
476+
"database_name": "command-monitoring-tests"
477+
}
478+
},
479+
{
480+
"command_succeeded_event": {
481+
"reply": {
482+
"ok": 1,
483+
"cursor": {
484+
"id": {
485+
"$numberLong": "0"
486+
},
487+
"ns": "command-monitoring-tests.test",
488+
"nextBatch": [
489+
{
490+
"_id": 4,
491+
"x": 44
492+
}
493+
]
494+
}
495+
},
496+
"command_name": "getMore"
497+
}
498+
}
499+
]
500+
},
398501
{
399502
"description": "A failed find event",
400503
"operation": {

test/test_command_monitoring_spec.py

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
from bson.json_util import object_hook
2727
from pymongo import monitoring
2828
from pymongo.errors import OperationFailure
29-
from pymongo.read_preferences import make_read_preference
29+
from pymongo.read_preferences import (make_read_preference,
30+
read_pref_mode_from_name)
3031
from pymongo.write_concern import WriteConcern
3132
from test import unittest, client_context
3233
from test.utils import single_client, wait_until, EventListener
@@ -49,7 +50,6 @@ class TestAllScenarios(unittest.TestCase):
4950
@client_context.require_connection
5051
def setUpClass(cls):
5152
cls.listener = EventListener()
52-
cls.listener.add_command_filter('killCursors')
5353
cls.saved_listeners = monitoring._LISTENERS
5454
monitoring._LISTENERS = monitoring._Listeners([])
5555
cls.client = single_client(event_listeners=[cls.listener])
@@ -68,27 +68,42 @@ def run_scenario(self):
6868
dbname = scenario_def['database_name']
6969
collname = scenario_def['collection_name']
7070

71-
# Clear the kill cursors queue.
72-
self.client._kill_cursors_executor.wake()
73-
7471
for test in scenario_def['tests']:
72+
ver = client_context.version[:2]
73+
if "ignore_if_server_version_greater_than" in test:
74+
version = test["ignore_if_server_version_greater_than"]
75+
if ver > tuple(map(int, version.split("."))):
76+
continue
77+
if "ignore_if_server_version_less_than" in test:
78+
version = test["ignore_if_server_version_less_than"]
79+
if ver < tuple(map(int, version.split("."))):
80+
continue
81+
if "ignore_if_topology_type" in test:
82+
types = set(test["ignore_if_topology_type"])
83+
if "sharded" in types and client_context.is_mongos:
84+
continue
85+
7586
coll = self.client[dbname][collname]
7687
coll.drop()
7788
coll.insert_many(scenario_def['data'])
7889
self.listener.results.clear()
7990
name = camel_to_snake(test['operation']['name'])
80-
args = test['operation']['arguments']
8191
# Don't send $readPreference to mongos before 2.4.
8292
if (client_context.version.at_least(2, 4, 0)
83-
and 'readPreference' in args):
84-
pref = make_read_preference(
85-
args['readPreference']['mode'], None)
86-
coll = coll.with_options(read_preference=pref)
87-
if 'writeConcern' in args:
93+
and 'read_preference' in test['operation']):
94+
mode = read_pref_mode_from_name(
95+
test['operation']['read_preference']['mode'])
96+
coll = coll.with_options(
97+
read_preference=make_read_preference(mode, None))
98+
99+
test_args = test['operation']['arguments']
100+
if 'writeConcern' in test_args:
101+
concern = test_args.pop('writeConcern')
88102
coll = coll.with_options(
89-
write_concern=WriteConcern(**args['writeConcern']))
90-
for arg in args:
91-
args[camel_to_snake(arg)] = args.pop(arg)
103+
write_concern=WriteConcern(**concern))
104+
args = {}
105+
for arg in test_args:
106+
args[camel_to_snake(arg)] = test_args[arg]
92107

93108
if name == 'bulk_write':
94109
bulk_args = []
@@ -102,25 +117,20 @@ def run_scenario(self):
102117
except OperationFailure:
103118
pass
104119
elif name == 'find':
105-
if 'limit' in args:
106-
# XXX: Skip killCursors test when using the find command.
107-
if client_context.version.at_least(3, 1, 1):
108-
continue
109-
self.listener.remove_command_filter('killCursors')
110120
if 'sort' in args:
111121
args['sort'] = list(args['sort'].items())
112122
try:
113123
# Iterate the cursor.
114124
tuple(coll.find(**args))
115125
except OperationFailure:
116126
pass
117-
# Wait for the killCursors thread to run.
118-
if 'limit' in args:
127+
# Wait for the killCursors thread to run if necessary.
128+
if 'limit' in args and client_context.version[:2] < (3, 1):
129+
self.client._kill_cursors_executor.wake()
119130
started = self.listener.results['started']
120131
wait_until(
121132
lambda: started[-1].command_name == 'killCursors',
122133
"publish a start event for killCursors.")
123-
self.listener.add_command_filter('killCursors')
124134
else:
125135
try:
126136
getattr(coll, name)(**args)
@@ -132,7 +142,8 @@ def run_scenario(self):
132142
if event_type == "command_started_event":
133143
event = self.listener.results['started'].pop(0)
134144
# The tests substitute 42 for any number other than 0.
135-
if event.command_name == 'getMore':
145+
if (event.command_name == 'getMore'
146+
and event.command['getMore']):
136147
event.command['getMore'] = 42
137148
elif event.command_name == 'killCursors':
138149
event.command['cursors'] = [42]

0 commit comments

Comments
 (0)