PYTHON-1205 - Use SIGALRM instead of interrupt_main on non-Windows
This commit is contained in:
parent
544fd06f6f
commit
80fdf61cdb
@ -16,11 +16,12 @@
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import threading
|
||||
import signal
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
import thread
|
||||
import threading
|
||||
import time
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
@ -935,31 +936,53 @@ with client.start_request() as request:
|
||||
db.drop_collection('foo')
|
||||
db.foo.insert({'_id': 1})
|
||||
|
||||
def interrupter():
|
||||
# Raises KeyboardInterrupt in the main thread
|
||||
time.sleep(0.25)
|
||||
thread.interrupt_main()
|
||||
|
||||
thread.start_new_thread(interrupter, ())
|
||||
|
||||
raised = False
|
||||
old_signal_handler = None
|
||||
try:
|
||||
# Will be interrupted by a KeyboardInterrupt.
|
||||
db.foo.find({'$where': where}).next()
|
||||
except KeyboardInterrupt:
|
||||
raised = True
|
||||
# Platform-specific hacks for raising a KeyboardInterrupt on the
|
||||
# main thread while find() is in-progress: On Windows, SIGALRM is
|
||||
# unavailable so we use a second thread. In our Evergreen setup on
|
||||
# Linux, the thread technique causes an error in the test at
|
||||
# sock.recv(): TypeError: 'int' object is not callable
|
||||
# We don't know what causes this, so we hack around it.
|
||||
|
||||
# Can't use self.assertRaises() because it doesn't catch system
|
||||
# exceptions
|
||||
self.assertTrue(raised, "Didn't raise expected KeyboardInterrupt")
|
||||
if sys.platform == 'win32':
|
||||
def interrupter():
|
||||
# Raises KeyboardInterrupt in the main thread
|
||||
time.sleep(0.25)
|
||||
thread.interrupt_main()
|
||||
|
||||
thread.start_new_thread(interrupter, ())
|
||||
else:
|
||||
# Convert SIGALRM to SIGINT -- it's hard to schedule a SIGINT
|
||||
# for one second in the future, but easy to schedule SIGALRM.
|
||||
def sigalarm(num, frame):
|
||||
raise KeyboardInterrupt
|
||||
|
||||
old_signal_handler = signal.signal(signal.SIGALRM, sigalarm)
|
||||
signal.alarm(1)
|
||||
|
||||
raised = False
|
||||
try:
|
||||
# Will be interrupted by a KeyboardInterrupt.
|
||||
db.foo.find({'$where': where}).next()
|
||||
except KeyboardInterrupt:
|
||||
raised = True
|
||||
|
||||
# Can't use self.assertRaises() because it doesn't catch system
|
||||
# exceptions
|
||||
self.assertTrue(raised, "Didn't raise expected KeyboardInterrupt")
|
||||
|
||||
# Raises AssertionError due to PYTHON-294 -- Mongo's response to
|
||||
# the previous find() is still waiting to be read on the socket,
|
||||
# so the request id's don't match.
|
||||
self.assertEqual(
|
||||
{'_id': 1},
|
||||
db.foo.find().next()
|
||||
)
|
||||
finally:
|
||||
if old_signal_handler:
|
||||
signal.signal(signal.SIGALRM, old_signal_handler)
|
||||
|
||||
# Raises AssertionError due to PYTHON-294 -- Mongo's response to the
|
||||
# previous find() is still waiting to be read on the socket, so the
|
||||
# request id's don't match.
|
||||
self.assertEqual(
|
||||
{'_id': 1},
|
||||
db.foo.find().next()
|
||||
)
|
||||
|
||||
def test_operation_failure_without_request(self):
|
||||
# Ensure MongoClient doesn't close socket after it gets an error
|
||||
|
||||
@ -956,15 +956,29 @@ class TestReplicaSetClient(TestReplicaSetClientBase, TestRequestMixin):
|
||||
db.foo.insert({'_id': 1})
|
||||
|
||||
old_signal_handler = None
|
||||
|
||||
try:
|
||||
def interrupter():
|
||||
time.sleep(0.25)
|
||||
# Platform-specific hacks for raising a KeyboardInterrupt on the
|
||||
# main thread while find() is in-progress: On Windows, SIGALRM is
|
||||
# unavailable so we use a second thread. In our Evergreen setup on
|
||||
# Linux, the thread technique causes an error in the test at
|
||||
# sock.recv(): TypeError: 'int' object is not callable
|
||||
# We don't know what causes this, so we hack around it.
|
||||
|
||||
# Raises KeyboardInterrupt in the main thread
|
||||
thread.interrupt_main()
|
||||
if sys.platform == 'win32':
|
||||
def interrupter():
|
||||
# Raises KeyboardInterrupt in the main thread
|
||||
time.sleep(0.25)
|
||||
thread.interrupt_main()
|
||||
|
||||
thread.start_new_thread(interrupter, ())
|
||||
thread.start_new_thread(interrupter, ())
|
||||
else:
|
||||
# Convert SIGALRM to SIGINT -- it's hard to schedule a SIGINT
|
||||
# for one second in the future, but easy to schedule SIGALRM.
|
||||
def sigalarm(num, frame):
|
||||
raise KeyboardInterrupt
|
||||
|
||||
old_signal_handler = signal.signal(signal.SIGALRM, sigalarm)
|
||||
signal.alarm(1)
|
||||
|
||||
raised = False
|
||||
try:
|
||||
@ -975,11 +989,11 @@ class TestReplicaSetClient(TestReplicaSetClientBase, TestRequestMixin):
|
||||
|
||||
# Can't use self.assertRaises() because it doesn't catch system
|
||||
# exceptions
|
||||
self.assertTrue(raised, "Didn't raise expected ConnectionFailure")
|
||||
self.assertTrue(raised, "Didn't raise expected KeyboardInterrupt")
|
||||
|
||||
# Raises AssertionError due to PYTHON-294 -- Mongo's response to the
|
||||
# previous find() is still waiting to be read on the socket, so the
|
||||
# request id's don't match.
|
||||
# Raises AssertionError due to PYTHON-294 -- Mongo's response to
|
||||
# the previous find() is still waiting to be read on the socket,
|
||||
# so the request id's don't match.
|
||||
self.assertEqual(
|
||||
{'_id': 1},
|
||||
db.foo.find().next()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user