Completed
Push — master ( 92689a...85289d )
by Björn
14s queued 11s
created

tests.scripts.test_create_consolidated_report   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 320
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 129
dl 0
loc 320
rs 10
c 0
b 0
f 0
wmc 18

7 Methods

Rating   Name   Duplication   Size   Complexity  
A CreateConsolidatedReportsTestCase.test_send_report() 0 42 1
C CreateConsolidatedReportsTestCase.test_parse_period() 0 46 9
A CreateConsolidatedReportsTestCase.setUp() 0 3 1
A CreateConsolidatedReportsTestCase.test_combine_reports() 0 108 4
A CreateConsolidatedReportsTestCase.test_get_last_reports_from_tasks() 0 47 1
A CreateConsolidatedReportsTestCase.test_generate_task_filter() 0 26 1
A CreateConsolidatedReportsTestCase.test_parse_tags() 0 8 1
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 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
19
20
import unittest
21
from datetime import date
22
23
from unittest.mock import patch
24
from pathlib import Path
25
from lxml import etree
26
from . import GmpMockFactory, load_script
27
28
CWD = Path(__file__).absolute().parent
29
30
31
class CreateConsolidatedReportsTestCase(unittest.TestCase):
32
    def setUp(self):
33
        self.create_consolidated_report = load_script(
34
            (CWD.parent.parent / 'scripts'), 'create-consolidated-report'
35
        )
36
37
    def test_parse_period(self):
38
        with self.assertRaises(SystemExit), self.assertRaises(ValueError):
39
            self.create_consolidated_report.parse_period(
40
                ["a/b/c", "2020/02/03"]
41
            )
42
43
        with self.assertRaises(SystemExit), self.assertRaises(ValueError):
44
            self.create_consolidated_report.parse_period(
45
                ["1/2/3/4", "2020/02/03"]
46
            )
47
48
        with self.assertRaises(SystemExit), self.assertRaises(ValueError):
49
            self.create_consolidated_report.parse_period(
50
                ["2020/02/03", "a/b/c"]
51
            )
52
53
        with self.assertRaises(SystemExit), self.assertRaises(ValueError):
54
            self.create_consolidated_report.parse_period(
55
                ["2020/02/03", "1/2/3/4"]
56
            )
57
58
        with self.assertRaises(SystemExit), self.assertRaises(ValueError):
59
            self.create_consolidated_report.parse_period(
60
                ["2020/20/03", "2001/2/3"]
61
            )
62
63
        with self.assertRaises(SystemExit), self.assertRaises(ValueError):
64
            self.create_consolidated_report.parse_period(
65
                ["2020/12/03", "2001/2/300"]
66
            )
67
68
        with self.assertRaises(SystemExit), self.assertRaises(ValueError):
69
            self.create_consolidated_report.parse_period(
70
                ["2020/12/03", "2001/22/30"]
71
            )
72
73
        with self.assertRaises(SystemExit), self.assertRaises(ValueError):
74
            self.create_consolidated_report.parse_period(
75
                ["2020/12/43", "2001/2/3"]
76
            )
77
78
        date1, date2 = self.create_consolidated_report.parse_period(
79
            ["1980/1/11", "2001/2/3"]
80
        )
81
        self.assertEqual(date1, date(1980, 1, 11))
82
        self.assertEqual(date2, date(2001, 2, 3))
83
84
    def test_parse_tags(self):
85
        tags = ['abc', 'dba8624e-a56c-4901-a3f2-591f062e4c20']
86
87
        filter_tags = self.create_consolidated_report.parse_tags(tags)
88
89
        self.assertEqual(filter_tags[0], 'tag="abc"')
90
        self.assertEqual(
91
            filter_tags[1], 'tag_id="dba8624e-a56c-4901-a3f2-591f062e4c20"'
92
        )
93
94
    def test_generate_task_filter(self):
95
        asserted_task_filter = (
96
            'rows=-1 created>2020-01-01 and created<2020-02-01 and tag="blah"'
97
        )
98
        period_start = date(2020, 1, 1)
99
        period_end = date(2020, 2, 1)
100
        tags = ['tag="blah"']
101
102
        task_filter = self.create_consolidated_report.generate_task_filter(
103
            period_start, period_end, tags
104
        )
105
106
        self.assertEqual(task_filter, asserted_task_filter)
107
108
        asserted_task_filter = (
109
            'rows=-1 created>2020-01-01 and created<2020-02-01 and '
110
            'tag="blah" or created>2020-01-01 and created<2020-02-01'
111
            ' and tag="blah2"'
112
        )
113
        tags = ['tag="blah"', 'tag="blah2"']
114
115
        task_filter = self.create_consolidated_report.generate_task_filter(
116
            period_start, period_end, tags
117
        )
118
119
        self.assertEqual(task_filter, asserted_task_filter)
120
121
    @patch('gvm.protocols.latest.Gmp', new_callable=GmpMockFactory)
122
    def test_get_last_reports_from_tasks(self, mock_gmp: GmpMockFactory):
123
        mock_gmp.mock_response(
124
            'get_tasks',
125
            '<get_tasks_response status="200" status_text="OK">'
126
            '  <apply_overrides>0</apply_overrides>'
127
            '  <task id="ef4469db-1cd7-4859-ba5f-45f72f49f09e">'
128
            '    <last_report>'
129
            '      <report id="4108fe11-91c8-4b7b-90da-854e3200af19">'
130
            '      </report>'
131
            '    </last_report>'
132
            '  </task>'
133
            '  <task id="bdd80dd6-9c7b-47b9-a87b-e2ca28fae2df">'
134
            '    <last_report>'
135
            '      <report id="55af942a-fa45-472c-aa50-f2af77d700a0">'
136
            '      </report>'
137
            '    </last_report>'
138
            '  </task>'
139
            '  <task id="6e5373cd-e69a-4008-afc3-a6d05e22507f">'
140
            '    <last_report>'
141
            '      <report id="52b67045-2c2c-4dbd-af58-ecf814d92f07">'
142
            '      </report>'
143
            '    </last_report>'
144
            '  </task>'
145
            '  <task id="bab515c2-156b-451f-9f1c-7af5b2c4b568">'
146
            '    <last_report>'
147
            '      <report id="52b67045-2c2c-4dbd-af58-ecf814d92f07">'
148
            '      </report>'
149
            '    </last_report>'
150
            '  </task>'
151
            '</get_tasks_response>',
152
        )
153
154
        reports = self.create_consolidated_report.get_last_reports_from_tasks(
155
            mock_gmp.gmp_protocol,
156
            task_filter=(
157
                'rows=-1 created>2020-01-01 and '
158
                'created<2020-02-01 and tag="blah"'
159
            ),
160
        )
161
162
        asserted_reports = [
163
            '4108fe11-91c8-4b7b-90da-854e3200af19',
164
            '55af942a-fa45-472c-aa50-f2af77d700a0',
165
            '52b67045-2c2c-4dbd-af58-ecf814d92f07',
166
        ]
167
        self.assertEqual(reports, asserted_reports)
168
169
    @patch('gvm.protocols.latest.Gmp', new_callable=GmpMockFactory)
170
    def test_combine_reports(self, mock_gmp: GmpMockFactory):
171
        reports = [
172
            '00000000-0000-0000-0000-000000000000',
173
            '00000000-0000-0000-0000-000000000001',
174
            '00000000-0000-0000-0000-000000000002',
175
        ]
176
177
        mock_gmp.mock_responses(
178
            'get_report',
179
            [
180
                '<get_reports_response status="200" status_text="OK">'
181
                '<report id="00000000-0000-0000-0000-000000000000">'
182
                '<name>2020-11-13T14:47:28Z</name>'
183
                '<creation_time>2020-11-13T14:47:28Z</creation_time>'
184
                '<modification_time>2020-11-13T14:47:28Z</modification_time>'
185
                '<task id="00000000-0000-0000-0001-000000000000">'
186
                '<name>Offline Scan from 2020-11-13T15:47:28+01:00 8</name>'
187
                '</task>'
188
                '<report id="00000000-0000-0000-0000-000000000000">'
189
                '<scan_run_status>Done</scan_run_status>'
190
                '<timestamp>2020-11-13T14:47:48Z</timestamp>'
191
                '<scan_start>2020-11-13T14:47:28Z</scan_start>'
192
                '<ports max="-1" start="1">'
193
                '<port>0<host>127.0.0.0</host></port>'
194
                '<port>1<host>127.0.0.1</host></port></ports>'
195
                '<results start="1" max="100">'
196
                '<result id="00000001-0000-0000-0000-000000000000">'
197
                '</result>'
198
                '<result id="00000001-0000-0000-0000-000000000001">'
199
                '</result></results>'
200
                '<scan_end>2020-11-13T14:47:28Z</scan_end>'
201
                '</report></report></get_reports_response>',
202
                '<get_reports_response status="200" status_text="OK">'
203
                '<report id="00000000-0000-0000-0000-000000000001">'
204
                '<name>2020-11-13T14:47:28Z</name>'
205
                '<creation_time>2020-11-13T14:47:28Z</creation_time>'
206
                '<modification_time>2020-11-13T14:47:28Z</modification_time>'
207
                '<task id="00000000-0000-0000-0002-000000000000">'
208
                '<name>Offline Scan from 2020-11-13T15:47:28+01:00 8</name>'
209
                '</task>'
210
                '<report id="00000000-0000-0000-0000-000000000001">'
211
                '<scan_run_status>Done</scan_run_status>'
212
                '<timestamp>2020-11-13T14:47:48Z</timestamp>'
213
                '<scan_start>2020-11-13T14:47:28Z</scan_start>'
214
                '<ports max="-1" start="1">'
215
                '<port>2<host>127.0.0.2</host></port>'
216
                '<port>3<host>127.0.0.3</host></port></ports>'
217
                '<results start="1" max="100">'
218
                '<result id="00000001-0000-0000-0000-000000000002"></result>'
219
                '<result id="00000001-0000-0000-0000-000000000003">'
220
                '</result></results>'
221
                '<scan_end>2020-11-13T14:47:28Z</scan_end>'
222
                '</report><host><ip>127.0.0.0</ip></host>'
223
                '</report></get_reports_response>',
224
                '<get_reports_response status="200" status_text="OK">'
225
                '<report id="00000000-0000-0000-0000-000000000002">'
226
                '<name>2020-11-13T14:47:28Z</name>'
227
                '<creation_time>2020-11-13T14:47:28Z</creation_time>'
228
                '<modification_time>2020-11-13T14:47:28Z</modification_time>'
229
                '<task id="00000000-0000-0000-0003-000000000000">'
230
                '<name>Offline Scan from 2020-11-13T15:47:28+01:00 8</name>'
231
                '</task>'
232
                '<report id="00000000-0000-0000-0000-000000000002">'
233
                '<scan_run_status>Done</scan_run_status>'
234
                '<timestamp>2020-11-13T14:47:48Z</timestamp>'
235
                '<scan_start>2020-11-13T14:47:28Z</scan_start>'
236
                '<results start="1" max="100">'
237
                '<result id="00000001-0000-0000-0000-000000000004">'
238
                '</result></results>'
239
                '<scan_end>2020-11-13T14:47:28Z</scan_end>'
240
                '</report><host><ip>127.0.0.1</ip></host>'
241
                '</report></get_reports_response>',
242
            ],
243
        )
244
245
        combined_report = self.create_consolidated_report.combine_reports(
246
            mock_gmp.gmp_protocol, reports, filter_term="foo"
247
        )
248
249
        ports = combined_report.find('report').find('ports').findall('port')
250
        i = 0
251
        for port in ports:
252
            self.assertEqual(port.text, f'{str(i)}')
253
            i += 1
254
255
        self.assertEqual(i, 4)
256
257
        results = (
258
            combined_report.find('report').find('results').findall('result')
259
        )
260
        i = 0
261
        for result in results:
262
            self.assertEqual(
263
                result.get('id'), f'00000001-0000-0000-0000-00000000000{str(i)}'
264
            )
265
            i += 1
266
267
        self.assertEqual(i, 5)
268
269
        hosts = combined_report.find('report').findall('host')
270
271
        i = 0
272
        for host in hosts:
273
            self.assertEqual(host.find('ip').text, f'127.0.0.{str(i)}')
274
            i += 1
275
276
        self.assertEqual(i, 2)
277
278
    @patch('gvm.protocols.latest.Gmp', new_callable=GmpMockFactory)
279
    def test_send_report(self, mock_gmp: GmpMockFactory):
280
281
        combined_report = etree.fromstring(
282
            '<report id="20574712-c404-4a04-9c83-03144ae02dca" '
283
            'format_id="d5da9f67-8551-4e51-807b-b6a873d70e34" '
284
            'extension="xml" content_type="text/xml">'
285
            '<report id="20574712-c404-4a04-9c83-03144ae02dca">'
286
            '<results start="1" max="-1">'
287
            '<result id="00000001-0000-0000-0000-000000000000"/>'
288
            '<result id="00000001-0000-0000-0000-000000000001"/>'
289
            '<result id="00000001-0000-0000-0000-000000000002"/>'
290
            '<result id="00000001-0000-0000-0000-000000000003"/>'
291
            '<result id="00000001-0000-0000-0000-000000000004"/>'
292
            '</results></report></report>'
293
        )
294
295
        report_id = '0e4d8fb2-47fa-494e-a242-d5327d3772f9'
296
297
        mock_gmp.mock_response(
298
            'import_report',
299
            '<create_report_response status="201" status_text="OK, '
300
            f'resource created" id="{report_id}"/>',
301
        )
302
303
        mock_gmp.mock_response(
304
            'create_container_task',
305
            '<create_task_response status="201" status_text="OK, '
306
            'resource created" id="6488ef71-e2d5-491f-95bd-ed9f915fa179"/>',
307
        )
308
309
        period_start = date(2020, 1, 1)
310
        period_end = date(2020, 2, 1)
311
312
        created_report_id = self.create_consolidated_report.send_report(
313
            gmp=mock_gmp.gmp_protocol,
314
            combined_report=combined_report,
315
            period_start=period_start,
316
            period_end=period_end,
317
        )
318
319
        self.assertEqual(report_id, created_report_id)
320