Skip to content

Commit

Permalink
Merge pull request #39 from gregoil/add_monitor_ut
Browse files Browse the repository at this point in the history
Added monitors ut
  • Loading branch information
gregoil committed Mar 25, 2018
2 parents 44c6d4f + 718d86d commit 54d2ce8
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 5 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

setup(
name='rotest',
version="2.7.5",
version="2.7.6",
description="Resource oriented testing framework",
long_description=open("README.rst").read(),
license="MIT",
Expand Down
6 changes: 4 additions & 2 deletions src/rotest/core/result/monitor/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,16 @@ def safe_run_monitor(self, test):
test.logger.exception("Got an error while running monitor %r",
self.NAME)

def start_test(self, test):
def setup_finished(self, test):
"""Handle test start event - register the monitor.
Args:
test (object): test item instance.
"""
# Don't register a thread if the monitor doesn't override 'run_monitor'
if self.run_monitor.im_func is AbstractMonitor.run_monitor.im_func:
if self.run_monitor.im_func is AbstractMonitor.run_monitor.im_func or \
self.CYCLE is NotImplemented:

return

if isinstance(test, TestCase) or \
Expand Down
270 changes: 270 additions & 0 deletions tests/core/handlers_tests/test_monitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
"""Test Rotest's Monitor class behavior."""
import time
import threading

from rotest.core.case import request
from rotest.management.models.ut_models import DemoResource
from rotest.core.result.monitor import AbstractMonitor, AbstractResourceMonitor

from tests.core.utils import (MockCase,
MockTestSuite,
BasicRotestUnitTest)

COMMON_LIST = []
RESOURCE_NAME = 'available_resource1'


class SuccessShortMonitor(AbstractMonitor):
"""Monitor with short cycle."""
CYCLE = 0.2

def run_monitor(self, test):
COMMON_LIST.append(threading.current_thread())


class SuccessLongMonitor(AbstractMonitor):
"""Monitor with cycle longer than the test."""
CYCLE = 5.0

def run_monitor(self, test):
COMMON_LIST.append(threading.current_thread())


class SuccessNonMonitor(AbstractMonitor):
"""Monitor with no cyclevalue passed."""
def run_monitor(self, test):
COMMON_LIST.append(threading.current_thread())


class FailingOnceShortMonitor(AbstractMonitor):
"""Monitor that fails once with short cycle."""
CYCLE = 0.2
SINGLE_FAILURE = True

def run_monitor(self, test):
COMMON_LIST.append(threading.current_thread())
self.fail_test(test, "monitor failure")


class FailingMuchShortMonitor(AbstractMonitor):
"""Monitor that fails many times with short cycle.."""
CYCLE = 0.2
SINGLE_FAILURE = False

def run_monitor(self, test):
COMMON_LIST.append(threading.current_thread())
self.fail_test(test, "monitor failure")


class GotResourceMonitor(AbstractResourceMonitor):
"""Resource monitor with short cycle."""
CYCLE = 0.2
RESOURCE_NAME = 'test_resource'

def run_monitor(self, test):
COMMON_LIST.append(threading.current_thread())


class NoResourceMonitor(AbstractResourceMonitor):
"""Resource monitor that expected a non-existing resource."""
CYCLE = 0.2
RESOURCE_NAME = 'non_existing_resource'

def run_monitor(self, test):
COMMON_LIST.append(threading.current_thread())


class LongSuccessCase(MockCase):
"""Test that waits a while and then passes."""
__test__ = False

resources = (request('test_resource', DemoResource, name=RESOURCE_NAME),)

WAIT_TIME = 0.5

def test_method(self):
"""Wait a while and then pass."""
time.sleep(self.WAIT_TIME)


class AbstractMonitorTest(BasicRotestUnitTest):
"""Abstract class for testing monitors."""
__test__ = False

fixtures = ['resource_ut.json']

def setUp(self):
"""Clear global COMMON_LIST."""
super(AbstractMonitorTest, self).setUp()
del COMMON_LIST[:]

def _run_case(self, test_case):
"""Run given case and return it.
Args:
test_case (rotest.core.case.TestCase): case to run.
Returns:
rotest.core.case.TestCase. the case.
"""
class InternalSuite(MockTestSuite):
components = (test_case,)

test_suite = InternalSuite()
self.run_test(test_suite)
return next(iter(test_suite))


class TestShortCycle(AbstractMonitorTest):
"""Test that monitor with a short cycle is called many times."""
__test__ = True
RESULT_OUTPUTS = [SuccessShortMonitor]

def test_method(self):
self._run_case(LongSuccessCase)

self.assertTrue(self.result.wasSuccessful(),
'Case failed when it should have succeeded')

fail_nums = len(self.result.failures)
self.assertEqual(fail_nums, 0,
"Unexpected number of failures, expected %d got %d" %
(0, fail_nums))

cycle_nums = len(COMMON_LIST)
self.assertGreater(cycle_nums, 1,
"Unexpected number of cycles, expected more than "
"%d got %d" %
(1, cycle_nums))

monitor_thread = COMMON_LIST[0]
self.assertFalse(monitor_thread.is_alive(),
"Monitor thread is still alive after the test")


class TestLongCycle(AbstractMonitorTest):
"""Test that monitor with a too long cycle is called only one time."""
__test__ = True
RESULT_OUTPUTS = [SuccessLongMonitor]

def test_method(self):
self._run_case(LongSuccessCase)

self.assertTrue(self.result.wasSuccessful(),
'Case failed when it should have succeeded')

fail_nums = len(self.result.failures)
self.assertEqual(fail_nums, 0,
"Unexpected number of failures, expected %d got %d" %
(0, fail_nums))

cycle_nums = len(COMMON_LIST)
self.assertEqual(cycle_nums, 1,
"Unexpected number of cycles, expected %d got %d" %
(1, cycle_nums))

monitor_thread = COMMON_LIST[0]
self.assertFalse(monitor_thread.is_alive(),
"Monitor thread is still alive after the test")


class TestNoCycle(AbstractMonitorTest):
"""Test that monitor with no cycle defined is not called."""
__test__ = True
RESULT_OUTPUTS = [SuccessNonMonitor]

def test_method(self):
self._run_case(LongSuccessCase)

self.assertTrue(self.result.wasSuccessful(),
'Case failed when it should have succeeded')

fail_nums = len(self.result.failures)
self.assertEqual(fail_nums, 0,
"Unexpected number of failures, expected %d got %d" %
(0, fail_nums))

cycle_nums = len(COMMON_LIST)
self.assertEqual(cycle_nums, 0,
"Unexpected number of cycles, expected %d got %d" %
(0, cycle_nums))


class TestSingleFailure(AbstractMonitorTest):
"""Test that monitor that allows a single failure only fails once."""
__test__ = True
RESULT_OUTPUTS = [FailingOnceShortMonitor]

def test_method(self):
self._run_case(LongSuccessCase)

self.assertFalse(self.result.wasSuccessful(),
'Case failed when it should have succeeded')

fail_nums = len(self.result.failures)
print self.result.failures
self.assertEqual(fail_nums, 1,
"Unexpected number of failures, expected %d got %d" %
(1, fail_nums))

monitor_thread = COMMON_LIST[0]
self.assertFalse(monitor_thread.is_alive(),
"Monitor thread is still alive after the test")


class TestMultipleFailure(AbstractMonitorTest):
"""Test that monitor that allows many single failure fails many times."""
__test__ = True
RESULT_OUTPUTS = [FailingMuchShortMonitor]

def test_method(self):
self._run_case(LongSuccessCase)

self.assertFalse(self.result.wasSuccessful(),
'Case failed when it should have succeeded')

fail_nums = len(self.result.failures)
self.assertGreater(fail_nums, 1,
"Unexpected number of failures, expected more than "
"%d got %d" %
(1, fail_nums))

monitor_thread = COMMON_LIST[0]
self.assertFalse(monitor_thread.is_alive(),
"Monitor thread is still alive after the test")


class TestGotResourceMonitor(AbstractMonitorTest):
"""Test that resource monitor runs when it gets its resource."""
__test__ = True
RESULT_OUTPUTS = [GotResourceMonitor]

def test_method(self):
self._run_case(LongSuccessCase)

self.assertTrue(self.result.wasSuccessful(),
'Case failed when it should have succeeded')

cycle_nums = len(COMMON_LIST)
self.assertGreater(cycle_nums, 1,
"Unexpected number of cycles, expected more than "
"%d got %d" %
(1, cycle_nums))


class TestNoResourceMonitor(AbstractMonitorTest):
"""Test that resource monitor doesn't runs when there's no resource."""
__test__ = True
RESULT_OUTPUTS = [NoResourceMonitor]

def test_method(self):
"""."""
self._run_case(LongSuccessCase)

self.assertTrue(self.result.wasSuccessful(),
'Case failed when it should have succeeded')

cycle_nums = len(COMMON_LIST)
self.assertEqual(cycle_nums, 0,
"Unexpected number of cycles, expected %d got %d" %
(0, cycle_nums))
2 changes: 1 addition & 1 deletion tests/core/test_run_delta.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class TestRunDelta(BasicRotestUnitTest):

fixtures = ['case_ut.json']

RESULT_OUTPUTS = [DBHandler.NAME]
RESULT_OUTPUTS = [DBHandler]

def setUp(self):
"""Create a run data the enabled running in delta mode."""
Expand Down
6 changes: 5 additions & 1 deletion tests/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ def create_result(cls, main_test):
Returns:
Result. a new initiated result object.
"""
result = Result(outputs=cls.RESULT_OUTPUTS, main_test=main_test)
result = Result(outputs=[], main_test=main_test)
for handler_class in cls.RESULT_OUTPUTS:
result.result_handlers.append(handler_class(
main_test=result.main_test))

result.startTestRun()
return result

Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ envlist =
{py27}-{linux,win32}

[testenv]
passenv=ROTEST_WORK_DIR
basepython =
py27: python2.7
py36: python3.6
Expand Down

0 comments on commit 54d2ce8

Please sign in to comment.