Completed
Push — master ( f4924a...c72d79 )
by Matěj
16s queued 13s
created

test_interface.test_default_requirements()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
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
    }
90
    interface.PolicyData = policy_structure
91
92
    callback.assert_call("PolicyData", policy_structure)
93
    assert interface.PolicyData == policy_structure
94
95
96
def test_default_requirements(interface: OSCAPInterface):
97
    assert interface.CollectRequirements() == []
98
99
100
def test_no_requirements(service: OSCAPService, interface: OSCAPInterface):
101
    service.policy_enabled = True
102
    service.policy_data = PolicyData()
103
    assert interface.CollectRequirements() == []
104
105
106
def test_datastream_requirements(service: OSCAPService, interface: OSCAPInterface):
107
    data = PolicyData()
108
    data.content_type = "datastream"
109
    data.profile_id = "Web Server"
110
111
    service.policy_enabled = True
112
    service.policy_data = data
113
114
    requirements = Requirement.from_structure_list(
115
        interface.CollectRequirements()
116
    )
117
118
    assert len(requirements) == 2
119
    assert requirements[0].type == REQUIREMENT_TYPE_PACKAGE
120
    assert requirements[0].name == "openscap"
121
    assert requirements[1].type == REQUIREMENT_TYPE_PACKAGE
122
    assert requirements[1].name == "openscap-scanner"
123
124
125
def test_scap_security_guide_requirements(service: OSCAPService, interface: OSCAPInterface):
126
    data = PolicyData()
127
    data.content_type = "scap-security-guide"
128
    data.profile_id = "Web Server"
129
130
    service.policy_enabled = True
131
    service.policy_data = data
132
133
    requirements = Requirement.from_structure_list(
134
        interface.CollectRequirements()
135
    )
136
137
    assert len(requirements) == 3
138
    assert requirements[0].type == REQUIREMENT_TYPE_PACKAGE
139
    assert requirements[0].name == "openscap"
140
    assert requirements[1].type == REQUIREMENT_TYPE_PACKAGE
141
    assert requirements[1].name == "openscap-scanner"
142
    assert requirements[2].type == REQUIREMENT_TYPE_PACKAGE
143
    assert requirements[2].name == "scap-security-guide"
144
145
146
def test_configure_with_no_tasks(interface: OSCAPInterface):
147
    object_paths = interface.ConfigureWithTasks()
148
    assert len(object_paths) == 0
149
150
151
def test_configure_with_tasks(service: OSCAPService, interface: OSCAPInterface):
152
    data = PolicyData()
153
    data.content_type = "scap-security-guide"
154
    data.profile_id = "Web Server"
155
156
    service.policy_enabled = True
157
    service.policy_data = data
158
159
    object_paths = interface.ConfigureWithTasks()
160
    assert len(object_paths) == 3
161
162
    tasks = TaskContainer.from_object_path_list(object_paths)
163
    assert isinstance(tasks[0], installation.FetchContentTask)
164
    assert isinstance(tasks[1], installation.CheckFingerprintTask)
165
    assert isinstance(tasks[2], 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
178
    service.policy_enabled = True
179
    service.policy_data = data
180
181
    object_paths = interface.InstallWithTasks()
182
    assert len(object_paths) == 2
183
184
    tasks = TaskContainer.from_object_path_list(object_paths)
185
    assert isinstance(tasks[0], installation.InstallContentTask)
186
    assert isinstance(tasks[1], installation.RemediateSystemTask)
187
188
189
def test_cancel_tasks(service: OSCAPService):
190
    data = PolicyData()
191
    data.content_type = "scap-security-guide"
192
    data.profile_id = "Web Server"
193
194
    service.policy_enabled = True
195
    service.policy_data = data
196
197
    # Collect all tasks.
198
    tasks = service.configure_with_tasks() + service.install_with_tasks()
199
200
    # No task is canceled by default.
201
    for task in tasks:
202
        assert task.check_cancel() is False
203
204
    callback = Mock()
205
    service.installation_canceled.connect(callback)
206
207
    # The first task should fail with the given data.
208
    with pytest.raises(Exception):
209
        tasks[0].run_with_signals()
210
211
    # That should cancel all tasks.
212
    callback.assert_called_once()
213
214
    for task in tasks:
215
        assert task.check_cancel() is True
216