Completed
Push — master ( 922c4e...42fcf2 )
by Björn
13s queued 11s
created

ScriptUtilsTestCase.test_create_xml_tree_invalid_file()   A

Complexity

Conditions 3

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2020 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 unittest
20
from unittest.mock import patch, MagicMock
21
from io import BytesIO
22
from pathlib import Path
23
from lxml import etree
24
from gvm.errors import GvmError
25
from gvmtools.helper import (
26
    Table,
27
    do_not_run_as_root,
28
    authenticate,
29
    run_script,
30
    create_xml_tree,
31
    error_and_exit,
32
    yes_or_no,
33
)
34
35
CWD = Path(__file__).absolute().parent
36
37
38
class TableTestCase(unittest.TestCase):
39
    def setUp(self):
40
        self.heading = ['ID', 'Name', 'Severity']
41
        self.rows = [
42
            ['1', 'foobar', 'high'],
43
            ['2', 'bla', 'low'],
44
            ['3', 'blub', 'medium'],
45
        ]
46
        self.divider = ' - '
47
48
        self.table = Table(
49
            heading=self.heading, rows=self.rows, divider=self.divider
50
        )
51
52
    def test_init_no_args(self):
53
        table = Table()
54
55
        self.assertListEqual(table.heading, [])
56
        self.assertListEqual(table.rows, [])
57
        self.assertEqual(table.divider, ' | ')
58
59
    def test_init_with_args(self):
60
        self.assertListEqual(self.table.heading, self.heading)
61
        self.assertListEqual(self.table.rows, self.rows)
62
        self.assertEqual(self.table.divider, self.divider)
63
64
    def test_calculate_dimensions(self):
65
        expected_result = [
66
            len(self.heading[0]),
67
            len(self.rows[0][1]),
68
            len(self.heading[2]),
69
        ]
70
71
        column_sizes = (
72
            self.table._calculate_dimensions()  # pylint: disable=protected-access
73
        )
74
75
        self.assertEqual(column_sizes, expected_result)
76
77
    def test_create_column(self):
78
        column = 'foobar'
79
        size = 20
80
        expected = 'foobar              '
81
82
        result = self.table._create_column(  # pylint: disable=protected-access
83
            column, size
84
        )
85
86
        self.assertEqual(result, expected)
87
88
    def test_create_row(self):
89
        columns = ['foo', 'bar', 'blub']
90
        expected = self.divider.join(columns)
91
92
        result = self.table._create_row(columns)  # pylint: disable=W0212
93
94
        self.assertEqual(result, expected)
95
96
    def test_str(self):
97
        expected = (
98
            'ID - Name   - Severity\n'
99
            + '-- - ------ - --------\n'
100
            + '1  - foobar - high    \n'
101
            + '2  - bla    - low     \n'
102
            + '3  - blub   - medium  '
103
        )
104
105
        self.assertEqual(str(self.table), expected)
106
107
108
class DoNotRunAsRootTestCase(unittest.TestCase):
109
    @patch('gvmtools.helper.os')
110
    def test_do_not_run_as_root_as_root(self, mock_os):
111
        mock_os.geteuid = MagicMock(spec='geteuid')
112
        mock_os.geteuid.return_value = 0
113
114
        self.assertRaises(RuntimeError, do_not_run_as_root)
115
116
    @patch('gvmtools.helper.os')
117
    def test_do_not_run_as_root_as_non_root(self, mock_os):
118
        mock_os.geteuid = MagicMock(spec='geteuid')
119
        mock_os.geteuid.return_value = 123
120
121
        self.assertIsNone(do_not_run_as_root())
122
123
124
class AuthenticateTestCase(unittest.TestCase):
125
    def test_authenticate_already_authenticated(self):
126
        mock_gmp = self.create_gmp_mock(True)
127
128
        self.assertIsNone(authenticate(mock_gmp))
129
130
    @patch('gvmtools.helper.input', return_value='foo')
131
    def test_authenticate_username_is_none(
132
        self, mock_input
133
    ):  # pylint: disable=unused-argument,line-too-long
134
        mock_gmp = self.create_gmp_mock(False)
135
136
        return_value = authenticate(mock_gmp, password='bar')
137
138
        self.assertTrue(isinstance(return_value, tuple))
139
        self.assertEqual(return_value[0], 'foo')
140
        self.assertEqual(return_value[1], 'bar')
141
142
    @patch('gvmtools.helper.getpass')
143
    def test_authenticate_password_is_none(self, mock_getpass):
144
        mock_gmp = self.create_gmp_mock(False)
145
        mock_getpass.getpass = MagicMock(return_value='SuperSecret123!')
146
147
        return_value = authenticate(mock_gmp, username='user')
148
149
        self.assertTrue(isinstance(return_value, tuple))
150
        self.assertEqual(return_value[0], 'user')
151
        self.assertEqual(return_value[1], 'SuperSecret123!')
152
153
    def test_authenticate(self):
154
        mock_gmp = self.create_gmp_mock(False)
155
156
        return_value = authenticate(
157
            mock_gmp, username='user', password='password'
158
        )
159
160
        self.assertTrue(isinstance(return_value, tuple))
161
        self.assertEqual(return_value[0], 'user')
162
        self.assertEqual(return_value[1], 'password')
163
164
    def test_authenticate_bad_credentials(self):
165
        mock_gmp = self.create_gmp_mock(False)
166
167
        def my_authenticate(username, password):
168
            raise GvmError('foo')
169
170
        mock_gmp.authenticate = my_authenticate
171
172
        self.assertRaises(GvmError, authenticate, mock_gmp, 'user', 'password')
173
174
    def create_gmp_mock(self, authenticated_return_value):
175
        mock_gmp = MagicMock()
176
        mock_gmp.is_authenticated = MagicMock(
177
            return_value=authenticated_return_value
178
        )
179
        return mock_gmp
180
181
182
class RunScriptTestCase(unittest.TestCase):
183
    @patch('gvmtools.helper.open')
184
    @patch('gvmtools.helper.exec')
185
    def test_run_script(self, mock_exec, mock_open):
186
        path = 'foo'
187
        global_vars = ['OpenVAS', 'is', 'awesome']
188
        mock_open().read.return_value = 'file content'
189
190
        run_script(path, global_vars)
191
192
        mock_open.assert_called_with(path, 'r', newline='')
193
        mock_exec.assert_called_with('file content', global_vars)
194
195
    @patch('gvmtools.helper.open')
196
    @patch('gvmtools.helper.print')
197
    def test_run_script_file_not_found(self, mock_print, mock_open):
198
        def my_open(path, mode, newline):
199
            raise FileNotFoundError
200
201
        mock_open.side_effect = my_open
202
203
        path = 'foo'
204
        global_vars = ['OpenVAS', 'is', 'awesome']
205
206
        with self.assertRaises(SystemExit):
207
            run_script(path, global_vars)
208
209
        mock_print.assert_called_with(
210
            'Script {path} does not exist'.format(path=path), file=sys.stderr
211
        )
212
213
214
class ScriptUtilsTestCase(unittest.TestCase):
215
    @patch('builtins.input', lambda *args: 'y')
216
    def test_yes(self):
217
        yes = yes_or_no('foo?')
218
        self.assertTrue(yes)
219
220
    @patch('builtins.input', lambda *args: 'n')
221
    def test_no(self):
222
        no = yes_or_no('bar?')
223
        self.assertFalse(no)
224
225
    def test_error_and_exit(self):
226
        with self.assertRaises(SystemExit):
227
            error_and_exit('foo')
228
229
    def test_create_xml_tree(self):
230
        tree = create_xml_tree(BytesIO(b'<foo><baz/><bar>glurp</bar></foo>'))
231
        self.assertIsInstance(
232
            tree, etree._Element  # pylint: disable=protected-access
233
        )
234
        self.assertEqual(tree.tag, 'foo')
235
236
    def test_create_xml_tree_invalid_file(self):
237
        target_xml_path = CWD / 'invalid_file.xml'
238
239
        with self.assertRaises(SystemExit):
240
            with self.assertRaises(OSError):
241
                create_xml_tree(str(target_xml_path))
242
243
    def test_create_xml_tree_invalid_xml(self):
244
        with self.assertRaises(SystemExit):
245
            with self.assertRaises(etree.Error):
246
                create_xml_tree(BytesIO(b'<foo><baz/><bar>glurp<bar></foo>'))
247