def test_allocations_generate_metrics(tasks_allocations, expected_metrics):
    """Check that proper allocations metrics are generated. """
    containers = {task('/t1'): container('/t1'),
                  task('/t2'): container('/t2'),
                  }
    platform_mock.rdt_information.rdt_mb_control_enabled = True
    allocations_values = TasksAllocationsValues.create(
        True, tasks_allocations, containers, platform_mock)
    allocations_values.validate()
    metrics_got = allocations_values.generate_metrics()
    assert metrics_got == expected_metrics
def test_convert_invalid_task_allocations(tasks_allocations, expected_error):
    """After allocations are converted, check that for improper input values
    proper validation exception with appropriate message is raised."""
    containers = {task('/t1'): container('/t1'),
                  task('/t2'): container('/t2'),
                  task('/t3'): container('/t3'),
                  }
    with pytest.raises(InvalidAllocations, match=expected_error):
        got_allocations_values = TasksAllocationsValues.create(
            True, tasks_allocations, containers, platform_mock)
        got_allocations_values.validate()
def test_unique_rdt_allocations(tasks_allocations, expected_resgroup_reallocation_count):
    """Checks if allocation of resctrl group is performed only once if more than one
       task_allocations has RDTAllocation with the same name. In other words,
       check if unnecessary reallocation of resctrl group does not take place.

       The goal is achieved by checking how many times
       Container.write_schemata is called with allocate_rdt=True."""
    containers = {task('/t1'): container('/t1', resgroup_name='', with_config=True),
                  task('/t2'): container('/t2', resgroup_name='', with_config=True)}
    allocations_values = TasksAllocationsValues.create(
        True, tasks_allocations, containers, platform_mock)
    allocations_values.validate()
    with patch('wca.resctrl.ResGroup.write_schemata') as mock, \
            patch('wca.cgroups.Cgroup._write'), patch('wca.cgroups.Cgroup._read'):
        allocations_values.perform_allocations()
        assert mock.call_count == expected_resgroup_reallocation_count
Esempio n. 4
0
def test_containerset_get_measurements(resgroup_mock, perfcounter_mock, cgroup_mock):
    """Check whether summing of metrics for children containers are done properly.
       Note: because we are mocking here classes from which measurements are read,
       to calculate the proper value of ContainerSet we just need to multiple that
       single value by count of subcontainers (here defined as N)."""
    N = 3  # 3 subcontainers are created.
    subcgroups_paths = ['/t1/c1', '/t1/c2', '/t1/c3']
    containerset = container('/t1', subcgroups_paths, should_patch=False, rdt_enabled=True)

    containerset.set_resgroup(resgroup=resgroup_mock)

    # Call the main function.
    measurements = containerset.get_measurements()

    resgroup_mock.get_measurements.assert_called_once()
    assert {'foo': 3, 'cgroup_metric__1': _ANY_METRIC_VALUE * N,
            'perf_event_metric__1': _ANY_METRIC_VALUE * N} == measurements
Esempio n. 5
0
def test_containerset_get_allocations(*mock):
    c = container("/t1", ['/t1/s1', '/t1/s2'], rdt_enabled=True, resgroup_name='t1')
    assert c.get_allocations() == {}
Esempio n. 6
0
def test_containerset_get_pids(*args):
    subcgroups_paths = ['/t1/c1', '/t1/c2', '/t1/c3']
    containerset = container('/t1', subcgroups_paths)
    # We expect 6 consecutive numbers starting from 1 - as there are 3 subcgroups paths
    # for the container.
    assert containerset.get_pids() == [str(i) for i in range(1, 7)]
Esempio n. 7
0
def test_sync_containers_state(_, get_pids_mock, sync_mock, perf_counters_mock,
                               add_pids_mock, clean_taskless_groups_mock,
                               subcgroups,
                               tasks_, pre_running_containers_,
                               mon_groups_relation, expected_running_containers_,
                               labels_relation_, pre_running_labels_relation_):
    """Tests both Container and ContainerSet classes.

        Note: the input arguments tasks_, existing_containers_, expected_running_containers_
        contain in their names underscore at the end to distinguish them from the ones
        created inside the function body to emphasize the relationship: the input arguments
        is used to create real objects. We cannot pass already created objects, as to
        create them we need another argument from first of two paramatrize decorators:
        subcgroups.

        Note: we have three variables names with the same postfix:
        * pre_running_containers - state of ContainerManager before (pre) call sync_containers_state
        * expected_running_containers - similar as above but state expected after the call,
        * got_running_containers - similar as above but state which we got after the call.
        All of three are of the same type Dict[Task, ContainerInterface].
        """
    # Create Task and Container/ContainerSet objects from input arguments.
    #   This is done to both test Container and ContainerSet classes (to pass
    #   subcgroups argument into the constructing function >>container<<.
    tasks = [task(t, subcgroups_paths=subcgroups, labels=labels_relation_.get(t)) for t in tasks_]
    pre_running_containers = \
        {task(t, subcgroups_paths=subcgroups,
              labels=pre_running_labels_relation_.get(t)): container(c, subcgroups)
         for t, c in pre_running_containers_.items()}

    expected_running_containers = \
        {task(t, subcgroups_paths=subcgroups,
              labels=labels_relation_.get(t)): container(c, subcgroups)
         for t, c in expected_running_containers_.items()}

    rdt_information = RDTInformation(True, True, True, True, 'fff', '1', 0, 0, 0)
    platform_mock = Mock(
        spec=Platform,
        sockets=1,
        cores=1,
        cpus=1,
        rdt_information=rdt_information)

    containers_manager = ContainerManager(platform=platform_mock,
                                          allocation_configuration=AllocationConfiguration(),
                                          event_names=[],
                                          )
    # Put in into ContainerManager our input dict of containers.
    containers_manager.containers = dict(pre_running_containers)

    # Call sync_containers_state
    with patch('wca.resctrl.read_mon_groups_relation', return_value=mon_groups_relation):
        got_running_containers = containers_manager.sync_containers_state(tasks)

    # -----------------------
    # Assert that two sets of keys of two dictionaries got_containers and
    # expected_running_containers are equal.
    assert len(got_running_containers) == len(expected_running_containers)
    assert all([expected_task in got_running_containers
                for expected_task in expected_running_containers.keys()])
    for t in expected_running_containers.keys():
        assert_equal_containers(expected_running_containers[t], got_running_containers[t])

    # Check container objects has proper resgroup assigned.
    got_container_resgroup_names = {c.get_name():
                                    c.get_resgroup().name for c in got_running_containers.values()}
    for expected_resgroup_name, container_names in mon_groups_relation.items():
        for container_name in container_names:
            if container_name in got_container_resgroup_names:
                got_resgroup_name = got_container_resgroup_names.get(container_name)
                assert got_resgroup_name == expected_resgroup_name
Esempio n. 8
0
       One special assumption is made about private attribute of
       ContainerSet: that field _subcontainers exists with type
       Dict[str, Container]."""
    assert len(containers_a) == len(containers_b)
    for a, b in zip(containers_a, containers_b):
        assert_equal_containers(a, b)


@pytest.mark.parametrize(
    'discovered_tasks, containers, '
    'expected_new_tasks, expected_containers_to_delete', (
        # 1) One new task (t1) was discovered - before there was no containers.
        ([task('/t1')], [],
         [task('/t1')], []),
        # 2) No changes in environment - no actions are expected.
        ([task('/t1')], [container('/t1')],
         [], []),
        # 3) One new task (t2) was discovered.
        ([task('/t1'), task('/t2')], [container('/t1')],
         [task('/t2')], []),
        # 4) No changes in environment - no actions are expected
        #    (but now two containers already are running).
        ([task('/t1'), task('/t2')], [container('/t1'), container('/t2')],
         [], []),
        # 5) First task just disappeared - corresponding container should be removed.
        ([task('/t2')], [container('/t1'), container('/t2')],
         [], [container('/t1')]),
        # 6) Two new task were discovered.
        ([task('/t1'), task('/t2')], [],
         [task('/t1'), task('/t2')], []),
        # 7) New task was discovered and one task disappeared.