OpenvasCommandTestCase.test_stop_scan()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nop 3
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2014-2021 Greenbone Networks GmbH
3
#
4
# SPDX-License-Identifier: AGPL-3.0-or-later
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU Affero General Public License as
8
# published by the Free Software Foundation, either version 3 of the
9
# License, or (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU Affero General Public License for more details.
15
#
16
# You should have received a copy of the GNU Affero General Public License
17
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19
20
import subprocess
21
22
from unittest import TestCase
23
from unittest.mock import patch, MagicMock
24
25
import psutil
26
27
from ospd_openvas.openvas import Openvas
28
29
30
class OpenvasCommandTestCase(TestCase):
31
    @patch('ospd_openvas.openvas.subprocess.check_output')
32
    def test_get_version(self, mock_check_output: MagicMock):
33
        mock_check_output.return_value = b"OpenVAS 20.08"
34
35
        self.assertEqual(Openvas.get_version(), 'OpenVAS 20.08')
36
37
        mock_check_output.assert_called_with(
38
            ['openvas', '-V'], stderr=subprocess.STDOUT
39
        )
40
41
    @patch('ospd_openvas.openvas.subprocess.check_output')
42
    def test_get_version_not_found(self, mock_check_output: MagicMock):
43
        mock_check_output.return_value = b"Foo 20.08"
44
45
        self.assertIsNone(Openvas.get_version())
46
47
        mock_check_output.assert_called_with(
48
            ['openvas', '-V'], stderr=subprocess.STDOUT
49
        )
50
51
    @patch('ospd_openvas.openvas.subprocess.check_output')
52
    def test_get_version_with_error(self, mock_check_output: MagicMock):
53
        mock_check_output.side_effect = subprocess.SubprocessError('foo')
54
55
        self.assertIsNone(Openvas.get_version())
56
57
        mock_check_output.assert_called_with(
58
            ['openvas', '-V'], stderr=subprocess.STDOUT
59
        )
60
61
        mock_check_output.reset_mock()
62
        mock_check_output.side_effect = OSError('foo')
63
64
        self.assertIsNone(Openvas.get_version())
65
66
        mock_check_output.assert_called_with(
67
            ['openvas', '-V'], stderr=subprocess.STDOUT
68
        )
69
70
    @patch('ospd_openvas.openvas.subprocess.check_call')
71
    def test_check(self, mock_check_call: MagicMock):
72
        self.assertTrue(Openvas.check())
73
        mock_check_call.assert_called_with(
74
            ['openvas', '-V'], stdout=subprocess.DEVNULL
75
        )
76
77
    @patch('ospd_openvas.openvas.subprocess.check_call')
78
    def test_check_with_error(self, mock_check_call: MagicMock):
79
        mock_check_call.side_effect = subprocess.SubprocessError('foo')
80
81
        self.assertFalse(Openvas.check())
82
        mock_check_call.assert_called_with(
83
            ['openvas', '-V'], stdout=subprocess.DEVNULL
84
        )
85
86
        mock_check_call.reset_mock()
87
        mock_check_call.side_effect = OSError('foo')
88
89
        self.assertFalse(Openvas.check())
90
        mock_check_call.assert_called_with(
91
            ['openvas', '-V'], stdout=subprocess.DEVNULL
92
        )
93
94
    @patch('ospd_openvas.openvas.subprocess.check_call')
95
    def test_check_sudo(self, mock_check_call: MagicMock):
96
        self.assertTrue(Openvas.check_sudo())
97
        mock_check_call.assert_called_with(
98
            ['sudo', '-n', 'openvas', '-s'], stdout=subprocess.DEVNULL
99
        )
100
101
    @patch('ospd_openvas.openvas.subprocess.check_call')
102
    def test_check_sudo_with_error(self, mock_check_call: MagicMock):
103
        mock_check_call.side_effect = subprocess.SubprocessError('foo')
104
105
        self.assertFalse(Openvas.check_sudo())
106
        mock_check_call.assert_called_with(
107
            ['sudo', '-n', 'openvas', '-s'], stdout=subprocess.DEVNULL
108
        )
109
110
        mock_check_call.reset_mock()
111
        mock_check_call.side_effect = OSError('foo')
112
113
        self.assertFalse(Openvas.check_sudo())
114
        mock_check_call.assert_called_with(
115
            ['sudo', '-n', 'openvas', '-s'], stdout=subprocess.DEVNULL
116
        )
117
118
    @patch('ospd_openvas.openvas.logger')
119
    @patch('ospd_openvas.openvas.subprocess.check_call')
120
    def test_load_vts_into_redis(self, mock_check_call, mock_logger):
121
        Openvas.load_vts_into_redis()
122
123
        mock_check_call.assert_called_with(
124
            ['openvas', '--update-vt-info'], stdout=subprocess.DEVNULL
125
        )
126
127
        mock_logger.error.assert_not_called()
128
129
    @patch('ospd_openvas.openvas.logger')
130
    @patch('ospd_openvas.openvas.subprocess.check_call')
131
    def test_load_vts_into_redis_with_error(
132
        self, mock_check_call: MagicMock, mock_logger: MagicMock
133
    ):
134
        mock_check_call.side_effect = subprocess.SubprocessError('foo')
135
136
        Openvas.load_vts_into_redis()
137
138
        mock_check_call.assert_called_with(
139
            ['openvas', '--update-vt-info'], stdout=subprocess.DEVNULL
140
        )
141
142
        self.assertEqual(mock_logger.error.call_count, 1)
143
144
    @patch('ospd_openvas.openvas.logger')
145
    @patch('ospd_openvas.openvas.subprocess.check_output')
146
    def test_get_settings(
147
        self, mock_check_output: MagicMock, _mock_logger: MagicMock
148
    ):
149
        mock_check_output.return_value = (
150
            b'non_simult_ports = 22 \n plugins_folder = /foo/bar\nfoo = yes\n'
151
            b'bar=no\nipsum= \nlorem\n'
152
        )
153
154
        settings = Openvas.get_settings()
155
156
        mock_check_output.assert_called_with(['openvas', '-s'])
157
158
        self.assertEqual(settings['non_simult_ports'], '22')
159
        self.assertEqual(settings['plugins_folder'], '/foo/bar')
160
        self.assertEqual(settings['foo'], 1)
161
        self.assertEqual(settings['bar'], 0)
162
        self.assertFalse('ipsum' in settings)
163
        self.assertFalse('lorem' in settings)
164
165
    @patch('ospd_openvas.openvas.logger')
166
    @patch('ospd_openvas.openvas.subprocess.check_output')
167
    def test_get_settings_with_error(
168
        self, mock_check_output: MagicMock, _mock_logger: MagicMock
169
    ):
170
        mock_check_output.side_effect = subprocess.SubprocessError('foo')
171
172
        settings = Openvas.get_settings()
173
174
        mock_check_output.assert_called_with(['openvas', '-s'])
175
176
        self.assertFalse(settings)  # settings dict is empty
177
178
        mock_check_output.reset_mock()
179
180
        mock_check_output.side_effect = OSError('foo')
181
182
        settings = Openvas.get_settings()
183
184
        mock_check_output.assert_called_with(['openvas', '-s'])
185
186
        self.assertFalse(settings)  # settings dict is empty
187
188
        mock_check_output.reset_mock()
189
190
        # https://gehrcke.de/2015/12/how-to-raise-unicodedecodeerror-in-python-3/
191
        mock_check_output.side_effect = UnicodeDecodeError(
192
            'funnycodec', b'\x00\x00', 1, 2, 'This is just a fake reason!'
193
        )
194
195
        settings = Openvas.get_settings()
196
197
        mock_check_output.assert_called_with(['openvas', '-s'])
198
199
        self.assertFalse(settings)  # settings dict is empty
200
201
    @patch('ospd_openvas.openvas.psutil.Popen')
202
    def test_start_scan(self, mock_popen: MagicMock):
203
        proc = Openvas.start_scan('scan_1')
204
205
        mock_popen.assert_called_with(
206
            ['openvas', '--scan-start', 'scan_1'], shell=False
207
        )
208
209
        self.assertIsNotNone(proc)
210
211
    @patch('ospd_openvas.openvas.psutil.Popen')
212
    def test_start_scan_with_sudo(self, mock_popen: MagicMock):
213
        proc = Openvas.start_scan('scan_1', sudo=True)
214
215
        mock_popen.assert_called_with(
216
            ['sudo', '-n', 'openvas', '--scan-start', 'scan_1'], shell=False
217
        )
218
219
        self.assertIsNotNone(proc)
220
221
    @patch('ospd_openvas.openvas.psutil.Popen')
222
    def test_start_scan_with_niceness(self, mock_popen: MagicMock):
223
        proc = Openvas.start_scan('scan_1', niceness=4)
224
225
        mock_popen.assert_called_with(
226
            ['nice', '-n', 4, 'openvas', '--scan-start', 'scan_1'], shell=False
227
        )
228
229
        self.assertIsNotNone(proc)
230
231
    @patch('ospd_openvas.openvas.psutil.Popen')
232
    def test_start_scan_with_niceness_and_sudo(self, mock_popen: MagicMock):
233
        proc = Openvas.start_scan('scan_1', niceness=4, sudo=True)
234
235
        mock_popen.assert_called_with(
236
            [
237
                'nice',
238
                '-n',
239
                4,
240
                'sudo',
241
                '-n',
242
                'openvas',
243
                '--scan-start',
244
                'scan_1',
245
            ],
246
            shell=False,
247
        )
248
249
        self.assertIsNotNone(proc)
250
251
    @patch('ospd_openvas.openvas.logger')
252
    @patch('ospd_openvas.openvas.psutil.Popen')
253
    def test_start_scan_error(
254
        self, mock_popen: MagicMock, mock_logger: MagicMock
255
    ):
256
        mock_popen.side_effect = psutil.Error('foo')
257
258
        proc = Openvas.start_scan('scan_1')
259
260
        mock_popen.assert_called_with(
261
            ['openvas', '--scan-start', 'scan_1'], shell=False
262
        )
263
264
        self.assertIsNone(proc)
265
266
        self.assertEqual(mock_logger.warning.call_count, 1)
267
268
        mock_popen.reset_mock()
269
        mock_logger.reset_mock()
270
271
        mock_popen.side_effect = OSError('foo')
272
273
        proc = Openvas.start_scan('scan_1')
274
275
        mock_popen.assert_called_with(
276
            ['openvas', '--scan-start', 'scan_1'], shell=False
277
        )
278
279
        self.assertIsNone(proc)
280
281
        self.assertEqual(mock_logger.warning.call_count, 1)
282
283
    @patch('ospd_openvas.openvas.logger')
284
    @patch('ospd_openvas.openvas.subprocess.check_call')
285
    def test_stop_scan(
286
        self, mock_check_call: MagicMock, _mock_logger: MagicMock
287
    ):
288
        success = Openvas.stop_scan('scan_1')
289
290
        mock_check_call.assert_called_with(['openvas', '--scan-stop', 'scan_1'])
291
292
        self.assertTrue(success)
293
294
    @patch('ospd_openvas.openvas.logger')
295
    @patch('ospd_openvas.openvas.subprocess.check_call')
296
    def test_stop_scan_with_sudo(
297
        self, mock_check_call: MagicMock, _mock_logger: MagicMock
298
    ):
299
        success = Openvas.stop_scan('scan_1', sudo=True)
300
301
        mock_check_call.assert_called_with(
302
            ['sudo', '-n', 'openvas', '--scan-stop', 'scan_1']
303
        )
304
305
        self.assertTrue(success)
306
307
    @patch('ospd_openvas.openvas.logger')
308
    @patch('ospd_openvas.openvas.subprocess.check_call')
309
    def test_stop_scan_with_error(
310
        self, mock_check_call: MagicMock, mock_logger: MagicMock
311
    ):
312
        mock_check_call.side_effect = subprocess.SubprocessError('foo')
313
314
        success = Openvas.stop_scan('scan_1')
315
316
        mock_check_call.assert_called_with(['openvas', '--scan-stop', 'scan_1'])
317
318
        self.assertFalse(success)
319
320
        self.assertEqual(mock_logger.warning.call_count, 1)
321
322
        mock_check_call.reset_mock()
323
        mock_logger.reset_mock()
324
325
        mock_check_call.side_effect = OSError('foo')
326
327
        success = Openvas.stop_scan('scan_1')
328
329
        mock_check_call.assert_called_with(['openvas', '--scan-stop', 'scan_1'])
330
331
        self.assertFalse(success)
332
333
        self.assertEqual(mock_logger.warning.call_count, 1)
334