You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
6.5 KiB
Python
169 lines
6.5 KiB
Python
5 years ago
|
from gevent import monkey
|
||
|
monkey.patch_all()
|
||
|
|
||
|
import sys
|
||
|
import unittest
|
||
|
from gevent.testing.testcase import SubscriberCleanupMixin
|
||
|
|
||
|
class TestMonkey(SubscriberCleanupMixin, unittest.TestCase):
|
||
|
|
||
|
maxDiff = None
|
||
|
|
||
|
def setUp(self):
|
||
|
super(TestMonkey, self).setUp()
|
||
|
|
||
|
self.all_events = []
|
||
|
self.addSubscriber(self.all_events.append)
|
||
|
self.orig_saved = orig_saved = {}
|
||
|
for k, v in monkey.saved.items():
|
||
|
orig_saved[k] = v.copy()
|
||
|
|
||
|
|
||
|
def tearDown(self):
|
||
|
monkey.saved = self.orig_saved
|
||
|
del self.orig_saved
|
||
|
del self.all_events
|
||
|
super(TestMonkey, self).tearDown()
|
||
|
|
||
|
def test_time(self):
|
||
|
import time
|
||
|
from gevent import time as gtime
|
||
|
self.assertIs(time.sleep, gtime.sleep)
|
||
|
|
||
|
def test_thread(self):
|
||
|
try:
|
||
|
import thread
|
||
|
except ImportError:
|
||
|
import _thread as thread
|
||
|
import threading
|
||
|
|
||
|
from gevent import thread as gthread
|
||
|
self.assertIs(thread.start_new_thread, gthread.start_new_thread)
|
||
|
self.assertIs(threading._start_new_thread, gthread.start_new_thread)
|
||
|
|
||
|
# Event patched by default
|
||
|
self.assertTrue(monkey.is_object_patched('threading', 'Event'))
|
||
|
|
||
|
if sys.version_info[0] == 2:
|
||
|
from gevent import threading as gthreading
|
||
|
from gevent.event import Event as GEvent
|
||
|
self.assertIs(threading._sleep, gthreading._sleep)
|
||
|
self.assertTrue(monkey.is_object_patched('threading', '_Event'))
|
||
|
self.assertIs(threading._Event, GEvent)
|
||
|
|
||
|
def test_socket(self):
|
||
|
import socket
|
||
|
from gevent import socket as gevent_socket
|
||
|
self.assertIs(socket.create_connection, gevent_socket.create_connection)
|
||
|
|
||
|
def test_os(self):
|
||
|
import os
|
||
|
import types
|
||
|
from gevent import os as gos
|
||
|
for name in ('fork', 'forkpty'):
|
||
|
if hasattr(os, name):
|
||
|
attr = getattr(os, name)
|
||
|
self.assertNotIn('built-in', repr(attr))
|
||
|
self.assertNotIsInstance(attr, types.BuiltinFunctionType)
|
||
|
self.assertIsInstance(attr, types.FunctionType)
|
||
|
self.assertIs(attr, getattr(gos, name))
|
||
|
|
||
|
def test_saved(self):
|
||
|
self.assertTrue(monkey.saved)
|
||
|
for modname in monkey.saved:
|
||
|
self.assertTrue(monkey.is_module_patched(modname))
|
||
|
|
||
|
for objname in monkey.saved[modname]:
|
||
|
self.assertTrue(monkey.is_object_patched(modname, objname))
|
||
|
|
||
|
def test_patch_subprocess_twice(self):
|
||
|
Popen = monkey.get_original('subprocess', 'Popen')
|
||
|
self.assertNotIn('gevent', repr(Popen))
|
||
|
self.assertIs(Popen, monkey.get_original('subprocess', 'Popen'))
|
||
|
monkey.patch_subprocess()
|
||
|
self.assertIs(Popen, monkey.get_original('subprocess', 'Popen'))
|
||
|
|
||
|
def test_patch_twice_warnings_events(self):
|
||
|
import warnings
|
||
|
|
||
|
all_events = self.all_events
|
||
|
|
||
|
with warnings.catch_warnings(record=True) as issued_warnings:
|
||
|
# Patch again, triggering just one warning, for
|
||
|
# a different set of arguments. Because we're going to False instead of
|
||
|
# turning something on, nothing is actually done, no events are issued.
|
||
|
monkey.patch_all(os=False, extra_kwarg=42)
|
||
|
self.assertEqual(len(issued_warnings), 1)
|
||
|
self.assertIn('more than once', str(issued_warnings[0].message))
|
||
|
self.assertEqual(all_events, [])
|
||
|
|
||
|
# Same warning again, but still nothing is done.
|
||
|
del issued_warnings[:]
|
||
|
monkey.patch_all(os=False)
|
||
|
self.assertEqual(len(issued_warnings), 1)
|
||
|
self.assertIn('more than once', str(issued_warnings[0].message))
|
||
|
self.assertEqual(all_events, [])
|
||
|
self.orig_saved['_gevent_saved_patch_all_module_settings'] = monkey.saved[
|
||
|
'_gevent_saved_patch_all_module_settings']
|
||
|
|
||
|
# Make sure that re-patching did not change the monkey.saved
|
||
|
# attribute, overwriting the original functions.
|
||
|
if 'logging' in monkey.saved and 'logging' not in self.orig_saved:
|
||
|
# some part of the warning or unittest machinery imports logging
|
||
|
self.orig_saved['logging'] = monkey.saved['logging']
|
||
|
self.assertEqual(self.orig_saved, monkey.saved)
|
||
|
|
||
|
# Make sure some problematic attributes stayed correct.
|
||
|
# NOTE: This was only a problem if threading was not previously imported.
|
||
|
for k, v in monkey.saved['threading'].items():
|
||
|
self.assertNotIn('gevent', str(v), (k, v))
|
||
|
|
||
|
def test_patch_events(self):
|
||
|
from gevent import events
|
||
|
from gevent.testing import verify
|
||
|
all_events = self.all_events
|
||
|
|
||
|
def veto(event):
|
||
|
if isinstance(event, events.GeventWillPatchModuleEvent) and event.module_name == 'ssl':
|
||
|
raise events.DoNotPatch
|
||
|
self.addSubscriber(veto)
|
||
|
|
||
|
monkey.saved = {} # Reset
|
||
|
monkey.patch_all(thread=False, select=False, extra_kwarg=42) # Go again
|
||
|
|
||
|
self.assertIsInstance(all_events[0], events.GeventWillPatchAllEvent)
|
||
|
self.assertEqual({'extra_kwarg': 42}, all_events[0].patch_all_kwargs)
|
||
|
verify.verifyObject(events.IGeventWillPatchAllEvent, all_events[0])
|
||
|
|
||
|
self.assertIsInstance(all_events[1], events.GeventWillPatchModuleEvent)
|
||
|
verify.verifyObject(events.IGeventWillPatchModuleEvent, all_events[1])
|
||
|
|
||
|
self.assertIsInstance(all_events[2], events.GeventDidPatchModuleEvent)
|
||
|
verify.verifyObject(events.IGeventWillPatchModuleEvent, all_events[1])
|
||
|
|
||
|
self.assertIsInstance(all_events[-2], events.GeventDidPatchBuiltinModulesEvent)
|
||
|
verify.verifyObject(events.IGeventDidPatchBuiltinModulesEvent, all_events[-2])
|
||
|
|
||
|
self.assertIsInstance(all_events[-1], events.GeventDidPatchAllEvent)
|
||
|
verify.verifyObject(events.IGeventDidPatchAllEvent, all_events[-1])
|
||
|
|
||
|
for e in all_events:
|
||
|
self.assertFalse(isinstance(e, events.GeventDidPatchModuleEvent)
|
||
|
and e.module_name == 'ssl')
|
||
|
|
||
|
def test_patch_queue(self):
|
||
|
try:
|
||
|
import queue
|
||
|
except ImportError:
|
||
|
# Python 2 called this Queue. Note that having
|
||
|
# python-future installed gives us a queue module on
|
||
|
# Python 2 as well.
|
||
|
queue = None
|
||
|
if not hasattr(queue, 'SimpleQueue'):
|
||
|
raise unittest.SkipTest("Needs SimpleQueue")
|
||
|
# pylint:disable=no-member
|
||
|
self.assertIs(queue.SimpleQueue, queue._PySimpleQueue)
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
unittest.main()
|