Merge pull request #731 from datastax/python-update-unit-tests

Python update unit tests
This commit is contained in:
Jaume Marhuenda 2017-04-19 13:57:04 -04:00 committed by GitHub
commit 4ca22b2e8e
8 changed files with 136 additions and 115 deletions

View File

@ -12,24 +12,13 @@ python -c "import platform; print(platform.architecture())"
$wc = New-Object 'System.Net.WebClient'
nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=unit_results.xml .\tests\unit
$env:MONKEY_PATCH_LOOP=1
nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=unit_results.xml .\tests\unit\io\test_geventreactor.py
nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=unit_results.xml .\tests\unit\io\test_eventletreactor.py
Remove-Item $env:MONKEY_PATCH_LOOP
echo "uploading unit results"
$wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\unit_results.xml))
if($env:ci_type -eq 'standard' -Or $env:ci_type -eq 'long'){
echo "Running CQLEngine integration tests"
nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=cqlengine_results.xml .\tests\integration\cqlengine
$wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\cqlengine_results.xml))
echo "uploading CQLEngine test results"
echo "Running standard integration tests"
nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=standard_results.xml .\tests\integration\standard
$wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\standard_results.xml))
echo "uploading standard integration test results"
}
if($env:ci_type -eq 'long'){
nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=cqlengine_results.xml .\tests\integration\cqlengine
$wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\cqlengine_results.xml))
echo "uploading standard integration test results"
}
exit 0

View File

@ -20,6 +20,7 @@ import logging
import sys
import socket
import platform
import os
log = logging.getLogger()
log.setLevel('DEBUG')
@ -44,7 +45,22 @@ def is_gevent_monkey_patched():
return socket.socket is gevent.socket.socket
def is_gevent_time_monkey_patched():
import gevent.monkey
return "time" in gevent.monkey.saved
def is_eventlet_time_monkey_patched():
import eventlet
return eventlet.patcher.is_monkey_patched('time')
def is_monkey_patched():
return is_gevent_monkey_patched() or is_eventlet_monkey_patched()
MONKEY_PATCH_LOOP = bool(os.getenv('MONKEY_PATCH_LOOP', False))
notwindows = unittest.skipUnless(not "Windows" in platform.system(), "This test is not adequate for windows")
notpypy = unittest.skipUnless(not platform.python_implementation() == 'PyPy', "This tests is not suitable for pypy")
notmonkeypatch = unittest.skipUnless(MONKEY_PATCH_LOOP, "Skpping this test because monkey patching is required")

View File

@ -16,13 +16,21 @@
import os
import select
import socket
import thread
import Queue
try:
import thread
import Queue
import __builtin__
#For python3 compatibility
except ImportError:
import _thread as thread
import queue as Queue
import builtins as __builtin__
import threading
import __builtin__
import ssl
import time
import eventlet
from imp import reload
def eventlet_un_patch_all():
"""
@ -34,4 +42,7 @@ def eventlet_un_patch_all():
for to_unpatch in modules_to_unpatch:
reload(to_unpatch)
def restore_saved_module(module):
reload(module)
del eventlet.patcher.already_patched[module.__name__]

View File

@ -18,50 +18,30 @@ try:
except ImportError:
import unittest # noqa
from tests.unit.io.utils import submit_and_wait_for_completion, TimerCallback
from tests import is_eventlet_monkey_patched
import time
from tests.unit.io.utils import TimerConnectionTests
from tests import notpypy, MONKEY_PATCH_LOOP, notmonkeypatch
from eventlet import monkey_patch
try:
from cassandra.io.eventletreactor import EventletConnection
except ImportError:
EventletConnection = None # noqa
class EventletTimerTest(unittest.TestCase):
def setUp(self):
if EventletConnection is None:
raise unittest.SkipTest("Eventlet libraries not available")
if not is_eventlet_monkey_patched():
raise unittest.SkipTest("Can't test eventlet without monkey patching")
# There are some issues with some versions of pypy and eventlet
@notpypy
@unittest.skipIf(EventletConnection is None, "Skpping the eventlet tests because it's not installed")
@notmonkeypatch
class EventletTimerTest(unittest.TestCase, TimerConnectionTests):
@classmethod
def setUpClass(cls):
# This is run even though the class is skipped, so we need
# to make sure no monkey patching is happening
if not MONKEY_PATCH_LOOP:
return
monkey_patch()
cls.connection_class = EventletConnection
EventletConnection.initialize_reactor()
def test_multi_timer_validation(self, *args):
"""
Verify that timer timeouts are honored appropriately
"""
# Tests timers submitted in order at various timeouts
submit_and_wait_for_completion(self, EventletConnection, 0, 100, 1, 100)
# Tests timers submitted in reverse order at various timeouts
submit_and_wait_for_completion(self, EventletConnection, 100, 0, -1, 100)
# Tests timers submitted in varying order at various timeouts
submit_and_wait_for_completion(self, EventletConnection, 0, 100, 1, 100, True)
def test_timer_cancellation(self):
"""
Verify that timer cancellation is honored
"""
# Various lists for tracking callback stage
timeout = .1
callback = TimerCallback(timeout)
timer = EventletConnection.create_timer(timeout, callback.invoke)
timer.cancel()
# Release context allow for timer thread to run.
time.sleep(.2)
timer_manager = EventletConnection._timers
# Assert that the cancellation was honored
self.assertFalse(timer_manager._queue)
self.assertFalse(timer_manager._new_timers)
self.assertFalse(callback.was_invoked())
# There is no unpatching because there is not a clear way
# of doing it reliably

View File

@ -17,67 +17,28 @@ try:
except ImportError:
import unittest # noqa
import time
from tests.unit.io.utils import submit_and_wait_for_completion, TimerCallback
from tests import is_gevent_monkey_patched, is_eventlet_monkey_patched
from tests.unit.io.utils import TimerConnectionTests
from tests import MONKEY_PATCH_LOOP, notmonkeypatch
try:
from cassandra.io.geventreactor import GeventConnection
import gevent.monkey
from gevent_utils import gevent_un_patch_all
except ImportError:
GeventConnection = None # noqa
class GeventTimerTest(unittest.TestCase):
need_unpatch = False
@unittest.skipIf(GeventConnection is None, "Skpping the gevent tests because it's not installed")
@notmonkeypatch
class GeventTimerTest(unittest.TestCase, TimerConnectionTests):
@classmethod
def setUpClass(cls):
if is_eventlet_monkey_patched():
return # no dynamic patching if we have eventlet applied
if GeventConnection is not None:
if not is_gevent_monkey_patched():
cls.need_unpatch = True
gevent.monkey.patch_all()
@classmethod
def tearDownClass(cls):
if cls.need_unpatch:
gevent_un_patch_all()
def setUp(self):
if not is_gevent_monkey_patched():
raise unittest.SkipTest("Can't test gevent without monkey patching")
# This is run even though the class is skipped, so we need
# to make sure no monkey patching is happening
if not MONKEY_PATCH_LOOP:
return
gevent.monkey.patch_all()
cls.connection_class = GeventConnection
GeventConnection.initialize_reactor()
def test_multi_timer_validation(self):
"""
Verify that timer timeouts are honored appropriately
"""
# Tests timers submitted in order at various timeouts
submit_and_wait_for_completion(self, GeventConnection, 0, 100, 1, 100)
# Tests timers submitted in reverse order at various timeouts
submit_and_wait_for_completion(self, GeventConnection, 100, 0, -1, 100)
# Tests timers submitted in varying order at various timeouts
submit_and_wait_for_completion(self, GeventConnection, 0, 100, 1, 100, True),
def test_timer_cancellation(self):
"""
Verify that timer cancellation is honored
"""
# Various lists for tracking callback stage
timeout = .1
callback = TimerCallback(timeout)
timer = GeventConnection.create_timer(timeout, callback.invoke)
timer.cancel()
# Release context allow for timer thread to run.
time.sleep(.2)
timer_manager = GeventConnection._timers
# Assert that the cancellation was honored
self.assertFalse(timer_manager._queue)
self.assertFalse(timer_manager._new_timers)
self.assertFalse(callback.was_invoked())
# There is no unpatching because there is not a clear way
# of doing it reliably

View File

@ -22,6 +22,7 @@ from mock import patch, Mock
import time
from tests.unit.io.utils import submit_and_wait_for_completion, TimerCallback
from tests.unit.io.utils import TimerConnectionTests
from tests import is_monkey_patched

View File

@ -12,6 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
try:
import unittest2 as unittest
except ImportError:
import unittest # noqa
import time
@ -103,3 +108,34 @@ def submit_and_wait_for_completion(unit_test, connection, start, end, increment,
# ensure they are all called back in a timely fashion
for callback in completed_callbacks:
unit_test.assertAlmostEqual(callback.expected_wait, callback.get_wait_time(), delta=.15)
class TimerConnectionTests(object):
def test_multi_timer_validation(self):
"""
Verify that timer timeouts are honored appropriately
"""
# Tests timers submitted in order at various timeouts
submit_and_wait_for_completion(self, self.connection_class, 0, 100, 1, 100)
# Tests timers submitted in reverse order at various timeouts
submit_and_wait_for_completion(self, self.connection_class, 100, 0, -1, 100)
# Tests timers submitted in varying order at various timeouts
submit_and_wait_for_completion(self, self.connection_class, 0, 100, 1, 100, True),
def test_timer_cancellation(self):
"""
Verify that timer cancellation is honored
"""
# Various lists for tracking callback stage
timeout = .1
callback = TimerCallback(timeout)
timer = self.connection_class.create_timer(timeout, callback.invoke)
timer.cancel()
# Release context allow for timer thread to run.
time.sleep(.2)
timer_manager = self.connection_class._timers
# Assert that the cancellation was honored
self.assertFalse(timer_manager._queue)
self.assertFalse(timer_manager._new_timers)
self.assertFalse(callback.was_invoked())

33
tox.ini
View File

@ -7,13 +7,40 @@ deps = nose
PyYAML
six
packaging
cython
eventlet
twisted <15.5.0
[testenv]
deps = {[base]deps}
cython
py{27}: gevent
twisted <15.5.0
setenv = LIBEV_EMBED=0
CARES_EMBED=0
changedir = {envtmpdir}
commands = nosetests --verbosity=2 --no-path-adjustment {toxinidir}/tests/unit/
[testenv:py27]
deps = {[base]deps}
gevent
setenv = LIBEV_EMBED=0
CARES_EMBED=0
MONKEY_PATCH_LOOP=1
changedir = {envtmpdir}
commands =
nosetests --verbosity=2 --no-path-adjustment {toxinidir}/tests/unit/io/test_eventletreactor.py
nosetests --verbosity=2 --no-path-adjustment {toxinidir}/tests/unit/io/test_geventreactor.py
[testenv:py34]
deps = {[base]deps}
gevent
setenv = LIBEV_EMBED=0
CARES_EMBED=0
MONKEY_PATCH_LOOP=1
changedir = {envtmpdir}
commands =
nosetests --verbosity=2 --no-path-adjustment {toxinidir}/tests/unit/io/test_eventletreactor.py
nosetests --verbosity=2 --no-path-adjustment {toxinidir}/tests/unit/io/test_geventreactor.py