File: test_rules_transformer.py

package info (click to toggle)
scap-security-guide 0.1.76-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 110,644 kB
  • sloc: xml: 241,883; sh: 73,777; python: 32,527; makefile: 27
file content (174 lines) | stat: -rw-r--r-- 5,606 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import os
import pytest
from typing import Any, Dict, List

from trestle.oscal.common import Property


from ssg.environment import open_environment
from ssg.products import product_yaml_path

from utils.oscal.params_extractor import ParameterExtractor, ParamInfo
from utils.oscal.rules_transformer import RulesTransformer, RuleInfo


DATADIR = os.path.join(os.path.dirname(__file__), "data")
TEST_ROOT = os.path.abspath(os.path.join(DATADIR, "test_root"))
TEST_BUILD_CONFIG = os.path.join(DATADIR, "build-config.yml")
TEST_RULE_JSON = os.path.join(DATADIR, "rule_dirs.json")
TEST_PRODUCT = "test_product"


@pytest.fixture(scope="function")
def env_yaml() -> Dict[str, Any]:
    """Return the environment yaml."""
    product_yaml = product_yaml_path(TEST_ROOT, TEST_PRODUCT)
    return open_environment(
        TEST_BUILD_CONFIG,
        product_yaml,
        os.path.join(TEST_ROOT, "product_properties"),
    )


@pytest.fixture(scope="function")
def test_rule_objs() -> List[RuleInfo]:
    """Create a set of test rules."""
    rule_with_parameter = RuleInfo(rule_id="rule_1", rule_dir="rule_dir")
    rule_with_parameter.add_description("Rule 1 description")
    test_parameter = ParamInfo(
        param_id="var_test",
        description="Test parameter",
    )
    test_parameter.set_selected_value("default")
    test_parameter.set_options({"default": "default", "alternate": "alternate"})
    rule_with_parameter.add_parameter(test_parameter)
    rule_with_no_parameter = RuleInfo(
        rule_id="rule_2",
        rule_dir="rule_dir",
    )
    rule_with_no_parameter.add_description("Rule 2 description")
    return [rule_with_parameter, rule_with_no_parameter]


def test_rule_transformer_load(env_yaml: Dict[str, Any]) -> None:
    """Test loading rules from a set of rules ids."""
    transformer = RulesTransformer(
        TEST_ROOT,
        env_yaml,
        TEST_RULE_JSON,
        ParameterExtractor(TEST_ROOT, env_yaml),
    )
    transformer.add_rules(["rule_1", "rule_2"])
    rule_objs = transformer.get_all_rules()

    assert len(rule_objs) == 2
    assert rule_objs[0].id == "rule_1"
    assert (
        rule_objs[0].description
        == "This is a rule with a template example. It has two lines."
    )
    assert rule_objs[0].parameters is not None
    assert rule_objs[0].parameters[0].id == "var_test"
    assert rule_objs[0].parameters[0].description == "This is a test variable."
    assert rule_objs[0].parameters[0].selected_value == "default"
    assert rule_objs[0].parameters[0].options == {
        "default": "default",
        "alt": "alternate",
    }
    assert rule_objs[1].id == "rule_2"
    assert rule_objs[1].description == "This is a rule with no template."
    assert not rule_objs[1].parameters


def test_rule_transformer_load_with_param(env_yaml: Dict[str, Any]) -> None:
    """Test loading rules from a set of rules ids with a parameter override."""
    transformer = RulesTransformer(
        TEST_ROOT,
        env_yaml,
        TEST_RULE_JSON,
        ParameterExtractor(TEST_ROOT, env_yaml),
    )
    transformer.add_rules(
        [
            "rule_1",
            "rule_2",
        ],
        {"var_test": "alternate"},
    )
    rule_objs = transformer.get_all_rules()

    assert len(rule_objs) == 2
    assert rule_objs[0].id == "rule_1"
    assert rule_objs[0].parameters is not None
    assert rule_objs[0].parameters[0].id == "var_test"
    assert rule_objs[0].parameters[0].selected_value == "alternate"
    assert rule_objs[1].id == "rule_2"
    assert not rule_objs[1].parameters


def test_rules_transformer_transform(
    test_rule_objs: List[RuleInfo], env_yaml: Dict[str, Any]
) -> None:
    """Test transforming a set of rules into properties."""
    transformer = RulesTransformer(
        TEST_ROOT,
        env_yaml,
        TEST_RULE_JSON,
        ParameterExtractor(TEST_ROOT, env_yaml),
    )
    props = transformer.transform(test_rule_objs)

    assert len(props) == 7

    # Verify there are two rule sets
    rulesets: Dict[str, List[Property]] = dict()
    for prop in props:
        if prop.remarks not in rulesets:
            rulesets[prop.remarks] = []  # type: ignore
        rulesets[prop.remarks].append(prop)  # type: ignore

    assert len(rulesets) == 2

    set1_props: List[Property] = next(
        (rulesets[ruleset] for ruleset in rulesets.keys() if ruleset == "rule_set_0"),
        [],
    )

    assert len(set1_props) == 5
    prop_names = [prop.name for prop in set1_props]
    expected_prop_names = [
        "Rule_Id",
        "Rule_Description",
        "Parameter_Id",
        "Parameter_Description",
        "Parameter_Value_Alternatives",
    ]
    assert sorted(prop_names) == sorted(expected_prop_names)
    prop_values = [prop.value for prop in set1_props]
    expected_prop_values = [
        "rule_1",
        "Rule 1 description",
        "var_test",
        "Test parameter",
        "{'default': 'default', 'alternate': 'alternate'}",
    ]
    assert sorted(prop_values) == sorted(expected_prop_values)

    set2_props: List[Property] = next(
        (rulesets[ruleset] for ruleset in rulesets.keys() if ruleset == "rule_set_1"),
        [],
    )

    assert len(set2_props) == 2
    prop_names = [prop.name for prop in set2_props]
    expected_prop_names = [
        "Rule_Id",
        "Rule_Description",
    ]
    assert sorted(prop_names) == sorted(expected_prop_names)
    prop_values = [prop.value for prop in set2_props]
    expected_prop_values = [
        "rule_2",
        "Rule 2 description",
    ]
    assert sorted(prop_values) == sorted(expected_prop_values)