Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,11 @@ If you are running one of the `no-responder` tests, omit the `run-server` step.
To run any of the test suites with minimum supported dependencies, pass `--test-min-deps` to
`just setup-tests`.

## Testing time-dependent operations

- `test.utils_shared.delay` - One can trigger an arbitrarily long-running operation on the server using this delay utility
in combination with a `$where` operation. Use this to test behaviors around timeouts or signals.

## Adding a new test suite

- If adding new tests files that should only be run for that test suite, add a pytest marker to the file and add
Expand Down
45 changes: 44 additions & 1 deletion test/utils_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,50 @@ def oid_generated_on_process(oid):


def delay(sec):
return """function() { sleep(%f * 1000); return true; }""" % sec
"""Along with a ``$where`` operator, this triggers an arbitrarily long-running
operation on the server.

This can be useful in time-sensitive tests (e.g., timeouts, signals).
Note that you must have at least one document in the collection or the
server may decide not to sleep at all.

Example
-------

.. code-block:: python

db.coll.insert_one({"x": 1})
db.test.find_one({"x": 1})
# {'x': 1, '_id': ObjectId('54f4e12bfba5220aa4d6dee8')}

# The following will wait 2.5 seconds before returning.
db.test.find_one({"$where": delay(2.5)})
# {'x': 1, '_id': ObjectId('54f4e12bfba5220aa4d6dee8')}

Using ``delay`` to provoke a KeyboardInterrupt
----------------------------------------------

.. code-block:: python

import signal

# Raise KeyboardInterrupt in 1 second
def sigalarm(num, frame):
raise KeyboardInterrupt


signal.signal(signal.SIGALRM, sigalarm)
signal.alarm(1)

raised = False
try:
clxn.find_one({"$where": delay(1.5)})
except KeyboardInterrupt:
raised = True

assert raised
"""
return "function() { sleep(%f * 1000); return true; }" % sec


def camel_to_snake(camel):
Expand Down
Loading