Test Failed
Pull Request — master (#84)
by
unknown
05:57
created

TestMain.test_update_mw_case_2()   A

Complexity

Conditions 1

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 10
nop 2
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 1
rs 9.9
c 0
b 0
f 0
1
"""Tests for the main madule."""
2
3 1
from unittest.mock import patch, call, MagicMock
4 1
from datetime import datetime, timedelta
5
6 1
import pytz
7 1
import pytest
8
9 1
from kytos.lib.helpers import get_controller_mock, get_test_client
10 1
from napps.kytos.maintenance.main import Main
11 1
from napps.kytos.maintenance.models import MaintenanceWindow as MW
12 1
from napps.kytos.maintenance.models import MaintenanceWindows
13
14 1
TIME_FMT = "%Y-%m-%dT%H:%M:%S%z"
15
16
17 1
class TestMain:
18
    """Test the Main class of this NApp."""
19
20
    # pylint: disable=too-many-public-methods
21
22 1
    def setup_method(self):
23
        """Initialize before tests are executed."""
24 1
        self.controller = get_controller_mock()
25 1
        self.controller.napps[("kytos", "topology")] = MagicMock()
26 1
        self.controller.switches = MagicMock()
27 1
        self.scheduler = MagicMock()
28 1
        new_sched = (
29 1
            "napps.kytos.maintenance.managers.MaintenanceScheduler.new_scheduler"
30 1
        )
31 1
        with patch(new_sched) as new_scheduler:
32 1
            new_scheduler.return_value = self.scheduler
33 1
            self.napp = Main(self.controller)
34 1
        self.api = get_test_client(self.controller, self.napp)
35
        self.maxDiff = None
36 1
        self.base_endpoint = "kytos/maintenance/v1"
37
38 1
    async def test_create_mw_case_1(self, event_loop):
39 1
        """Test a successful case of the REST to create."""
40 1
        self.napp.controller.loop = event_loop
41 1
        url = f"{self.base_endpoint}"
42 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
43
        end = start + timedelta(hours=2)
44
        self.controller.switches = MagicMock()
45
        self.controller.get_interface_by_id = MagicMock()
46
        self.controller.napps[("kytos", "topology")].links = MagicMock()
47
        switches = {"00:00:00:00:00:00:00:02": 1, "00:00:00:00:00:00:00:03": 2}
48
        interfaces = {"00:00:00:00:00:00:00:03:3": 1, "00:00:00:00:00:00:00:02:1": 2}
49
        links = {
50
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260": 1,
51
            "4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30": 2,
52 1
        }
53 1
        self.controller.switches.get.side_effect = switches.get
54 1
        get_interface_side_effect = lambda interface_id: interfaces.get(interface_id)
55 1
        self.controller.get_interface_by_id.side_effect = get_interface_side_effect
56 1
        self.controller.napps[("kytos", "topology")].links.get.side_effect = links.get
57
        payload = {
58 1
            "start": start.strftime(TIME_FMT),
59 1
            "end": end.strftime(TIME_FMT),
60 1
            "switches": ["00:00:00:00:00:00:00:02", "00:00:00:00:00:00:00:03"],
61 1
            "interfaces": ["00:00:00:00:00:00:00:03:3", "00:00:00:00:00:00:00:02:1"],
62 1
            "links": [
63
                "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260",
64 1
                "4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30",
65
            ],
66 1
        }
67
        response = await self.api.post(url, json=payload)
68 1
        current_data = response.json()
69 1
        assert response.status_code == 201, current_data
70 1
        switch_calls = [
71
            call("00:00:00:00:00:00:00:02"),
72
            call("00:00:00:00:00:00:00:03"),
73
        ]
74
        self.controller.switches.get.assert_has_calls(switch_calls)
75
        interface_calls = [
76
            call("00:00:00:00:00:00:00:03:3"),
77
            call("00:00:00:00:00:00:00:02:1"),
78 1
        ]
79 1
        self.controller.get_interface_by_id.assert_has_calls(interface_calls)
80 1
        link_calls = [
81
            call("cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260"),
82 1
            call("4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30"),
83
        ]
84 1
        self.controller.napps[("kytos", "topology")].links.get.assert_has_calls(
85 1
            link_calls
86 1
        )
87 1
        args, kwargs = self.scheduler.add.call_args
88 1
        window: MW = args[0]
89
90
        assert window.start == start.replace(microsecond=0)
91
        assert window.end == end.replace(microsecond=0)
92
        assert window.switches == ["00:00:00:00:00:00:00:02", "00:00:00:00:00:00:00:03"]
93
        assert window.interfaces == [
94
            "00:00:00:00:00:00:00:03:3",
95
            "00:00:00:00:00:00:00:02:1",
96
        ]
97
        assert window.links == [
98 1
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260",
99 1
            "4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30",
100 1
        ]
101 1
102
        assert current_data == {"mw_id": window.id}
103 1
104
    async def test_create_mw_case_2(self, event_loop):
105 1
        """Test a successful case of the REST to create."""
106
        self.napp.controller.loop = event_loop
107 1
        url = f"{self.base_endpoint}"
108 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
109 1
        end = start + timedelta(hours=2)
110 1
        self.controller.switches = MagicMock()
111 1
        switches = {"00:00:00:00:00:00:00:01": 1}
112
        self.controller.switches.get.side_effect = switches.get
113
        payload = {
114
            "start": start.strftime(TIME_FMT),
115
            "end": end.strftime(TIME_FMT),
116
            "switches": [
117
                "00:00:00:00:00:00:00:01",
118
            ],
119
        }
120
        response = await self.api.post(url, json=payload)
121 1
        current_data = response.json()
122 1
        assert response.status_code == 201, current_data
123
        self.controller.switches.get.assert_called_with("00:00:00:00:00:00:00:01")
124 1
        args, kwargs = self.scheduler.add.call_args
125 1
        window: MW = args[0]
126
127 1
        assert window.start == start.replace(microsecond=0)
128
        assert window.end == end.replace(microsecond=0)
129 1
        assert window.switches == ["00:00:00:00:00:00:00:01"]
130 1
        assert window.interfaces == []
131
        assert window.links == []
132
133
        assert current_data == {"mw_id": window.id}
134
135
    async def test_create_mw_case_3(self, event_loop):
136
        """Test a successful case of the REST to create."""
137
        self.napp.controller.loop = event_loop
138
        url = f"{self.base_endpoint}"
139
        start = datetime.now(pytz.utc) + timedelta(days=1)
140
        end = start + timedelta(hours=2)
141
        self.controller.get_interface_by_id = MagicMock()
142
        interfaces = {"00:00:00:00:00:00:00:01:1": 1}
143
        get_interface_side_effect = lambda interface_id: interfaces.get(interface_id)
144
        self.controller.get_interface_by_id.side_effect = get_interface_side_effect
145
        payload = {
146
            "id": "some_mw",
147
            "description": "some_mw",
148
            "start": start.strftime(TIME_FMT),
149
            "end": end.strftime(TIME_FMT),
150
            "interfaces": [
151
                "00:00:00:00:00:00:00:01:1",
152
            ],
153
        }
154
        response = await self.api.post(url, json=payload)
155 1
        current_data = response.json()
156
        assert response.status_code == 201, current_data
157 1
        self.controller.get_interface_by_id.assert_called_with(
158 1
            "00:00:00:00:00:00:00:01:1"
159 1
        )
160 1
        assert response.status_code == 201, current_data
161 1
        args, kwargs = self.scheduler.add.call_args
162
        response = await self.api.get(f"{url}/some_mw")
163
        window: MW = args[0]
164
165
        assert window.start == start.replace(microsecond=0)
166
        assert window.end == end.replace(microsecond=0)
167
        assert window.switches == []
168
        assert window.interfaces == ["00:00:00:00:00:00:00:01:1"]
169
        assert window.links == []
170
171
        assert current_data == {"mw_id": "some_mw"}
172 1
173 1
    async def test_create_mw_case_4(self, event_loop):
174
        """Test a successful case of the REST to create."""
175 1
        self.napp.controller.loop = event_loop
176 1
        url = f"{self.base_endpoint}"
177
        start = datetime.now(pytz.utc) + timedelta(days=1)
178 1
        end = start + timedelta(hours=2)
179
        self.controller.napps[("kytos", "topology")].links = MagicMock()
180 1
        links = {"cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260": 1}
181
        self.controller.napps[("kytos", "topology")].links.get.side_effect = links.get
182 1
        payload = {
183 1
            "start": start.strftime(TIME_FMT),
184 1
            "end": end.strftime(TIME_FMT),
185 1
            "links": [
186 1
                "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260",
187 1
            ],
188 1
        }
189
        response = await self.api.post(url, json=payload)
190 1
        current_data = response.json()
191
        assert response.status_code == 201, current_data
192 1
        self.controller.napps[("kytos", "topology")].links.get.assert_called_with(
193 1
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260"
194 1
        )
195 1
        assert response.status_code == 201, current_data
196 1
        args, kwargs = self.scheduler.add.call_args
197 1
        window: MW = args[0]
198
199
        assert window.start == start.replace(microsecond=0)
200
        assert window.end == end.replace(microsecond=0)
201
        assert window.switches == []
202
        assert window.interfaces == []
203
        assert window.links == [
204
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260"
205
        ]
206
207
        assert current_data == {"mw_id": window.id}
208
209
    async def test_create_mw_case_5(self, event_loop):
210
        """Test a fail case of the REST to create a maintenance window."""
211
        self.napp.controller.loop = event_loop
212
        url = f"{self.base_endpoint}"
213
        payload = {
214
            "switches": [
215
                "00:00:00:00:00:00:02",
216
            ],
217
            "interfaces": [
218
                "00:00:00:00:00:00:00:03:3",
219
            ],
220
        }
221
        response = await self.api.post(url, json=payload)
222
        assert response.status_code == 400
223
        self.scheduler.add.assert_not_called()
224
225 View Code Duplication
    async def test_create_mw_case_6(self, event_loop):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
226
        """Test a fail case of the REST to create a maintenance window."""
227
        self.napp.controller.loop = event_loop
228 1
        url = f"{self.base_endpoint}"
229
        start = datetime.now(pytz.utc) - timedelta(days=1)
230
        end = start + timedelta(hours=2)
231
        payload = {
232
            "start": start.strftime(TIME_FMT),
233
            "end": end.strftime(TIME_FMT),
234
            "switches": [
235
                "00:00:00:00:00:00:02",
236
            ],
237
            "interfaces": [
238
                "00:00:00:00:00:00:00:03:3",
239
            ],
240
        }
241
        response = await self.api.post(url, json=payload)
242
        current_data = response.json()
243
        assert response.status_code == 400
244
        assert current_data["description"] == "start: Start in the past not allowed"
245
        self.scheduler.add.assert_not_called()
246
247 View Code Duplication
    async def test_create_mw_case_7(self, event_loop):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
248
        """Test a fail case of the REST to create a maintenance window."""
249
        self.napp.controller.loop = event_loop
250
        url = f"{self.base_endpoint}"
251
        start = datetime.now(pytz.utc) + timedelta(days=1)
252
        end = start - timedelta(hours=2)
253
        payload = {
254
            "start": start.strftime(TIME_FMT),
255
            "end": end.strftime(TIME_FMT),
256
            "switches": [
257
                "00:00:00:00:00:00:02",
258
            ],
259 1
            "interfaces": [
260 1
                "00:00:00:00:00:00:00:03:3",
261 1
            ],
262 1
        }
263 1
        response = await self.api.post(url, json=payload)
264 1
        current_data = response.json()
265
266 1
        assert response.status_code == 400
267
        assert current_data["description"] == "end: End before start not allowed"
268 1
        self.scheduler.add.assert_not_called()
269 1
270 1 View Code Duplication
    @pytest.mark.skip(reason="Future feature")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
271 1
    async def test_create_mw_case_8(self, event_loop):
272 1
        """Test a fail case of the REST to create a maintenance window."""
273 1
        self.napp.controller.loop = event_loop
274
        url = f"{self.base_endpoint}"
275 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
276
        end = start + timedelta(hours=2)
277 1
        payload = {
278
            "id": "1234",
279 1
            "start": start.strftime(TIME_FMT),
280 1
            "end": end.strftime(TIME_FMT),
281 1
            "switches": [
282 1
                "00:00:00:00:00:00:02",
283
            ],
284
            "interfaces": [
285
                "00:00:00:00:00:00:00:03:3",
286
            ],
287
        }
288
        response = await self.api.post(url, json=payload)
289
        current_data = response.json()
290
291
        assert response.status_code == 400
292 1
        assert current_data["description"] == "Setting a maintenance id is not allowed"
293
        self.scheduler.add.assert_not_called()
294
295 View Code Duplication
    async def test_create_mw_case_9(self, event_loop):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
296
        """Test a fail case of the REST to create a maintenance window."""
297
        self.napp.controller.loop = event_loop
298
        url = f"{self.base_endpoint}"
299
        start = datetime.now(pytz.utc) + timedelta(days=1)
300
        end = start + timedelta(hours=2)
301
        payload = {
302
            "status": "fun",
303
            "start": start.strftime(TIME_FMT),
304
            "end": end.strftime(TIME_FMT),
305
            "switches": [
306 1
                "00:00:00:00:00:00:02",
307 1
            ],
308 1
            "interfaces": [
309 1
                "00:00:00:00:00:00:00:03:3",
310 1
            ],
311 1
        }
312
        response = await self.api.post(url, json=payload)
313 1
        current_data = response.json()
314
315 1
        assert response.status_code == 400
316 1
        assert (
317 1
            current_data["description"] == "Setting a maintenance status is not allowed"
318 1
        )
319 1
        self.scheduler.add.assert_not_called()
320 1
321
    async def test_get_mw_case_1(self):
322 1
        """Test get all maintenance windows, empty list."""
323 1
        self.scheduler.list_maintenances.return_value = MaintenanceWindows.construct(
324
            __root__=[]
325 1
        )
326
        url = f"{self.base_endpoint}"
327 1
        response = await self.api.get(url)
328 1
        current_data = response.json()
329 1
        assert response.status_code == 200
330
        assert current_data == []
331
        self.scheduler.list_maintenances.assert_called_once()
332
333
    async def test_get_mw_case_2(self):
334
        """Test get all maintenance windows."""
335
        now = datetime.now(pytz.utc)
336
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
337 1
        end1 = start1 + timedelta(hours=6)
338 1
        start2 = datetime.now(pytz.utc) + timedelta(hours=5)
339 1
        end2 = start2 + timedelta(hours=1, minutes=30)
340 1
        self.scheduler.list_maintenances.return_value = MaintenanceWindows.construct(
341 1
            __root__=[
342
                MW.construct(
343 1
                    id="1234",
344 1
                    start=start1.replace(microsecond=0),
345
                    end=end1.replace(microsecond=0),
346 1
                    switches=["00:00:00:00:00:00:12:23"],
347
                    description="",
348 1
                    links=[],
349 1
                    interfaces=[],
350 1
                    status="pending",
351
                    updated_at=now.replace(microsecond=0),
352
                    inserted_at=now.replace(microsecond=0),
353
                ),
354
                MW.construct(
355
                    id="4567",
356
                    start=start2.replace(microsecond=0),
357
                    end=end2.replace(microsecond=0),
358
                    switches=["12:34:56:78:90:ab:cd:ef"],
359 1
                    description="",
360 1
                    links=[],
361 1
                    interfaces=[],
362 1
                    status="pending",
363 1
                    updated_at=now.replace(microsecond=0),
364
                    inserted_at=now.replace(microsecond=0),
365 1
                ),
366 1
            ]
367
        )
368 1
        mw_dict = [
369
            {
370 1
                "id": "1234",
371 1
                "start": start1.strftime(TIME_FMT),
372 1
                "end": end1.strftime(TIME_FMT),
373 1
                "switches": ["00:00:00:00:00:00:12:23"],
374
                "description": "",
375
                "links": [],
376 1
                "interfaces": [],
377 1
                "status": "pending",
378 1
                "updated_at": now.strftime(TIME_FMT),
379 1
                "inserted_at": now.strftime(TIME_FMT),
380 1
            },
381
            {
382 1
                "id": "4567",
383
                "start": start2.strftime(TIME_FMT),
384 1
                "end": end2.strftime(TIME_FMT),
385
                "switches": ["12:34:56:78:90:ab:cd:ef"],
386 1
                "description": "",
387 1
                "links": [],
388 1
                "interfaces": [],
389
                "status": "pending",
390
                "updated_at": now.strftime(TIME_FMT),
391 1
                "inserted_at": now.strftime(TIME_FMT),
392 1
            },
393 1
        ]
394 1
395 1
        url = f"{self.base_endpoint}"
396
        response = await self.api.get(url)
397 1
        current_data = response.json()
398
        assert response.status_code == 200
399 1
        assert current_data == mw_dict
400 1
        self.scheduler.list_maintenances.assert_called_once()
401 1
402 1
    async def test_get_mw_case_3(self):
403
        """Test get non-existent id."""
404
        self.scheduler.get_maintenance.return_value = None
405
        url = f"{self.base_endpoint}/2345"
406
        response = await self.api.get(url)
407
        current_data = response.json()
408
        assert response.status_code == 404
409
        assert current_data["description"] == "Maintenance with id 2345 not found"
410 1
        self.scheduler.get_maintenance.assert_called_once_with("2345")
411 1
412
    async def test_get_mw_case_4(self):
413
        """Test get existent id."""
414 1
        now = datetime.now(pytz.utc)
415 1
        start2 = datetime.now(pytz.utc) + timedelta(hours=5)
416 1
        end2 = start2 + timedelta(hours=1, minutes=30)
417 1
        self.scheduler.get_maintenance.return_value = MW.construct(
418
            id="4567",
419 1
            start=start2.replace(microsecond=0),
420 1
            end=end2.replace(microsecond=0),
421 1
            switches=["12:34:56:78:90:ab:cd:ef"],
422
            updated_at=now.replace(microsecond=0),
423
            inserted_at=now.replace(microsecond=0),
424
        )
425
        mw_dict = {
426
            "id": "4567",
427
            "start": start2.strftime(TIME_FMT),
428
            "end": end2.strftime(TIME_FMT),
429
            "switches": ["12:34:56:78:90:ab:cd:ef"],
430
            "description": "",
431
            "links": [],
432 1
            "interfaces": [],
433
            "status": "pending",
434 1
            "updated_at": now.strftime(TIME_FMT),
435 1
            "inserted_at": now.strftime(TIME_FMT),
436 1
        }
437 1
        url = f"{self.base_endpoint}/4567"
438
        response = await self.api.get(url)
439
        current_data = response.json()
440
        assert response.status_code == 200
441
        assert current_data == mw_dict
442
        self.scheduler.get_maintenance.assert_called_once_with("4567")
443
444
    async def test_remove_mw_case_1(self):
445 1
        """Test remove non-existent id."""
446 1
        self.scheduler.get_maintenance.return_value = None
447
        url = f"{self.base_endpoint}/2345"
448
        response = await self.api.delete(url)
449 1
        current_data = response.json()
450 1
        assert response.status_code == 404
451 1
        assert current_data["description"] == "Maintenance with id 2345 not found"
452 1
        self.scheduler.get_maintenance.assert_called_once_with("2345")
453 1
        self.scheduler.remove.assert_not_called()
454
455 1
    async def test_remove_mw_case_2(self):
456 1
        """Test remove existent id."""
457
        start1 = datetime.now(pytz.utc) + timedelta(hours=1)
458 1
        end1 = start1 + timedelta(hours=6)
459
        self.scheduler.get_maintenance.return_value = MW.construct(
460 1
            id="1234",
461 1
            start=start1.replace(microsecond=0),
462 1
            end=end1.replace(microsecond=0),
463 1
            switches=["00:00:00:00:00:00:12:23"],
464
        )
465
        url = f"{self.base_endpoint}/1234"
466
        response = await self.api.delete(url)
467
        current_data = response.json()
468
        assert response.status_code == 200
469
        assert current_data == {
470
            "response": "Maintenance with id 1234 " "successfully removed"
471 1
        }
472 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
473 1
        self.scheduler.remove.assert_called_once_with("1234")
474
475 View Code Duplication
    async def test_remove_mw_case_3(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
476
        """Test remove existent id."""
477 1
        start1 = datetime.now(pytz.utc) - timedelta(days=1)
478 1
        end1 = start1 + timedelta(hours=6)
479 1
        self.scheduler.get_maintenance.return_value = MW.construct(
480 1
            id="1234",
481 1
            start=start1.replace(microsecond=0),
482
            end=end1.replace(microsecond=0),
483 1
            switches=["00:00:00:00:00:00:12:23"],
484 1
            status="running",
485
        )
486 1
        url = f"{self.base_endpoint}/1234"
487
        response = await self.api.delete(url)
488 1
        current_data = response.json()
489 1
        assert response.status_code == 400
490 1
        assert (
491 1
            current_data["description"]
492
            == "Deleting a running maintenance is not allowed"
493
        )
494
        self.scheduler.get_maintenance.assert_called_once_with("1234")
495
        self.scheduler.remove.assert_not_called()
496
497
    async def test_update_mw_case_1(self, event_loop):
498
        """Test update non-existent id."""
499 1
        self.napp.controller.loop = event_loop
500 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
501
        self.scheduler.get_maintenance.return_value = None
502
        payload = {
503
            "start": start1.strftime(TIME_FMT),
504
        }
505
        url = f"{self.base_endpoint}/2345"
506
        response = await self.api.patch(url, json=payload)
507 1
        current_data = response.json()
508 1
        assert response.status_code == 404
509 1
        assert current_data["description"] == "Maintenance with id 2345 not found"
510 1
        self.scheduler.update.assert_not_called()
511 1
512
    async def test_update_mw_case_2(self, event_loop):
513 1
        """Test update no data."""
514 1
        self.napp.controller.loop = event_loop
515
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
516 1
        payload = {
517
            "start": start1.strftime(TIME_FMT),
518 1
        }
519 1
        url = f"{self.base_endpoint}/1234"
520 1
        response = await self.api.patch(url, json=payload)
521 1
        current_data = response.json()
522
        assert response.status_code == 400
523
        assert "field required" in current_data["description"]
524
525
    async def test_update_mw_case_3(self, event_loop):
526
        """Test successful update."""
527
        self.napp.controller.loop = event_loop
528
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
529 1
        end1 = start1 + timedelta(hours=6)
530
        self.scheduler.get_maintenance.return_value = MW.construct(
531
            id="1234",
532 1
            start=start1.replace(microsecond=0),
533 1
            end=end1.replace(microsecond=0),
534 1
            switches=["00:00:00:00:00:00:12:23"],
535 1
        )
536 1
        start_new = datetime.now(pytz.utc) + timedelta(days=1, hours=3)
537
        payload = {
538 1
            "start": start_new.strftime(TIME_FMT),
539
        }
540 1
        url = f"{self.base_endpoint}/1234"
541
        response = await self.api.patch(url, json=payload)
542 1
        current_data = response.json()
543 1
        assert current_data == {"response": "Maintenance 1234 updated"}
544 1
        assert response.status_code == 200
545 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
546 1
        self.scheduler.update.assert_called_once_with(
547 1
            MW.construct(
548
                id="1234",
549
                start=start_new.replace(microsecond=0),
550 1
                end=end1.replace(microsecond=0),
551
                switches=["00:00:00:00:00:00:12:23"],
552 1
            )
553 1
        )
554 1
555
    async def test_update_mw_case_4(self, event_loop):
556
        """Test successful update."""
557
        self.napp.controller.loop = event_loop
558
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
559
        end1 = start1 + timedelta(hours=6)
560
        self.scheduler.get_maintenance.return_value = MW.construct(
561
            id="1234",
562
            start=start1.replace(microsecond=0),
563 1
            end=end1.replace(microsecond=0),
564 1
            switches=["00:00:00:00:00:00:12:23"],
565 1
        )
566 1
        start_new = datetime.now(pytz.utc) - timedelta(days=1, hours=3)
567 1
        payload = {
568 1
            "start": start_new.strftime(TIME_FMT),
569 1
        }
570
        url = f"{self.base_endpoint}/1234"
571
        response = await self.api.patch(url, json=payload)
572 1
        current_data = response.json()
573
        assert response.status_code == 400
574 1
        assert current_data["description"] == "start: Start in the past not allowed"
575 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
576 1
        self.scheduler.update.assert_not_called()
577
578
    async def test_update_mw_case_5(self, event_loop):
579
        """Test successful update."""
580
        self.napp.controller.loop = event_loop
581
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
582
        end1 = start1 + timedelta(hours=6)
583
        self.scheduler.get_maintenance.return_value = MW.construct(
584
            id="1234",
585 1
            start=start1.replace(microsecond=0),
586 1
            end=end1.replace(microsecond=0),
587 1
            switches=["00:00:00:00:00:00:12:23"],
588 1
        )
589 1
        start_new = datetime.now(pytz.utc) + timedelta(days=1, hours=3)
590 1
        end_new = start_new - timedelta(hours=5)
591 1
        payload = {
592
            "start": start_new.strftime(TIME_FMT),
593
            "end": end_new.strftime(TIME_FMT),
594 1
        }
595
        url = f"{self.base_endpoint}/1234"
596 1
        response = await self.api.patch(url, json=payload)
597 1
        current_data = response.json()
598 1
        assert response.status_code == 400
599
        assert current_data["description"] == "end: End before start not allowed"
600
        self.scheduler.get_maintenance.assert_called_once_with("1234")
601
        self.scheduler.update.assert_not_called()
602
603
    async def test_update_mw_case_6(self, event_loop):
604
        """Test successful update."""
605
        self.napp.controller.loop = event_loop
606
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
607 1
        end1 = start1 + timedelta(hours=6)
608 1
        self.scheduler.get_maintenance.return_value = MW.construct(
609 1
            id="1234",
610 1
            start=start1.replace(microsecond=0),
611 1
            end=end1.replace(microsecond=0),
612 1
            switches=["00:00:00:00:00:00:12:23"],
613 1
        )
614
        start_new = datetime.now(pytz.utc) + timedelta(days=1, hours=3)
615
        payload = {
616 1
            "start": start_new.strftime(TIME_FMT),
617
            "switches": [],
618 1
            "interfaces": [],
619 1
            "links": [],
620 1
        }
621 1
622
        url = f"{self.base_endpoint}/1234"
623
        response = await self.api.patch(url, json=payload)
624
        current_data = response.json()
625
        assert response.status_code == 400
626
        assert (
627
            current_data["description"]
628
            == "__root__: At least one item must be provided"
629
        )
630 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
631 1
        self.scheduler.update.assert_not_called()
632
633 View Code Duplication
    async def test_update_mw_case_7(self, event_loop):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
634 1
        """Test successful update."""
635 1
        self.napp.controller.loop = event_loop
636 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
637 1
        end1 = start1 + timedelta(hours=6)
638
        self.scheduler.get_maintenance.return_value = MW.construct(
639
            id="1234",
640
            start=start1.replace(microsecond=0),
641
            end=end1.replace(microsecond=0),
642
            switches=["00:00:00:00:00:00:12:23"],
643
        )
644
        payload = {
645
            "status": "running",
646
        }
647 1
        url = f"{self.base_endpoint}/1234"
648
        response = await self.api.patch(url, json=payload)
649 1
        current_data = response.json()
650 1
        assert response.status_code == 400
651 1
        assert (
652 1
            current_data["description"]
653 1
            == "Updating a maintenance status is not allowed"
654 1
        )
655 1
        self.scheduler.update.assert_not_called()
656
657 1
    async def test_end_mw_case_1(self):
658
        """Test method that finishes the maintenance now."""
659 1
        self.scheduler.get_maintenance.return_value = None
660 1
        url = f"{self.base_endpoint}/2345/end"
661 1
        response = await self.api.patch(url)
662
        current_data = response.json()
663
        assert response.status_code == 404
664 1
        assert current_data["description"] == "Maintenance with id 2345 not found"
665 1
666 1 View Code Duplication
    async def test_end_mw_case_2(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
667 1
        """Test method that finishes the maintenance now."""
668
        start1 = datetime.now(pytz.utc) - timedelta(hours=1)
669 1
        end1 = start1 + timedelta(hours=6)
670
        self.scheduler.get_maintenance.return_value = MW.construct(
671 1
            id="1234",
672
            start=start1.replace(microsecond=0),
673 1
            end=end1.replace(microsecond=0),
674 1
            switches=["00:00:00:00:00:00:12:23"],
675 1
            status="running",
676
        )
677
        url = f"{self.base_endpoint}/1234/end"
678 1
        response = await self.api.patch(url)
679 1
        current_data = response.json()
680 1
        self.scheduler.get.asssert_called_once_with("1234")
681 1
        self.scheduler.end_maintenance_early.assert_called_once_with("1234")
682
        assert response.status_code == 200
683 1
        assert current_data == {"response": "Maintenance window 1234 finished"}
684
685 1 View Code Duplication
    async def test_end_mw_case_3(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
686
        """Test method that finishes the maintenance now."""
687 1
        start1 = datetime.now(pytz.utc) + timedelta(hours=1)
688 1
        end1 = start1 + timedelta(hours=6)
689 1
        self.scheduler.get_maintenance.return_value = MW.construct(
690 1
            id="1234",
691
            start=start1.replace(microsecond=0),
692
            end=end1.replace(microsecond=0),
693
            switches=["00:00:00:00:00:00:12:23"],
694
            status="pending",
695
        )
696
        url = f"{self.base_endpoint}/1234/end"
697
        response = await self.api.patch(url)
698
        current_data = response.json()
699 1
        self.scheduler.get.asssert_called_once_with("1234")
700 1
        self.scheduler.end_maintenance_early.assert_not_called()
701
        assert response.status_code == 400
702
        assert (
703 1
            current_data["description"] == "Maintenance window 1234 has not yet started"
704 1
        )
705 1
706 1 View Code Duplication
    async def test_end_mw_case_4(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
707
        """Test method that finishes the maintenance now."""
708 1
        start1 = datetime.now(pytz.utc) - timedelta(hours=5)
709 1
        end1 = start1 + timedelta(hours=4)
710
        self.scheduler.get_maintenance.return_value = MW.construct(
711 1
            id="1234",
712
            start=start1.replace(microsecond=0),
713 1
            end=end1.replace(microsecond=0),
714 1
            switches=["00:00:00:00:00:00:12:23"],
715 1
            status="finished",
716 1
        )
717
        url = f"{self.base_endpoint}/1234/end"
718
        response = await self.api.patch(url)
719
        current_data = response.json()
720
        self.scheduler.get.asssert_called_once_with("1234")
721
        self.scheduler.end_maintenance_early.assert_not_called()
722
        assert response.status_code == 400
723
        assert (
724
            current_data["description"]
725 1
            == "Maintenance window 1234 has already finished"
726 1
        )
727
728
    async def test_extend_case_1(self, event_loop):
729 1
        """Test successful extension."""
730 1
        self.napp.controller.loop = event_loop
731 1
        start1 = datetime.now(pytz.utc) - timedelta(hours=3)
732 1
        end1 = start1 + timedelta(hours=4)
733
        self.scheduler.get_maintenance.return_value = MW.construct(
734 1
            id="1234",
735 1
            start=start1.replace(microsecond=0),
736
            end=end1.replace(microsecond=0),
737 1
            switches=["00:00:00:00:00:00:12:23"],
738
            status="running",
739 1
        )
740 1
        url = f"{self.base_endpoint}/1234/extend"
741 1
        payload = {"minutes": 45}
742 1
        response = await self.api.patch(url, json=payload)
743
        assert response.status_code == 200
744
        self.scheduler.get_maintenance.called_with("1234")
745 1
        self.scheduler.update.assert_called_with(
746 1
            MW.construct(
747 1
                id="1234",
748 1
                start=start1.replace(microsecond=0),
749
                end=end1.replace(microsecond=0) + timedelta(minutes=45),
750 1
                switches=["00:00:00:00:00:00:12:23"],
751 1
                status="running",
752
            )
753
        )
754
755
    async def test_extend_case_2(self, event_loop):
756
        """Test no payload error."""
757
        self.napp.controller.loop = event_loop
758
        url = f"{self.base_endpoint}/1234/extend"
759
        response = await self.api.patch(url)
760
        assert response.status_code == 400
761
        current_data = response.json()
762
        assert "Invalid json" in current_data["description"]
763
        self.scheduler.update.assert_not_called()
764
765
    async def test_extend_case_3(self, event_loop):
766
        """Test payload without minutes."""
767
        self.napp.controller.loop = event_loop
768
        url = f"{self.base_endpoint}/1234/extend"
769
        payload = {"seconds": 240}
770
        response = await self.api.patch(url, json=payload)
771
        assert response.status_code == 400
772
        current_data = response.json()
773
        assert current_data["description"] == "Minutes of extension must be sent"
774
        self.scheduler.update.assert_not_called()
775
776
    async def test_extend_case_4(self, event_loop):
777
        """Test no integer extension minutes."""
778
        self.napp.controller.loop = event_loop
779
        url = f"{self.base_endpoint}/1234/extend"
780
        payload = {"minutes": "240"}
781
        response = await self.api.patch(url, json=payload)
782
        assert response.status_code == 400
783
        current_data = response.json()
784
        assert current_data["description"] == "Minutes of extension must be integer"
785
        self.scheduler.update.assert_not_called()
786
787 View Code Duplication
    async def test_extend_case_5(self, event_loop):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
788
        """Test maintenance did not start."""
789
        self.napp.controller.loop = event_loop
790
        start1 = datetime.now(pytz.utc) + timedelta(hours=3)
791
        end1 = start1 + timedelta(hours=4)
792
        self.scheduler.get_maintenance.return_value = MW.construct(
793
            id="1234",
794
            start=start1.replace(microsecond=0),
795
            end=end1.replace(microsecond=0),
796
            switches=["00:00:00:00:00:00:12:23"],
797
            status="pending",
798
        )
799
        url = f"{self.base_endpoint}/1234/extend"
800
        payload = {"minutes": 240}
801
        response = await self.api.patch(url, json=payload)
802
        assert response.status_code == 400
803
        current_data = response.json()
804
        assert (
805
            current_data["description"] == "Maintenance window 1234 has not yet started"
806
        )
807
        self.scheduler.get_maintenance.assert_called_once_with("1234")
808
        self.scheduler.update.assert_not_called()
809
810 View Code Duplication
    async def test_extend_case_6(self, event_loop):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
811
        """Test maintenance already finished."""
812
        self.napp.controller.loop = event_loop
813
        start1 = datetime.now(pytz.utc) - timedelta(hours=3)
814
        end1 = start1 + timedelta(hours=2)
815
        self.scheduler.get_maintenance.return_value = MW.construct(
816
            id="1234",
817
            start=start1.replace(microsecond=0),
818
            end=end1.replace(microsecond=0),
819
            switches=["00:00:00:00:00:00:12:23"],
820
            status="finished",
821
        )
822
        url = f"{self.base_endpoint}/1234/extend"
823
        payload = {"minutes": 240}
824
        response = await self.api.patch(url, json=payload)
825
        assert response.status_code == 400
826
        current_data = response.json()
827
        assert (
828
            current_data["description"]
829
            == "Maintenance window 1234 has already finished"
830
        )
831
        self.scheduler.get_maintenance.assert_called_once_with("1234")
832
        self.scheduler.update.assert_not_called()
833
834
    async def test_extend_case_7(self, event_loop):
835
        """Test no maintenace found."""
836
        self.napp.controller.loop = event_loop
837
        self.scheduler.get_maintenance.return_value = None
838
        url = f"{self.base_endpoint}/1235/extend"
839
        payload = {"minutes": 240}
840
        response = await self.api.patch(url, json=payload)
841
        assert response.status_code == 404
842
        current_data = response.json()
843
        assert current_data["description"] == "Maintenance with id 1235 not found"
844
        self.scheduler.get_maintenance.assert_called_once_with("1235")
845
        self.scheduler.update.assert_not_called()
846