Esempio n. 1
0
def test_restart_worker(mockplan):
    pool_name = ProcessPool.__name__
    pool_size = 4
    retries_limit = int(pool_size / 2)

    pool = ProcessPool(
        name=pool_name,
        size=pool_size,
        worker_heartbeat=2,
        heartbeats_miss_limit=3,
        max_active_loop_sleep=1,
    )
    pool._task_retries_limit = retries_limit
    pool_uid = mockplan.add_resource(pool)

    dirname = os.path.dirname(os.path.abspath(__file__))

    mockplan.schedule(
        target="multitest_kill_workers",
        module="func_pool_base_tasks",
        path=dirname,
        args=(os.getpid(),),
        resource=pool_name,
    )

    for idx in range(1, 25):
        mockplan.schedule(
            target="get_mtest",
            module="func_pool_base_tasks",
            path=dirname,
            kwargs=dict(name=idx),
            resource=pool_name,
        )

    res = mockplan.run()

    # Check that all workers are restarted
    assert (
        len(
            [
                worker
                for worker in mockplan.resources[pool_uid]._workers
                if worker._aborted is True
            ]
        )
        == 0
    )

    assert res.run is False
    assert res.success is False
    assert mockplan.report.status == Status.ERROR
    assert mockplan.report.counter[Status.ERROR] == 1
Esempio n. 2
0
def test_schedule_from_main(mockplan):
    """
    Test scheduling Tasks from __main__ - it should not be allowed for
    ProcessPool.
    """
    # Set up a testplan and add a ProcessPool.
    pool = ProcessPool(name="ProcPool", size=2)
    mockplan.add_resource(pool)

    # First check that scheduling a Task with module string of '__main__'
    # raises the expected ValueError.
    with pytest.raises(ValueError):
        mockplan.schedule(
            target="target", module="__main__", resource="ProcPool"
        )

    # Secondly, check that scheduling a callable target with a __module__ attr
    # of __main__ also raises a ValueError.
    def callable_target():
        raise RuntimeError

    callable_target.__module__ = "__main__"

    with pytest.raises(ValueError):
        mockplan.schedule(target=callable_target, resource="ProcPool")
Esempio n. 3
0
def test_disable_rerun_in_pool(mockplan):
    pool_name = ProcessPool.__name__
    uid = "custom_task_uid"
    rerun_limit = 2

    pool_size = 4
    pool = ProcessPool(
        name=pool_name,
        size=pool_size,
        worker_heartbeat=2,
        heartbeats_miss_limit=2,
        max_active_loop_sleep=1,
        restart_count=0,
        allow_task_rerun=False,
    )
    pool_uid = mockplan.add_resource(pool)

    dirname = os.path.dirname(os.path.abspath(__file__))

    uid = mockplan.schedule(
        target="get_mtest",
        module="func_pool_base_tasks",
        path=dirname,
        kwargs=dict(name="0"),
        resource=pool_name,
        uid=uid,
        rerun=rerun_limit,
    )

    res = mockplan.run()

    assert (
        len(
            [
                worker
                for worker in mockplan.resources[pool_uid]._workers
                if worker._aborted is True
            ]
        )
        == 0
    )

    assert res.success is True
    assert mockplan.report.status == Status.PASSED
    assert pool.added_item(uid).reassign_cnt == 0
Esempio n. 4
0
def test_kill_all_workers(mockplan):
    """Kill all workers and create a failed report."""
    pool_name = ProcessPool.__name__
    pool_size = 4
    retries_limit = 3
    pool = ProcessPool(
        name=pool_name,
        size=pool_size,
        worker_heartbeat=2,
        heartbeats_miss_limit=2,
        max_active_loop_sleep=1,
        restart_count=0,
    )
    pool._task_retries_limit = retries_limit
    pool_uid = mockplan.add_resource(pool)

    dirname = os.path.dirname(os.path.abspath(__file__))

    uid = mockplan.schedule(
        target="multitest_kill_workers",
        module="func_pool_base_tasks",
        path=dirname,
        args=(os.getpid(),),
        resource=pool_name,
    )

    res = mockplan.run()

    # Check that the worker killed by test was aborted
    assert (
        len(
            [
                worker
                for worker in mockplan.resources[pool_uid]._workers
                if worker._aborted is True
            ]
        )
        == pool_size
    )

    assert res.success is False
    # scheduled X times and killed all workers
    assert pool._task_retries_cnt[uid] == retries_limit + 1
    assert mockplan.report.status == Status.ERROR
Esempio n. 5
0
def test_serialization(mockplan):
    """Test serialization of test results."""
    pool = ProcessPool(name="ProcPool", size=2)
    mockplan.add_resource(pool)
    mockplan.schedule(
        target="make_serialization_mtest",
        module="test_pool_process",
        path=os.path.dirname(__file__),
        resource="ProcPool",
    )
    res = mockplan.run()
    assert res.success
Esempio n. 6
0
def test_kill_one_worker(mockplan):
    """Kill one worker but pass after reassigning task."""
    pool_name = ProcessPool.__name__
    pool_size = 4
    pool = ProcessPool(
        name=pool_name,
        size=pool_size,
        worker_heartbeat=2,
        heartbeats_miss_limit=2,
        max_active_loop_sleep=1,
        restart_count=0,
    )
    pool_uid = mockplan.add_resource(pool)

    dirname = os.path.dirname(os.path.abspath(__file__))

    kill_uid = mockplan.schedule(
        target="multitest_kill_one_worker",
        module="func_pool_base_tasks",
        path=dirname,
        args=(os.getpid(), pool_size),  # kills 4th worker
        resource=pool_name,
    )

    uids = []
    for idx in range(1, 25):
        uids.append(
            mockplan.schedule(
                target="get_mtest",
                module="func_pool_base_tasks",
                path=dirname,
                kwargs=dict(name=idx),
                resource=pool_name,
            ))

    res = mockplan.run()

    # Check that the worker killed by test was aborted
    assert (len([
        worker for worker in mockplan.resources[pool_uid]._workers
        if worker._aborted is True
    ]) == 1)

    assert res.run is True
    assert res.success is True
    assert mockplan.report.status == Status.PASSED

    # All tasks scheduled once except the killed one
    for idx in range(1, 25):
        if uids[idx - 1] == kill_uid:
            assert pool._task_retries_cnt[uids[idx - 1]] == 1
Esempio n. 7
0
def main(plan):
    """
    Testplan decorated main function to add and execute MultiTests.

    :return: Testplan result object.
    :rtype:  ``testplan.base.TestplanResult``
    """
    # Add a process pool test execution resource to the plan of given size.
    # Also you can use thread pool or remote pool instead.
    pool = ProcessPool(name="MyPool")
    plan.add_resource(pool)

    # Create task objects from all @task_target we could find in the modules
    # that matches the name pattern under the specified path, and schedule them
    # to MyPool.

    plan.schedule_all(path=".",
                      name_pattern=r".*tasks\.py$",
                      resource="MyPool")
Esempio n. 8
0
def main(plan):
    """
    Testplan decorated main function to add and execute MultiTests.

    :return: Testplan result object.
    :rtype:  ``testplan.base.TestplanResult``
    """
    # Add a process pool test execution resource to the plan of given size.
    pool = ProcessPool(name="MyPool", size=plan.args.pool_size)
    plan.add_resource(pool)

    # Add a given number of similar tests to the process pool
    # to be executed in parallel.
    for idx in range(plan.args.tasks_num):
        # All Task arguments need to be serializable.
        task = Task(target="make_multitest",
                    module="tasks",
                    kwargs={"index": idx})
        plan.schedule(task, resource="MyPool")
Esempio n. 9
0
def test_task_rerun_in_process_pool(mockplan):
    """
    Test 1 procedure:
      - 1st run: `unstable_case` fails.
      - 1st rerun: `mock_driver` raises during stop.
      - 2nd rerun: all pass.
    Test 2 procedure:
      - 1st run: `unstable_worker` makes child process exit.
      - monitor detects inactive worker, decommission the task from worker,
        then re-assign it and it passes (no rerun is needed).
    """
    pool_name = ProcessPool.__name__
    pool = ProcessPool(name=pool_name, size=2)
    mockplan.add_resource(pool)

    tmp_file_1 = os.path.join(tempfile.gettempdir(), getpass.getuser(),
                              "{}.tmp".format(uuid.uuid4()))
    tmp_file_2 = os.path.join(tempfile.gettempdir(), getpass.getuser(),
                              "{}.tmp".format(uuid.uuid4()))
    task1 = Task(target=make_multitest_1, args=(tmp_file_1, ), rerun=2)
    task2 = Task(target=make_multitest_2, args=(tmp_file_2, ), rerun=0)
    uid1 = mockplan.schedule(task=task1, resource=pool_name)
    uid2 = mockplan.schedule(task=task2, resource=pool_name)

    assert mockplan.run().run is True
    assert mockplan.report.passed is True
    assert mockplan.report.counter == {"passed": 5, "total": 5, "failed": 0}

    assert isinstance(mockplan.report.serialize(), dict)
    assert mockplan.result.test_results[uid1].report.name == "Unstable MTest1"
    assert mockplan.result.test_results[uid2].report.name == "Unstable MTest2"
    assert len(mockplan.report.entries) == 4
    assert mockplan.report.entries[-1].category == ReportCategories.TASK_RERUN
    assert mockplan.report.entries[-2].category == ReportCategories.TASK_RERUN

    assert task1.reassign_cnt == 2
    assert task2.reassign_cnt == 0  # 1st run: assigned but not executed
    assert pool._task_retries_cnt[uid2] == 1
    _remove_existing_tmp_file(tmp_file_1)
    _remove_existing_tmp_file(tmp_file_2)
Esempio n. 10
0
def test_process_pool_integration(
    runpath,
    fixture_dirname,
    expected_report,
    pdf_title,
    expected_plan_result,
    dependant_module,
):
    if dependant_module:
        importorxfail(dependant_module)

    pool = ProcessPool(name="MyProcessPool", size=1)
    pdf_path = os.path.join(runpath,
                            "test_report_local_{}.pdf".format(pdf_title))

    plan = TestplanMock(
        name="plan",
        exporters=[PDFExporter(pdf_path=pdf_path)],
        runpath=runpath,
    )
    plan.add_resource(pool)

    runners_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    fixture_path = os.path.join(runners_path, "fixtures", fixture_dirname)

    task = Task(target="make_multitest", module="suites", path=fixture_path)
    plan.schedule(task, resource="MyProcessPool")

    assert not os.path.exists(pdf_path)
    assert plan.run().run is True

    for log in plan.report.flattened_logs:
        if all(word in log["message"] for word in ["tkinter", "TclError"]):
            pytest.xfail(reason="Tkinter not installed properly")

    check_report(expected=expected_report, actual=plan.report)

    assert plan.result.success is expected_plan_result
    assert os.path.exists(pdf_path)
    assert os.stat(pdf_path).st_size > 0