def test_string_callable_to_runnable_tgt(self): """TODO.""" import sys task = Task("callable_to_runnable", module=__name__) materialized_task_result(task, sys.maxsize) task = Task("callable_to_runnable_with_arg", module=__name__, args=(2, )) materialized_task_result(task, 2) task = Task( "callable_to_runnable", module="tests.unit.testplan.runners.pools.tasks.data.sample_tasks", args=(2, ), ) materialized_task_result(task, 4) task = Task( "sample_tasks.callable_to_adapted_runnable", module="tests.unit.testplan.runners.pools.tasks.data.relative", args=(2, ), ) materialized_task_result(task, 4)
def test_multi_parts_invalid_parameter_1(): """ Execute MultiTest parts with invalid parameters that a part of MultiTest has been scheduled twice. """ plan = Testplan(name='plan', parse_cmdline=False, merge_scheduled_parts=True) pool = ThreadPool(name='MyPool', size=2) plan.add_resource(pool) for idx in range(3): task = Task(target=get_mtest(part_tuple=(idx, 3))) plan.schedule(task, resource='MyPool') plan.schedule(Task(target=get_mtest(part_tuple=(1, 3))), resource='MyPool') with log_propagation_disabled(TESTPLAN_LOGGER): assert plan.run().run is False assert len(plan.report.entries) == 1 assert len(plan.report.entries[0].entries) == 2 assert plan.report.status == Status.ERROR # Testplan result assert plan.report.entries[0].status == Status.ERROR # Multitest assert plan.report.entries[0].entries[0].status == Status.FAILED # Suite1 assert plan.report.entries[0].entries[1].status == Status.FAILED # Suite2 assert 'invalid parameter of part provided' in \ plan.report.entries[0].logs[0]['message']
def test_string_runnable_tgt_other_module(self): """TODO.""" task = Task( "Multiplier", module="tests.unit.testplan.runners.pools.tasks.data.sample_tasks", args=(4, ), ) materialized_task_result(task, 8) task = Task( "Wrapper.InnerMultiplier", module="tests.unit.testplan.runners.pools.tasks.data.sample_tasks", args=(5, ), ) materialized_task_result(task, 10) task = Task( "sample_tasks.Multiplier", module="tests.unit.testplan.runners.pools.tasks.data.relative", args=(4, ), kwargs={"multiplier": 3}, ) materialized_task_result(task, 12) task = Task( "sample_tasks.Wrapper.InnerMultiplier", module="tests.unit.testplan.runners.pools.tasks.data.relative", args=(5, ), kwargs={"multiplier": 3}, ) materialized_task_result(task, 15)
def test_multi_parts_merged(): """ Schedule MultiTest parts in different ways, execute them and merge reports. """ plan = TestplanMock(name="plan", merge_scheduled_parts=True) pool = ThreadPool(name="MyThreadPool", size=2) plan.add_resource(pool) def _get_mtest(): return MultiTest(name="MTest", suites=[Suite1(), Suite2()], part=(2, 3)) plan.add(target=_get_mtest()) # local_runner plan.add(Task(target=get_mtest(part_tuple=(1, 3)))) # local_runner plan.schedule(Task(target=get_mtest(part_tuple=(0, 3))), resource="MyThreadPool") assert plan.run().run is True assert len(plan.report.entries) == 1 assert plan.report.entries[0].name == "MTest" assert len(plan.report.entries[0].entries) == 2 # 2 suites assert plan.report.entries[0].entries[0].name == "Suite1" assert plan.report.entries[0].entries[1].name == "Suite2" assert len(plan.report.entries[0].entries[0].entries) == 1 # param group assert plan.report.entries[0].entries[0].entries[0].name == "test_true" assert len(plan.report.entries[0].entries[1].entries) == 1 # param group assert plan.report.entries[0].entries[1].entries[0].name == "test_false" assert len(plan.report.entries[0].entries[0].entries[0].entries) == 10 assert len(plan.report.entries[0].entries[1].entries[0].entries) == 3
def test_path_usage(self): # pylint: disable=R0201 """TODO.""" dirname = os.path.dirname(os.path.abspath(__file__)) path = os.path.join(dirname, "data") task = Task("Multiplier", module="relative.sample_tasks", args=(4, ), path=path) materialized_task_result(task, 8) task = Task( "callable_to_runnable", module="relative.sample_tasks", args=(2, ), path=path, ) materialized_task_result(task, 4) path = os.path.join(path, "relative") task = Task("Multiplier", module="sample_tasks", args=(4, ), path=path) materialized_task_result(task, 8) task = Task("callable_to_runnable", module="sample_tasks", args=(2, ), path=path) materialized_task_result(task, 4)
def test_multi_parts_duplicate_part(): """ Execute MultiTest parts with a part of MultiTest has been scheduled twice and automatically be filtered out. """ plan = TestplanMock(name="plan", merge_scheduled_parts=True) pool = ThreadPool(name="MyThreadPool", size=2) plan.add_resource(pool) for idx in range(3): task = Task(target=get_mtest_with_custom_uid(part_tuple=(idx, 3))) plan.schedule(task, resource="MyThreadPool") task = Task(target=get_mtest_with_custom_uid(part_tuple=(1, 3))) plan.schedule(task, resource="MyThreadPool") assert len(plan._tests) == 4 assert plan.run().run is False assert len(plan.report.entries) == 5 # one placeholder report & 4 siblings assert len(plan.report.entries[0].entries) == 0 # already cleared assert plan.report.status == Status.ERROR # Testplan result assert ("duplicate MultiTest parts had been scheduled" in plan.report.entries[0].logs[0]["message"])
def test_multi_parts_incorrect_schedule(): """ Execute MultiTest parts with invalid parameters that a MultiTest has been scheduled twice and each time split into different parts. """ plan = TestplanMock(name="plan", merge_scheduled_parts=True) pool = ThreadPool(name="MyThreadPool", size=2) plan.add_resource(pool) for idx in range(3): task = Task(target=get_mtest(part_tuple=(idx, 3))) plan.schedule(task, resource="MyThreadPool") for idx in range(2): task = Task(target=get_mtest(part_tuple=(idx, 2))) plan.schedule(task, resource="MyThreadPool") assert len(plan._tests) == 5 assert plan.run().run is False assert len(plan.report.entries) == 6 # one placeholder report & 5 siblings assert len(plan.report.entries[0].entries) == 0 # already cleared assert plan.report.status == Status.ERROR # Testplan result assert ("invalid parameter of part provided" in plan.report.entries[0].logs[0]["message"])
def test_basic_init(self): """TODO.""" task = Task("Runnable", module=__name__) result = "result" for task_result in ( TaskResult(task, result, True, None, None), TaskResult(task, result, True, "msg", None), TaskResult(task, result, True, None, [Task("Runnable", module=__name__)]), ): serialized = task_result.dumps() new_task_result = TaskResult().loads(serialized) for attr in ("_result", "status", "_reason", "_uid"): task_result_attr = getattr(task_result, attr) new_task_result_attr = getattr(new_task_result, attr) assert task_result_attr == new_task_result_attr assert task_result._task._uid == new_task_result._task._uid if task_result.follow is None: assert task_result.follow == new_task_result.follow else: assert len(task_result.follow) == len(new_task_result.follow) for idx, task in enumerate(task_result.follow): assert task._uid == new_task_result.follow[idx]._uid
def test_multi_parts_invalid_parameter_2(): """ Execute MultiTest parts with invalid parameters that a MultiTest has been scheduled twice. """ plan = TestplanMock(name="plan", merge_scheduled_parts=True) pool = ThreadPool(name="MyThreadPool", size=2) plan.add_resource(pool) for idx in range(3): task = Task(target=get_mtest(part_tuple=(idx, 3))) plan.schedule(task, resource="MyThreadPool") for idx in range(2): task = Task(target=get_mtest(part_tuple=(idx, 2))) plan.schedule(task, resource="MyThreadPool") with log_propagation_disabled(TESTPLAN_LOGGER): assert plan.run().run is False assert len(plan.report.entries) == 1 assert len(plan.report.entries[0].entries) == 2 assert plan.report.status == Status.ERROR # Testplan result assert plan.report.entries[0].status == Status.ERROR # Multitest assert plan.report.entries[0].entries[0].status == Status.FAILED # Suite1 assert plan.report.entries[0].entries[1].status == Status.FAILED # Suite2 assert ("invalid parameter of part provided" in plan.report.entries[0].logs[0]["message"])
def test_callable_to_non_runnable_tgt(self): """TODO.""" from .data.relative import sample_tasks for task in ( Task(callable_to_non_runnable), Task(sample_tasks.callable_to_non_runnable, args=(2, )), Task( "multiply", module= ("tests.unit.testplan.runners.pools.tasks.data.sample_tasks" ), args=(2, ), ), Task( "sample_tasks.multiply", module= "tests.unit.testplan.runners.pools.tasks.data.relative", args=(2, ), ), ): try: task.materialize() raise Exception("Should raise.") except RuntimeError as exc: assert "must have both `run` and `uid` methods" in str(exc)
def test_runner_timeout(): """ Execute MultiTests in LocalRunner, ThreadPool and ProcessPool respectively. Some of them will timeout and we'll get a report showing execution details. """ plan = Testplan(name='plan', parse_cmdline=False, runnable=MyTestRunner, timeout=60, abort_wait_timeout=5) mod_path = os.path.dirname(os.path.abspath(__file__)) THREAD_POOL = 'MyThreadPool' PROCESS_POOL = 'MyProcessPool' thread_pool = ThreadPool(name=THREAD_POOL, size=2, worker_heartbeat=None) proc_pool = ProcessPool(name=PROCESS_POOL, size=2, worker_heartbeat=None) plan.add_resource(thread_pool) plan.add_resource(proc_pool) plan.add(func_basic_tasks.get_mtest1()) plan.add(func_basic_tasks.get_mtest2()) task3 = Task(target='get_mtest3', module='func_basic_tasks', path=mod_path) task4 = Task(target='get_mtest4', module='func_basic_tasks', path=mod_path) task5 = Task(target='get_mtest5', module='func_basic_tasks', path=mod_path) task6 = Task(target='get_mtest6', module='func_basic_tasks', path=mod_path) plan.schedule(task3, resource=THREAD_POOL) plan.schedule(task4, resource=THREAD_POOL) plan.schedule(task5, resource=PROCESS_POOL) plan.schedule(task6, resource=PROCESS_POOL) with log_propagation_disabled(TESTPLAN_LOGGER): assert plan.run().run is False assert len(plan.report.entries) == 6 assert plan.report.status == Status.ERROR entries = plan.report.entries assert entries[0].name == 'MTest1' assert entries[0].status == Status.FAILED # testcase 'test_true' failed assert entries[2].name == 'MTest3' assert entries[2].status == Status.PASSED # testcase 'test_equal' passed assert entries[4].name == 'MTest5' assert entries[4].status == Status.ERROR # testcase 'test_contain' raised assert entries[1].name == 'MTest2' assert entries[1].status == Status.ERROR # timeout assert ' discarding due to ' in entries[1].logs[0]['message'] assert entries[3].name == 'Task[get_mtest4]' assert entries[3].status == Status.ERROR # timeout assert entries[3].logs[0]['message'].startswith('_target: get_mtest4') assert ' discarding due to ' in entries[3].logs[1]['message'] assert entries[5].name == 'Task[get_mtest6]' assert entries[5].status == Status.ERROR # timeout assert entries[5].logs[0]['message'].startswith('_target: get_mtest6') assert ' discarding due to ' in entries[5].logs[1]['message']
def test_string_runnable_tgt_same_module(self): """TODO.""" import sys task = Task('Runnable', module=__name__) materialized_task_result(task, sys.maxsize) task = Task('RunnableWithArg', module=__name__, args=(2, )) materialized_task_result(task, 2) task = Task('RunnableWithArg', module=__name__, kwargs={'number': 3}) materialized_task_result(task, 3)
def test_callable_to_non_runnable_tgt(self): # pylint: disable=R0201 """TODO.""" from .data.relative import sample_tasks for task in (Task(callable_to_non_runnable), Task(sample_tasks.callable_to_non_runnable, args=(2, )), Task('tasks.data.relative.sample_tasks.multiply', args=(2, ))): try: task.materialize() raise Exception('Should raise.') except RuntimeError as exc: assert 'must have a .run() method' in str(exc)
def test_string_runnable_tgt_other_module(self): """TODO.""" task = Task('tasks.data.sample_tasks.Multiplier', args=(4, )) materialized_task_result(task, 8) task = Task('Multiplier', module='tasks.data.sample_tasks', args=(5, )) materialized_task_result(task, 10) task = Task('tasks.data.sample_tasks.Multiplier', args=(4, ), kwargs={'multiplier': 3}) materialized_task_result(task, 12)
def test_callable_to_none(self): """TODO.""" from .data.relative import sample_tasks for task in ( Task(callable_to_none), Task(sample_tasks.callable_to_none), Task("tests.unit.testplan.runners.pools.tasks.data" ".relative.sample_tasks.callable_to_none"), ): try: task.materialize() raise Exception("Should raise.") except TaskMaterializationError as exc: assert "Cannot get a valid test object from target" in str(exc)
def test_runnable_tgt(self): # pylint: disable=R0201 """TODO.""" import sys from .data.sample_tasks import Multiplier try: materialized_task_result(Task(RunnableThatRaises()), 2) raise Exception('Should raise') except RuntimeError as exc: assert 'While running.' == str(exc) materialized_task_result(Task(Multiplier(2, 3)), 6) materialized_task_result(Task(Runnable()), sys.maxsize) materialized_task_result(Task(RunnableWithArg(2)), 2) task = Task(RunnableTaskAdaptor(lambda x: x * 2, 3)) materialized_task_result(task, 6)
def test_callable_to_runnable_tgt(self): # pylint: disable=R0201 """TODO.""" import sys task = Task(callable_to_runnable) materialized_task_result(task, sys.maxsize) task = Task(callable_to_runnable_with_arg, args=(2, )) materialized_task_result(task, 2) from .data import sample_tasks task = Task(sample_tasks.callable_to_runnable, args=(2, )) materialized_task_result(task, 4) task = Task(sample_tasks.callable_to_adapted_runnable, args=(2, )) materialized_task_result(task, 4)
def test_multi_parts_missing_parts(): """ Execute MultiTest parts with invalid parameters that not all parts of a MultiTest has been scheduled. """ plan = Testplan(name="plan", parse_cmdline=False, merge_scheduled_parts=True) pool = ThreadPool(name="MyPool", size=2) plan.add_resource(pool) for idx in range(1, 3): task = Task(target=get_mtest(part_tuple=(idx, 3))) plan.schedule(task, resource="MyPool") with log_propagation_disabled(TESTPLAN_LOGGER): assert plan.run().run is False assert len(plan.report.entries) == 1 assert len(plan.report.entries[0].entries) == 2 assert plan.report.status == Status.ERROR # Testplan result assert plan.report.entries[0].status == Status.ERROR # Multitest assert plan.report.entries[0].entries[0].status == Status.PASSED # Suite1 assert plan.report.entries[0].entries[1].status == Status.FAILED # Suite2 assert ("not all MultiTest parts had been scheduled" in plan.report.entries[0].logs[0]["message"])
def test_serialize(self): """TODO.""" import sys task = Task('Runnable', module=__name__) materialized_task_result(task, sys.maxsize, serialize=True) task = Task('RunnableWithArg', module=__name__, args=(2, )) materialized_task_result(task, 2, serialize=True) task = Task('RunnableWithArg', module=__name__, kwargs={'number': 3}) materialized_task_result(task, 3, serialize=True) dirname = os.path.dirname(os.path.abspath(__file__)) path = os.path.join(dirname, 'data', 'relative') task = Task('Multiplier', module='sample_tasks', args=(4, ), path=path) materialized_task_result(task, 8, serialize=True)
def test_multi_parts_merged(): """Execute MultiTest parts and merge report.""" plan = Testplan(name='plan', parse_cmdline=False, merge_scheduled_parts=True) pool = ThreadPool(name='MyPool', size=2) plan.add_resource(pool) for idx in range(3): task = Task(target=get_mtest(part_tuple=(idx, 3))) plan.schedule(task, resource='MyPool') with log_propagation_disabled(TESTPLAN_LOGGER): assert plan.run().run is True assert len(plan.report.entries) == 1 assert plan.report.entries[0].name == 'MTest' assert len(plan.report.entries[0].entries) == 2 # 2 suites assert plan.report.entries[0].entries[0].name == 'Suite1' assert plan.report.entries[0].entries[1].name == 'Suite2' assert len(plan.report.entries[0].entries[0].entries) == 1 # param group assert plan.report.entries[0].entries[0].entries[0].name == 'test_true' assert len(plan.report.entries[0].entries[1].entries) == 1 # param group assert plan.report.entries[0].entries[1].entries[0].name == 'test_false' assert len(plan.report.entries[0].entries[0].entries[0].entries) == 10 assert len(plan.report.entries[0].entries[1].entries[0].entries) == 3
def test_multi_parts_not_merged(): """Execute MultiTest parts but do not merge report.""" plan = TestplanMock(name="plan", merge_scheduled_parts=False) pool = ThreadPool(name="MyThreadPool", size=2) plan.add_resource(pool) for idx in range(3): task = Task(target=get_mtest(part_tuple=(idx, 3))) plan.schedule(task, resource="MyThreadPool") with log_propagation_disabled(TESTPLAN_LOGGER): assert plan.run().run is True assert len(plan.report.entries) == 3 assert plan.report.entries[0].name == "MTest - part(1/3)" assert plan.report.entries[1].name == "MTest - part(2/3)" assert plan.report.entries[2].name == "MTest - part(3/3)" assert len(plan.report.entries[0].entries) == 2 # 2 suites assert plan.report.entries[0].entries[0].name == "Suite1" assert plan.report.entries[0].entries[1].name == "Suite2" assert len(plan.report.entries[0].entries[0].entries) == 1 # param group assert plan.report.entries[0].entries[0].entries[0].name == "test_true" assert len(plan.report.entries[0].entries[1].entries) == 1 # param group assert plan.report.entries[0].entries[1].entries[0].name == "test_false" assert len(plan.report.entries[0].entries[0].entries[0].entries) == 4 assert len(plan.report.entries[0].entries[1].entries[0].entries) == 1
def materialized_task_result(task, expected, serialize=False): """TODO.""" assert isinstance(task, Task) materialized = task.materialize() if serialize is True: serialized = task.dumps() task = Task().loads(serialized) assert materialized.run() == expected
def test_string_callable_to_runnable_tgt(self): # pylint: disable=R0201 """TODO.""" import sys task = Task('callable_to_runnable', module=__name__) materialized_task_result(task, sys.maxsize) task = Task('callable_to_runnable_with_arg', module=__name__, args=(2, )) materialized_task_result(task, 2) task = Task('tasks.data.sample_tasks.callable_to_runnable', args=(2, )) materialized_task_result(task, 4) task = Task('tasks.data.sample_tasks.callable_to_adapted_runnable', args=(2, )) materialized_task_result(task, 4)
def test_non_runnable_tgt(self): # pylint: disable=R0201 """TODO.""" for task in (NonRunnableObject, NonRunnableObject(), NonRunnableObjectRunAttr, NonRunnableObjectRunAttr()): try: Task(task).materialize() except RuntimeError as exc: assert 'must have a .run() method' in str(exc)
def test_raise_on_serialization(self): """TODO.""" try: task = Task(RunnableTaskAdaptor(lambda x: x * 2, 3)) materialized_task_result(task, 6, serialize=True) raise Exception("Should raise.") except TaskSerializationError: pass
def test_serialize(self): """TODO.""" import sys task = Task("Runnable", module=__name__) materialized_task_result(task, sys.maxsize, serialize=True) task = Task("RunnableWithArg", module=__name__, args=(2, )) materialized_task_result(task, 2, serialize=True) task = Task("RunnableWithArg", module=__name__, kwargs={"number": 3}) materialized_task_result(task, 3, serialize=True) dirname = os.path.dirname(os.path.abspath(__file__)) path = os.path.join(dirname, "data", "relative") task = Task("Multiplier", module="sample_tasks", args=(4, ), path=path) materialized_task_result(task, 8, serialize=True)
def test_raise_on_deserialization(self): """TODO.""" # To add a case of a serializable but not # deserializable task. try: Task().loads(None) raise Exception("Should raise.") except TaskDeserializationError: pass
def test_path_usage(self): # pylint: disable=R0201 """TODO.""" dirname = os.path.dirname(os.path.abspath(__file__)) path = os.path.join(dirname, 'data', 'relative') task = Task('sample_tasks.Multiplier', args=(4, ), path=path) materialized_task_result(task, 8) task = Task('Multiplier', module='sample_tasks', args=(4, ), path=path) materialized_task_result(task, 8) task = Task('sample_tasks.callable_to_runnable', args=(2, ), path=path) materialized_task_result(task, 4) task = Task('callable_to_runnable', args=(2, ), module='sample_tasks', path=path) materialized_task_result(task, 4)
def test_non_runnable_tgt(self): """TODO.""" for task in ( NonRunnableObject, NonRunnableObject(), NonRunnableObjectRunAttr, NonRunnableObjectRunAttr(), ): try: Task(task).materialize() except RuntimeError as exc: assert "must have both `run` and `uid` methods" in str(exc)
def test_basic_init(self): """TODO.""" task = Task('Runnable', module=__name__) result = 'result' for task_result in (TaskResult(task, result, True, None, None), TaskResult(task, result, True, 'msg', None), TaskResult(task, result, True, None, [Task('Runnable', module=__name__)])): serialized = task_result.dumps() new_task_result = TaskResult().loads(serialized) for attr in ('_result', 'status', '_reason', '_uid'): task_result_attr = getattr(task_result, attr) new_task_result_attr = getattr(new_task_result, attr) assert task_result_attr == new_task_result_attr assert task_result._task._uid == new_task_result._task._uid if task_result.follow is None: assert task_result.follow == new_task_result.follow else: assert len(task_result.follow) == len(new_task_result.follow) for idx, task in enumerate(task_result.follow): assert task._uid == new_task_result.follow[idx]._uid