tests.test_helper   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 279
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 186
dl 0
loc 279
rs 9.6
c 0
b 0
f 0
wmc 35

26 Methods

Rating   Name   Duplication   Size   Complexity  
A TableTestCase.setUp() 0 11 1
A TableTestCase.test_create_row() 0 7 1
A TableTestCase.test_str() 0 10 1
A AuthenticateTestCase.test_authenticate() 0 10 1
A TableTestCase.test_calculate_dimensions() 0 12 1
A AuthenticateTestCase.create_gmp_mock() 0 6 1
A ScriptUtilsTestCase.test_create_xml_tree_invalid_file() 0 6 3
A AuthenticateTestCase.test_authenticate_bad_credentials() 0 9 1
A TableTestCase.test_init_with_args() 0 4 1
A ScriptUtilsTestCase.test_generate_uuid() 0 6 2
A ScriptUtilsTestCase.test_yes() 0 4 2
A AuthenticateTestCase.test_authenticate_password_is_none() 0 10 1
A ScriptUtilsTestCase.test_generate_id() 0 7 1
A RunScriptTestCase.test_run_script() 0 11 1
A DoNotRunAsRootTestCase.test_do_not_run_as_root_as_root() 0 6 1
A ScriptUtilsTestCase.test_create_xml_tree() 0 6 1
A DoNotRunAsRootTestCase.test_do_not_run_as_root_as_non_root() 0 6 1
A ScriptUtilsTestCase.test_no() 0 4 2
A AuthenticateTestCase.test_authenticate_already_authenticated() 0 4 1
A AuthenticateTestCase.test_authenticate_username_is_none() 0 11 1
A ScriptUtilsTestCase.test_error_and_exit() 0 3 2
A TableTestCase.test_init_no_args() 0 6 1
A ScriptUtilsTestCase.test_create_xml_tree_invalid_xml() 0 4 3
A RunScriptTestCase.test_run_script_file_not_found() 0 16 2
A TableTestCase.test_create_column() 0 10 1
A ScriptUtilsTestCase.test_generate_random_ips() 0 9 1
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2020-2021 Greenbone Networks GmbH
3
#
4
# SPDX-License-Identifier: GPL-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 General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (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 General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
import sys
19
import uuid
20
import unittest
21
import ipaddress
22
from unittest.mock import patch, MagicMock
23
from io import BytesIO
24
from pathlib import Path
25
from lxml import etree
26
27
from gvm.errors import GvmError
28
29
from gvmtools.helper import (
30
    Table,
31
    do_not_run_as_root,
32
    authenticate,
33
    run_script,
34
    generate_id,
35
    generate_random_ips,
36
    generate_uuid,
37
    create_xml_tree,
38
    error_and_exit,
39
    yes_or_no,
40
)
41
42
CWD = Path(__file__).absolute().parent
43
44
45
class TableTestCase(unittest.TestCase):
46
    def setUp(self):
47
        self.heading = ['ID', 'Name', 'Severity']
48
        self.rows = [
49
            ['1', 'foobar', 'high'],
50
            ['2', 'bla', 'low'],
51
            ['3', 'blub', 'medium'],
52
        ]
53
        self.divider = ' - '
54
55
        self.table = Table(
56
            heading=self.heading, rows=self.rows, divider=self.divider
57
        )
58
59
    def test_init_no_args(self):
60
        table = Table()
61
62
        self.assertListEqual(table.heading, [])
63
        self.assertListEqual(table.rows, [])
64
        self.assertEqual(table.divider, ' | ')
65
66
    def test_init_with_args(self):
67
        self.assertListEqual(self.table.heading, self.heading)
68
        self.assertListEqual(self.table.rows, self.rows)
69
        self.assertEqual(self.table.divider, self.divider)
70
71
    def test_calculate_dimensions(self):
72
        expected_result = [
73
            len(self.heading[0]),
74
            len(self.rows[0][1]),
75
            len(self.heading[2]),
76
        ]
77
78
        column_sizes = (
79
            self.table._calculate_dimensions()  # pylint: disable=protected-access
80
        )
81
82
        self.assertEqual(column_sizes, expected_result)
83
84
    def test_create_column(self):
85
        column = 'foobar'
86
        size = 20
87
        expected = 'foobar              '
88
89
        result = self.table._create_column(  # pylint: disable=protected-access
90
            column, size
91
        )
92
93
        self.assertEqual(result, expected)
94
95
    def test_create_row(self):
96
        columns = ['foo', 'bar', 'blub']
97
        expected = self.divider.join(columns)
98
99
        result = self.table._create_row(columns)  # pylint: disable=W0212
100
101
        self.assertEqual(result, expected)
102
103
    def test_str(self):
104
        expected = (
105
            'ID - Name   - Severity\n'
106
            + '-- - ------ - --------\n'
107
            + '1  - foobar - high    \n'
108
            + '2  - bla    - low     \n'
109
            + '3  - blub   - medium  '
110
        )
111
112
        self.assertEqual(str(self.table), expected)
113
114
115
class DoNotRunAsRootTestCase(unittest.TestCase):
116
    @patch('gvmtools.helper.os')
117
    def test_do_not_run_as_root_as_root(self, mock_os):
118
        mock_os.geteuid = MagicMock(spec='geteuid')
119
        mock_os.geteuid.return_value = 0
120
121
        self.assertRaises(RuntimeError, do_not_run_as_root)
122
123
    @patch('gvmtools.helper.os')
124
    def test_do_not_run_as_root_as_non_root(self, mock_os):
125
        mock_os.geteuid = MagicMock(spec='geteuid')
126
        mock_os.geteuid.return_value = 123
127
128
        self.assertIsNone(do_not_run_as_root())
129
130
131
class AuthenticateTestCase(unittest.TestCase):
132
    def test_authenticate_already_authenticated(self):
133
        mock_gmp = self.create_gmp_mock(True)
134
135
        self.assertIsNone(authenticate(mock_gmp))
136
137
    @patch('gvmtools.helper.input', return_value='foo')
138
    def test_authenticate_username_is_none(
139
        self, mock_input
140
    ):  # pylint: disable=unused-argument,line-too-long
141
        mock_gmp = self.create_gmp_mock(False)
142
143
        return_value = authenticate(mock_gmp, password='bar')
144
145
        self.assertTrue(isinstance(return_value, tuple))
146
        self.assertEqual(return_value[0], 'foo')
147
        self.assertEqual(return_value[1], 'bar')
148
149
    @patch('gvmtools.helper.getpass')
150
    def test_authenticate_password_is_none(self, mock_getpass):
151
        mock_gmp = self.create_gmp_mock(False)
152
        mock_getpass.getpass = MagicMock(return_value='SuperSecret123!')
153
154
        return_value = authenticate(mock_gmp, username='user')
155
156
        self.assertTrue(isinstance(return_value, tuple))
157
        self.assertEqual(return_value[0], 'user')
158
        self.assertEqual(return_value[1], 'SuperSecret123!')
159
160
    def test_authenticate(self):
161
        mock_gmp = self.create_gmp_mock(False)
162
163
        return_value = authenticate(
164
            mock_gmp, username='user', password='password'
165
        )
166
167
        self.assertTrue(isinstance(return_value, tuple))
168
        self.assertEqual(return_value[0], 'user')
169
        self.assertEqual(return_value[1], 'password')
170
171
    def test_authenticate_bad_credentials(self):
172
        mock_gmp = self.create_gmp_mock(False)
173
174
        def my_authenticate(username, password):
175
            raise GvmError('foo')
176
177
        mock_gmp.authenticate = my_authenticate
178
179
        self.assertRaises(GvmError, authenticate, mock_gmp, 'user', 'password')
180
181
    def create_gmp_mock(self, authenticated_return_value):
182
        mock_gmp = MagicMock()
183
        mock_gmp.is_authenticated = MagicMock(
184
            return_value=authenticated_return_value
185
        )
186
        return mock_gmp
187
188
189
class RunScriptTestCase(unittest.TestCase):
190
    @patch('gvmtools.helper.open')
191
    @patch('gvmtools.helper.exec')
192
    def test_run_script(self, mock_exec, mock_open):
193
        path = 'foo'
194
        global_vars = ['OpenVAS', 'is', 'awesome']
195
        mock_open().read.return_value = 'file content'
196
197
        run_script(path, global_vars)
198
199
        mock_open.assert_called_with(path, 'r', newline='')
200
        mock_exec.assert_called_with('file content', global_vars)
201
202
    @patch('gvmtools.helper.open')
203
    @patch('gvmtools.helper.print')
204
    def test_run_script_file_not_found(self, mock_print, mock_open):
205
        def my_open(path, mode, newline):
206
            raise FileNotFoundError
207
208
        mock_open.side_effect = my_open
209
210
        path = 'foo'
211
        global_vars = ['OpenVAS', 'is', 'awesome']
212
213
        with self.assertRaises(SystemExit):
214
            run_script(path, global_vars)
215
216
        mock_print.assert_called_with(
217
            'Script {path} does not exist'.format(path=path), file=sys.stderr
218
        )
219
220
221
class ScriptUtilsTestCase(unittest.TestCase):
222
    @patch('builtins.input', lambda *args: 'y')
223
    def test_yes(self):
224
        yes = yes_or_no('foo?')
225
        self.assertTrue(yes)
226
227
    @patch('builtins.input', lambda *args: 'n')
228
    def test_no(self):
229
        no = yes_or_no('bar?')
230
        self.assertFalse(no)
231
232
    def test_error_and_exit(self):
233
        with self.assertRaises(SystemExit):
234
            error_and_exit('foo')
235
236
    def test_create_xml_tree(self):
237
        tree = create_xml_tree(BytesIO(b'<foo><baz/><bar>glurp</bar></foo>'))
238
        self.assertIsInstance(
239
            tree, etree._Element  # pylint: disable=protected-access
240
        )
241
        self.assertEqual(tree.tag, 'foo')
242
243
    def test_create_xml_tree_invalid_file(self):
244
        target_xml_path = CWD / 'invalid_file.xml'
245
246
        with self.assertRaises(SystemExit):
247
            with self.assertRaises(OSError):
248
                create_xml_tree(str(target_xml_path))
249
250
    def test_create_xml_tree_invalid_xml(self):
251
        with self.assertRaises(SystemExit):
252
            with self.assertRaises(etree.Error):
253
                create_xml_tree(BytesIO(b'<foo><baz/><bar>glurp<bar></foo>'))
254
255
    def test_generate_uuid(self):
256
        random_uuid = generate_uuid()
257
        try:
258
            uuid.UUID(random_uuid, version=4)
259
        except (ValueError, TypeError, AttributeError):
260
            self.fail("No valid UUID.")
261
262
    def test_generate_id(self):
263
        random_id = generate_id(size=1, chars="a")
264
        self.assertEqual(random_id, 'a')
265
266
        random_id = generate_id(size=10)
267
        self.assertEqual(len(random_id), 10)
268
        self.assertTrue(random_id.isalnum())
269
270
    def test_generate_random_ips(self):
271
        random_ip = generate_random_ips(1)
272
        ip_addr = ipaddress.ip_address(random_ip[0])
273
        self.assertEqual(ip_addr.version, 4)
274
        self.assertEqual(str(ip_addr), random_ip[0])
275
276
        num = 10
277
        random_ips = generate_random_ips(num)
278
        self.assertEqual(len(random_ips), num)
279