def test_calculates_secondary_period_when_initialized():
    planner = CyclicExecutivePlanner([Task('T1', 10, 5)])
    assert planner.secondary_period == 5
    planner = CyclicExecutivePlanner(
        [Task('T1', 20, 3),
         Task('T2', 5, 2),
         Task('T3', 10, 2)])
    assert planner.secondary_period == 3
    planner = CyclicExecutivePlanner(
        [Task('T1', 30, 6),
         Task('T2', 20, 3),
         Task('T3', 120, 14)])
    assert planner.secondary_period == 20
def test_get_plan_raises_exception_when_task_cannot_be_planned_correctly():
    # Case 1
    planner = CyclicExecutivePlanner(
        [Task('T1', 5, 2),
         Task('T2', 10, 5),
         Task('T3', 5, 1)])
    with pytest.raises(Exception):
        planner.get_plan()
    # Case 2
    planner = CyclicExecutivePlanner(
        [Task('T1', 6, 2),
         Task('T2', 4, 1),
         Task('T3', 10, 3)])
    with pytest.raises(Exception):
        planner.get_plan()
def test_validate_secondary_period_returns_false_when_not_full_frame_from_task_start_to_task_deadline_for_each_task(
):
    planner = CyclicExecutivePlanner(
        [Task('T1', 30, 6),
         Task('T2', 20, 3),
         Task('T3', 120, 14)])
    assert not planner.validate_secondary_period(15)
def test_validate_secondary_period_returns_false_when_provided_sp_is_negative(
):
    planner = CyclicExecutivePlanner(
        [Task('T1', 30, 6),
         Task('T2', 20, 3),
         Task('T3', 120, 14)])
    assert not planner.validate_secondary_period(-5)
def test_can_add_task_returns_true_when_task_can_fit_in_secondary_period_and_was_not_executed_in_this_deadline_slice(
):
    tasks = [Task('T1', 30, 6), Task('T2', 20, 3), Task('T3', 120, 14)]
    planner = CyclicExecutivePlanner(tasks)
    planner.matrix = ExecutionMatrix(planner.hyperperiod, planner.hyperperiod,
                                     planner.secondary_period)
    assert planner.can_add_task(tasks[0], 0)
def test_calculate_remaining_sp_space_returns_remaining_secondary_period_space_when_timestamp_provided(
):
    tasks = [Task('T1', 30, 6), Task('T2', 20, 3), Task('T3', 120, 14)]
    planner = CyclicExecutivePlanner(tasks)
    assert planner.calculate_remaining_sp_space(0) == 20
    assert planner.calculate_remaining_sp_space(1) == 19
    assert planner.calculate_remaining_sp_space(19) == 1
    assert planner.calculate_remaining_sp_space(20) == 20
    assert planner.calculate_remaining_sp_space(39) == 1
def test_can_add_task_returns_false_when_task_not_fit_in_secondary_period():
    tasks = [Task('T1', 30, 6), Task('T2', 20, 3), Task('T3', 120, 14)]
    planner = CyclicExecutivePlanner(tasks)
    planner.matrix = ExecutionMatrix(planner.hyperperiod, planner.hyperperiod,
                                     planner.secondary_period)
    time_stamp = 15
    for x in range(time_stamp):
        planner.matrix.processors[0].add_time_unit()
    assert not planner.can_add_task(tasks[0], time_stamp)
def test_hyperperiod_cyclic_executive_planner():

    tasks = list_of_tasks()
    processors = 1
    planner = CyclicExecutivePlanner(tasks=tasks, processors=processors)

    assert planner.tasks == tasks
    assert planner.processors == 1
    planner.calculate_hyperperiod()
    assert planner.hyperperiod == 120
def test_get_plan_returns_cyclic_executive_planified_matrix_when_tasks_are_valids(
):
    # Case 1
    planner = CyclicExecutivePlanner(
        [Task('T1', 5, 2),
         Task('T2', 10, 3),
         Task('T3', 5, 1)])
    matrix = planner.get_plan()
    expected = ['T1', 'T1', 'T3', 'T2', 'T2', 'T2', 'T1', 'T1', 'T3', '']
    compare_each_processor_value(expected, matrix.processors[0])
    # Case 2
    planner = CyclicExecutivePlanner(
        [Task('T1', 6, 2),
         Task('T2', 5, 1),
         Task('T3', 10, 2)])
    matrix = planner.get_plan()
    expected = [
        'T1', 'T1', 'T2', '', 'T3', 'T3', 'T1', 'T1', 'T2', '', 'T2', '', 'T1',
        'T1', 'T3', 'T3', 'T2', '', 'T1', 'T1', 'T2', '', 'T3', 'T3', 'T1',
        'T1', 'T2', '', '', ''
    ]
    compare_each_processor_value(expected, matrix.processors[0])
    # Case 3
    planner = CyclicExecutivePlanner(
        [Task('T1', 15, 3),
         Task('T2', 10, 2),
         Task('T3', 25, 5)])
    matrix = planner.get_plan()
    expected = [
        'T1', 'T1', 'T1', 'T2', 'T2', 'T3', 'T3', 'T3', 'T3', 'T3', 'T2', 'T2',
        '', '', '', 'T1', 'T1', 'T1', '', '', 'T2', 'T2', '', '', '', 'T3',
        'T3', 'T3', 'T3', 'T3', 'T1', 'T1', 'T1', 'T2', 'T2', '', '', '', '',
        '', 'T2', 'T2', '', '', '', 'T1', 'T1', 'T1', '', '', 'T2', 'T2', '',
        '', '', 'T3', 'T3', 'T3', 'T3', 'T3', 'T1', 'T1', 'T1', 'T2', 'T2', '',
        '', '', '', '', 'T2', 'T2', '', '', '', 'T1', 'T1', 'T1', '', '', 'T2',
        'T2', '', '', '', 'T3', 'T3', 'T3', 'T3', 'T3', 'T1', 'T1', 'T1', 'T2',
        'T2', '', '', '', '', '', 'T2', 'T2', '', '', '', 'T1', 'T1', 'T1', '',
        '', 'T2', 'T2', '', '', '', 'T3', 'T3', 'T3', 'T3', 'T3', 'T1', 'T1',
        'T1', 'T2', 'T2', 'T3', 'T3', 'T3', 'T3', 'T3', 'T2', 'T2', '', '', '',
        'T1', 'T1', 'T1', '', '', 'T2', 'T2', '', '', '', '', '', '', '', ''
    ]
    compare_each_processor_value(expected, matrix.processors[0])
def test_can_add_task_returns_false_when_task_was_already_enqueued_in_this_deadline_slice(
):
    tasks = [Task('T1', 30, 6), Task('T2', 20, 3), Task('T3', 120, 14)]
    planner = CyclicExecutivePlanner(tasks)
    planner.matrix = ExecutionMatrix(planner.hyperperiod, planner.hyperperiod,
                                     planner.secondary_period)
    planner.matrix.processors[0].add_time_unit()
    planner.matrix.processors[0].set_task(tasks[0])
    for x in range(tasks[0].deadline - 1):
        planner.matrix.processors[0].add_time_unit()
    assert not planner.can_add_task(tasks[0], planner.secondary_period + 1)
def test_planner_always_set_processors_in_one_when_initialized():
    planner = CyclicExecutivePlanner([Task('T1', 10, 5)], 5)
    assert planner.processors == 1
def test_initialization_trows_error_when_secondary_period_cannot_be_calculated(
):
    with pytest.raises(Exception):
        CyclicExecutivePlanner([Task('T1', 30, 60), Task('T2', 20, 3)])
def test_initialization_trows_error_when_tasks_is_empty():
    with pytest.raises(Exception):
        CyclicExecutivePlanner([])