Skip to content

Commit 6011df9

Browse files
PYTHON-5643 Add contributor docs for the test.utils_shared.delay function (mongodb#2628)
1 parent 8bf8263 commit 6011df9

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

CONTRIBUTING.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,11 @@ If you are running one of the `no-responder` tests, omit the `run-server` step.
387387
To run any of the test suites with minimum supported dependencies, pass `--test-min-deps` to
388388
`just setup-tests`.
389389

390+
## Testing time-dependent operations
391+
392+
- `test.utils_shared.delay` - One can trigger an arbitrarily long-running operation on the server using this delay utility
393+
in combination with a `$where` operation. Use this to test behaviors around timeouts or signals.
394+
390395
## Adding a new test suite
391396

392397
- If adding new tests files that should only be run for that test suite, add a pytest marker to the file and add

test/utils_shared.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,50 @@ def oid_generated_on_process(oid):
377377

378378

379379
def delay(sec):
380-
return """function() { sleep(%f * 1000); return true; }""" % sec
380+
"""Along with a ``$where`` operator, this triggers an arbitrarily long-running
381+
operation on the server.
382+
383+
This can be useful in time-sensitive tests (e.g., timeouts, signals).
384+
Note that you must have at least one document in the collection or the
385+
server may decide not to sleep at all.
386+
387+
Example
388+
-------
389+
390+
.. code-block:: python
391+
392+
db.coll.insert_one({"x": 1})
393+
db.test.find_one({"x": 1})
394+
# {'x': 1, '_id': ObjectId('54f4e12bfba5220aa4d6dee8')}
395+
396+
# The following will wait 2.5 seconds before returning.
397+
db.test.find_one({"$where": delay(2.5)})
398+
# {'x': 1, '_id': ObjectId('54f4e12bfba5220aa4d6dee8')}
399+
400+
Using ``delay`` to provoke a KeyboardInterrupt
401+
----------------------------------------------
402+
403+
.. code-block:: python
404+
405+
import signal
406+
407+
# Raise KeyboardInterrupt in 1 second
408+
def sigalarm(num, frame):
409+
raise KeyboardInterrupt
410+
411+
412+
signal.signal(signal.SIGALRM, sigalarm)
413+
signal.alarm(1)
414+
415+
raised = False
416+
try:
417+
clxn.find_one({"$where": delay(1.5)})
418+
except KeyboardInterrupt:
419+
raised = True
420+
421+
assert raised
422+
"""
423+
return "function() { sleep(%f * 1000); return true; }" % sec
381424

382425

383426
def camel_to_snake(camel):

0 commit comments

Comments
 (0)