test_interface   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 218
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 135
dl 0
loc 218
rs 10
c 0
b 0
f 0
wmc 20

15 Functions

Rating   Name   Duplication   Size   Complexity  
A service() 0 3 1
A object_publisher() 0 4 1
A interface() 0 3 1
A callback() 0 5 1
A test_policy_enabled() 0 6 1
A test_install_with_no_tasks() 0 3 1
A test_policy_data() 0 18 1
A test_no_requirements() 0 4 1
A test_configure_with_no_tasks() 0 3 1
A test_datastream_requirements() 0 17 1
A test_scap_security_guide_requirements() 0 19 1
A test_configure_with_tasks() 0 14 1
A test_default_requirements() 0 2 1
A test_cancel_tasks() 0 27 4
A test_install_with_tasks() 0 16 1

2 Methods

Rating   Name   Duplication   Size   Complexity  
A PropertiesChangedCallback.assert_call() 0 5 1
A PropertiesChangedCallback.__call__() 0 2 1
1
#
2
# Copyright (C) 2021  Red Hat, Inc.
3
#
4
# This copyrighted material is made available to anyone wishing to use,
5
# modify, copy, or redistribute it subject to the terms and conditions of
6
# the GNU General Public License v.2, or (at your option) any later version.
7
# This program is distributed in the hope that it will be useful, but WITHOUT
8
# ANY WARRANTY expressed or implied, including the implied warranties of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
10
# Public License for more details.  You should have received a copy of the
11
# GNU General Public License along with this program; if not, write to the
12
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
13
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
14
# source code or documentation are not subject to the GNU General Public
15
# License and may only be used or replicated with the express permission of
16
# Red Hat, Inc.
17
#
18
import pytest
19
20
from unittest.mock import Mock
21
from dasbus.typing import get_native, get_variant, Str
22
from pyanaconda.core.constants import REQUIREMENT_TYPE_PACKAGE
23
from pyanaconda.modules.common.containers import TaskContainer
24
from pyanaconda.modules.common.structures.requirement import Requirement
25
26
from org_fedora_oscap.constants import OSCAP
27
from org_fedora_oscap.service import installation
28
from org_fedora_oscap.service.oscap import OSCAPService
29
from org_fedora_oscap.service.oscap_interface import OSCAPInterface
30
from org_fedora_oscap.structures import PolicyData
31
32
33
class PropertiesChangedCallback(Mock):
34
35
    def __call__(self, interface, changed, invalid):
36
        return super().__call__(interface, get_native(changed), invalid)
37
38
    def assert_call(self, property_name, value):
39
        self.assert_called_once_with(
40
            OSCAP.interface_name,
41
            {property_name: get_native(value)},
42
            []
43
        )
44
45
46
@pytest.fixture()
47
def service():
48
    return OSCAPService()
49
50
51
@pytest.fixture()
52
def interface(service):
53
    return OSCAPInterface(service)
54
55
56
@pytest.fixture
57
def callback(interface):
58
    callback = PropertiesChangedCallback()
59
    interface.PropertiesChanged.connect(callback)
60
    return callback
61
62
63
@pytest.fixture(autouse=True)
64
def object_publisher(monkeypatch):
65
    # Mock any publishing of DBus objects.
66
    monkeypatch.setattr("pyanaconda.core.dbus.DBus.publish_object", Mock())
67
68
69
def test_policy_enabled(interface: OSCAPInterface, callback):
70
    policy_enabled = False
71
    interface.PolicyEnabled = policy_enabled
72
73
    callback.assert_call("PolicyEnabled", policy_enabled)
74
    assert interface.PolicyEnabled == policy_enabled
75
76
77
def test_policy_data(interface: OSCAPInterface, callback):
78
    policy_structure = {
79
        "content-type": get_variant(Str, "datastream"),
80
        "content-url": get_variant(Str, "https://example.com/hardening.xml"),
81
        "datastream-id": get_variant(Str, "id_datastream_1"),
82
        "xccdf-id": get_variant(Str, "id_xccdf_new"),
83
        "profile-id": get_variant(Str, "Web Server"),
84
        "content-path": get_variant(Str, "/usr/share/oscap/testing_ds.xml"),
85
        "cpe-path": get_variant(Str, "/usr/share/oscap/cpe.xml"),
86
        "tailoring-path": get_variant(Str, "/usr/share/oscap/tailoring.xml"),
87
        "fingerprint": get_variant(Str, "240f2f18222faa98856c3b4fc50c4195"),
88
        "certificates": get_variant(Str, "/usr/share/oscap/cacert.pem"),
89
        "remediate": get_variant(Str, "both"),
90
    }
91
    interface.PolicyData = policy_structure
92
93
    callback.assert_call("PolicyData", policy_structure)
94
    assert interface.PolicyData == policy_structure
95
96
97
def test_default_requirements(interface: OSCAPInterface):
98
    assert interface.CollectRequirements() == []
99
100
101
def test_no_requirements(service: OSCAPService, interface: OSCAPInterface):
102
    service.policy_enabled = True
103
    service.policy_data = PolicyData()
104
    assert interface.CollectRequirements() == []
105
106
107
def test_datastream_requirements(service: OSCAPService, interface: OSCAPInterface):
108
    data = PolicyData()
109
    data.content_type = "datastream"
110
    data.profile_id = "Web Server"
111
112
    service.policy_enabled = True
113
    service.policy_data = data
114
115
    requirements = Requirement.from_structure_list(
116
        interface.CollectRequirements()
117
    )
118
119
    assert len(requirements) == 2
120
    assert requirements[0].type == REQUIREMENT_TYPE_PACKAGE
121
    assert requirements[0].name == "openscap"
122
    assert requirements[1].type == REQUIREMENT_TYPE_PACKAGE
123
    assert requirements[1].name == "openscap-scanner"
124
125
126
def test_scap_security_guide_requirements(service: OSCAPService, interface: OSCAPInterface):
127
    data = PolicyData()
128
    data.content_type = "scap-security-guide"
129
    data.profile_id = "Web Server"
130
131
    service.policy_enabled = True
132
    service.policy_data = data
133
134
    requirements = Requirement.from_structure_list(
135
        interface.CollectRequirements()
136
    )
137
138
    assert len(requirements) == 3
139
    assert requirements[0].type == REQUIREMENT_TYPE_PACKAGE
140
    assert requirements[0].name == "openscap"
141
    assert requirements[1].type == REQUIREMENT_TYPE_PACKAGE
142
    assert requirements[1].name == "openscap-scanner"
143
    assert requirements[2].type == REQUIREMENT_TYPE_PACKAGE
144
    assert requirements[2].name == "scap-security-guide"
145
146
147
def test_configure_with_no_tasks(interface: OSCAPInterface):
148
    object_paths = interface.ConfigureWithTasks()
149
    assert len(object_paths) == 0
150
151
152
def test_configure_with_tasks(service: OSCAPService, interface: OSCAPInterface):
153
    data = PolicyData()
154
    data.content_type = "scap-security-guide"
155
    data.profile_id = "Web Server"
156
157
    service.policy_enabled = True
158
    service.policy_data = data
159
160
    object_paths = interface.ConfigureWithTasks()
161
    assert len(object_paths) == 2
162
163
    tasks = TaskContainer.from_object_path_list(object_paths)
164
    assert isinstance(tasks[0], installation.PrepareValidContent)
165
    assert isinstance(tasks[1], installation.EvaluateRulesTask)
166
167
168
def test_install_with_no_tasks(interface: OSCAPInterface):
169
    object_paths = interface.InstallWithTasks()
170
    assert len(object_paths) == 0
171
172
173
def test_install_with_tasks(service: OSCAPService, interface: OSCAPInterface):
174
    data = PolicyData()
175
    data.content_type = "scap-security-guide"
176
    data.profile_id = "Web Server"
177
    data.remediate = "both"
178
179
    service.policy_enabled = True
180
    service.policy_data = data
181
182
    object_paths = interface.InstallWithTasks()
183
    assert len(object_paths) == 3
184
185
    tasks = TaskContainer.from_object_path_list(object_paths)
186
    assert isinstance(tasks[0], installation.InstallContentTask)
187
    assert isinstance(tasks[1], installation.RemediateSystemTask)
188
    assert isinstance(tasks[2], installation.ScheduleFirstbootRemediationTask)
189
190
191
def test_cancel_tasks(service: OSCAPService):
192
    data = PolicyData()
193
    data.content_type = "scap-security-guide"
194
    data.profile_id = "Web Server"
195
196
    service.policy_enabled = True
197
    service.policy_data = data
198
199
    # Collect all tasks.
200
    tasks = service.configure_with_tasks() + service.install_with_tasks()
201
202
    # No task is canceled by default.
203
    for task in tasks:
204
        assert task.check_cancel() is False
205
206
    callback = Mock()
207
    service.installation_canceled.connect(callback)
208
209
    # The first task should fail with the given data.
210
    with pytest.raises(Exception):
211
        tasks[0].run_with_signals()
212
213
    # That should cancel all tasks.
214
    callback.assert_called_once()
215
216
    for task in tasks:
217
        assert task.check_cancel() is True
218