Passed
Push — master ( 1a0953...219bfd )
by Vinicius
02:02 queued 14s
created

TestMain.test_create_mw_case_7()   A

Complexity

Conditions 1

Size

Total Lines 22
Code Lines 17

Duplication

Lines 22
Ratio 100 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 17
nop 2
dl 22
loc 22
rs 9.55
c 0
b 0
f 0
ccs 11
cts 11
cp 1
crap 1
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
            "napps.kytos.maintenance.managers.MaintenanceScheduler.new_scheduler"
30
        )
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 1
        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
        """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 1
        end = start + timedelta(hours=2)
44 1
        self.controller.switches = MagicMock()
45 1
        self.controller.get_interface_by_id = MagicMock()
46 1
        self.controller.napps[("kytos", "topology")].links = MagicMock()
47 1
        switches = {"00:00:00:00:00:00:00:02": 1, "00:00:00:00:00:00:00:03": 2}
48 1
        interfaces = {"00:00:00:00:00:00:00:03:3": 1, "00:00:00:00:00:00:00:02:1": 2}
49 1
        links = {
50
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260": 1,
51
            "4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30": 2,
52
        }
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 1
        payload = {
58
            "start": start.strftime(TIME_FMT),
59
            "end": end.strftime(TIME_FMT),
60
            "switches": ["00:00:00:00:00:00:00:02", "00:00:00:00:00:00:00:03"],
61
            "interfaces": ["00:00:00:00:00:00:00:03:3", "00:00:00:00:00:00:00:02:1"],
62
            "links": [
63
                "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260",
64
                "4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30",
65
            ],
66
        }
67 1
        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 1
        self.controller.switches.get.assert_has_calls(switch_calls)
75 1
        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
        ]
79 1
        self.controller.get_interface_by_id.assert_has_calls(interface_calls)
80 1
        link_calls = [
81
            call("cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260"),
82
            call("4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30"),
83
        ]
84 1
        self.controller.napps[("kytos", "topology")].links.get.assert_has_calls(
85
            link_calls
86
        )
87 1
        args, kwargs = self.scheduler.add.call_args
88 1
        window: MW = args[0]
89
90 1
        assert window.start == start.replace(microsecond=0)
91 1
        assert window.end == end.replace(microsecond=0)
92 1
        assert window.switches == ["00:00:00:00:00:00:00:02", "00:00:00:00:00:00:00:03"]
93 1
        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 1
        assert window.links == [
98
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260",
99
            "4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30",
100
        ]
101
102 1
        assert current_data == {"mw_id": window.id}
103
104 1
    async def test_create_mw_case_2(self, event_loop):
105
        """Test a successful case of the REST to create."""
106 1
        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 1
        self.controller.switches.get.side_effect = switches.get
113 1
        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 1
        response = await self.api.post(url, json=payload)
121 1
        current_data = response.json()
122 1
        assert response.status_code == 201, current_data
123 1
        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 1
        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 1
        assert window.links == []
132
133 1
        assert current_data == {"mw_id": window.id}
134
135 1
    async def test_create_mw_case_3(self, event_loop):
136
        """Test a successful case of the REST to create."""
137 1
        self.napp.controller.loop = event_loop
138 1
        url = f"{self.base_endpoint}"
139 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
140 1
        end = start + timedelta(hours=2)
141 1
        self.controller.get_interface_by_id = MagicMock()
142 1
        interfaces = {"00:00:00:00:00:00:00:01:1": 1}
143 1
        get_interface_side_effect = lambda interface_id: interfaces.get(interface_id)
144 1
        self.controller.get_interface_by_id.side_effect = get_interface_side_effect
145 1
        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 1
        response = await self.api.post(url, json=payload)
155 1
        current_data = response.json()
156 1
        assert response.status_code == 201, current_data
157 1
        self.controller.get_interface_by_id.assert_called_with(
158
            "00:00:00:00:00:00:00:01:1"
159
        )
160 1
        assert response.status_code == 201, current_data
161 1
        args, kwargs = self.scheduler.add.call_args
162 1
        response = await self.api.get(f"{url}/some_mw")
163 1
        window: MW = args[0]
164
165 1
        assert window.start == start.replace(microsecond=0)
166 1
        assert window.end == end.replace(microsecond=0)
167 1
        assert window.switches == []
168 1
        assert window.interfaces == ["00:00:00:00:00:00:00:01:1"]
169 1
        assert window.links == []
170
171 1
        assert current_data == {"mw_id": "some_mw"}
172
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 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
178 1
        end = start + timedelta(hours=2)
179 1
        self.controller.napps[("kytos", "topology")].links = MagicMock()
180 1
        links = {"cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260": 1}
181 1
        self.controller.napps[("kytos", "topology")].links.get.side_effect = links.get
182 1
        payload = {
183
            "start": start.strftime(TIME_FMT),
184
            "end": end.strftime(TIME_FMT),
185
            "links": [
186
                "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260",
187
            ],
188
        }
189 1
        response = await self.api.post(url, json=payload)
190 1
        current_data = response.json()
191 1
        assert response.status_code == 201, current_data
192 1
        self.controller.napps[("kytos", "topology")].links.get.assert_called_with(
193
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260"
194
        )
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 1
        assert window.start == start.replace(microsecond=0)
200 1
        assert window.end == end.replace(microsecond=0)
201 1
        assert window.switches == []
202 1
        assert window.interfaces == []
203 1
        assert window.links == [
204
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260"
205
        ]
206
207 1
        assert current_data == {"mw_id": window.id}
208
209 1
    async def test_create_mw_case_5(self, event_loop):
210
        """Test a fail case of the REST to create a maintenance window."""
211 1
        self.napp.controller.loop = event_loop
212 1
        url = f"{self.base_endpoint}"
213 1
        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 1
        response = await self.api.post(url, json=payload)
222 1
        assert response.status_code == 400
223 1
        self.scheduler.add.assert_not_called()
224
225 1 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 1
        self.napp.controller.loop = event_loop
228 1
        url = f"{self.base_endpoint}"
229 1
        start = datetime.now(pytz.utc) - timedelta(days=1)
230 1
        end = start + timedelta(hours=2)
231 1
        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 1
        response = await self.api.post(url, json=payload)
242 1
        current_data = response.json()
243 1
        assert response.status_code == 400
244 1
        assert current_data["description"] == "start: Start in the past not allowed"
245 1
        self.scheduler.add.assert_not_called()
246
247 1 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 1
        self.napp.controller.loop = event_loop
250 1
        url = f"{self.base_endpoint}"
251 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
252 1
        end = start - timedelta(hours=2)
253 1
        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
            "interfaces": [
260
                "00:00:00:00:00:00:00:03:3",
261
            ],
262
        }
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 1
        assert current_data["description"] == "end: End before start not allowed"
268 1
        self.scheduler.add.assert_not_called()
269
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
        """Test a fail case of the REST to create a maintenance window."""
273
        self.napp.controller.loop = event_loop
274
        url = f"{self.base_endpoint}"
275
        start = datetime.now(pytz.utc) + timedelta(days=1)
276
        end = start + timedelta(hours=2)
277
        payload = {
278
            "id": "1234",
279
            "start": start.strftime(TIME_FMT),
280
            "end": end.strftime(TIME_FMT),
281
            "switches": [
282
                "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
        assert current_data["description"] == "Setting a maintenance id is not allowed"
293
        self.scheduler.add.assert_not_called()
294
295 1 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 1
        self.napp.controller.loop = event_loop
298 1
        url = f"{self.base_endpoint}"
299 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
300 1
        end = start + timedelta(hours=2)
301 1
        payload = {
302
            "status": "fun",
303
            "start": start.strftime(TIME_FMT),
304
            "end": end.strftime(TIME_FMT),
305
            "switches": [
306
                "00:00:00:00:00:00:02",
307
            ],
308
            "interfaces": [
309
                "00:00:00:00:00:00:00:03:3",
310
            ],
311
        }
312 1
        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
            current_data["description"] == "Setting a maintenance status is not allowed"
318
        )
319 1
        self.scheduler.add.assert_not_called()
320
321 1
    async def test_get_mw_case_1(self):
322
        """Test get all maintenance windows, empty list."""
323 1
        self.scheduler.list_maintenances.return_value = MaintenanceWindows.construct(
324
            __root__=[]
325
        )
326 1
        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 1
        assert current_data == []
331 1
        self.scheduler.list_maintenances.assert_called_once()
332
333 1
    async def test_get_mw_case_2(self):
334
        """Test get all maintenance windows."""
335 1
        now = datetime.now(pytz.utc)
336 1
        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
            __root__=[
342
                MW.construct(
343
                    id="1234",
344
                    start=start1.replace(microsecond=0),
345
                    end=end1.replace(microsecond=0),
346
                    switches=["00:00:00:00:00:00:12:23"],
347
                    description="",
348
                    links=[],
349
                    interfaces=[],
350
                    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
                    description="",
360
                    links=[],
361
                    interfaces=[],
362
                    status="pending",
363
                    updated_at=now.replace(microsecond=0),
364
                    inserted_at=now.replace(microsecond=0),
365
                ),
366
            ]
367
        )
368 1
        mw_dict = [
369
            {
370
                "id": "1234",
371
                "start": start1.strftime(TIME_FMT),
372
                "end": end1.strftime(TIME_FMT),
373
                "switches": ["00:00:00:00:00:00:12:23"],
374
                "description": "",
375
                "links": [],
376
                "interfaces": [],
377
                "status": "pending",
378
                "updated_at": now.strftime(TIME_FMT),
379
                "inserted_at": now.strftime(TIME_FMT),
380
            },
381
            {
382
                "id": "4567",
383
                "start": start2.strftime(TIME_FMT),
384
                "end": end2.strftime(TIME_FMT),
385
                "switches": ["12:34:56:78:90:ab:cd:ef"],
386
                "description": "",
387
                "links": [],
388
                "interfaces": [],
389
                "status": "pending",
390
                "updated_at": now.strftime(TIME_FMT),
391
                "inserted_at": now.strftime(TIME_FMT),
392
            },
393
        ]
394
395 1
        url = f"{self.base_endpoint}"
396 1
        response = await self.api.get(url)
397 1
        current_data = response.json()
398 1
        assert response.status_code == 200
399 1
        assert current_data == mw_dict
400 1
        self.scheduler.list_maintenances.assert_called_once()
401
402 1
    async def test_get_mw_case_3(self):
403
        """Test get non-existent id."""
404 1
        self.scheduler.get_maintenance.return_value = None
405 1
        url = f"{self.base_endpoint}/2345"
406 1
        response = await self.api.get(url)
407 1
        current_data = response.json()
408 1
        assert response.status_code == 404
409 1
        assert current_data["description"] == "Maintenance with id 2345 not found"
410 1
        self.scheduler.get_maintenance.assert_called_once_with("2345")
411
412 1
    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
            start=start2.replace(microsecond=0),
420
            end=end2.replace(microsecond=0),
421
            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 1
        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
            "interfaces": [],
433
            "status": "pending",
434
            "updated_at": now.strftime(TIME_FMT),
435
            "inserted_at": now.strftime(TIME_FMT),
436
        }
437 1
        url = f"{self.base_endpoint}/4567"
438 1
        response = await self.api.get(url)
439 1
        current_data = response.json()
440 1
        assert response.status_code == 200
441 1
        assert current_data == mw_dict
442 1
        self.scheduler.get_maintenance.assert_called_once_with("4567")
443
444 1
    async def test_remove_mw_case_1(self):
445
        """Test remove non-existent id."""
446 1
        self.scheduler.get_maintenance.return_value = None
447 1
        url = f"{self.base_endpoint}/2345"
448 1
        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
        """Test remove existent id."""
457 1
        start1 = datetime.now(pytz.utc) + timedelta(hours=1)
458 1
        end1 = start1 + timedelta(hours=6)
459 1
        self.scheduler.get_maintenance.return_value = MW.construct(
460
            id="1234",
461
            start=start1.replace(microsecond=0),
462
            end=end1.replace(microsecond=0),
463
            switches=["00:00:00:00:00:00:12:23"],
464
        )
465 1
        url = f"{self.base_endpoint}/1234"
466 1
        response = await self.api.delete(url)
467 1
        current_data = response.json()
468 1
        assert response.status_code == 200
469 1
        assert current_data == {
470
            "response": "Maintenance with id 1234 " "successfully removed"
471
        }
472 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
473 1
        self.scheduler.remove.assert_called_once_with("1234")
474
475 1 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
            id="1234",
481
            start=start1.replace(microsecond=0),
482
            end=end1.replace(microsecond=0),
483
            switches=["00:00:00:00:00:00:12:23"],
484
            status="running",
485
        )
486 1
        url = f"{self.base_endpoint}/1234"
487 1
        response = await self.api.delete(url)
488 1
        current_data = response.json()
489 1
        assert response.status_code == 400
490 1
        assert (
491
            current_data["description"]
492
            == "Deleting a running maintenance is not allowed"
493
        )
494 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
495 1
        self.scheduler.remove.assert_not_called()
496
497 1
    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 1
        self.scheduler.get_maintenance.return_value = None
502 1
        payload = {
503
            "start": start1.strftime(TIME_FMT),
504
        }
505 1
        url = f"{self.base_endpoint}/2345"
506 1
        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
512 1
    async def test_update_mw_case_2(self, event_loop):
513
        """Test update no data."""
514 1
        self.napp.controller.loop = event_loop
515 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
516 1
        payload = {
517
            "start": start1.strftime(TIME_FMT),
518
        }
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 1
        assert response.status_code == 400
523 1
        assert "field required" in current_data["description"]
524
525 1
    async def test_update_mw_case_3(self, event_loop):
526
        """Test successful update."""
527 1
        self.napp.controller.loop = event_loop
528 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
529 1
        end1 = start1 + timedelta(hours=6)
530 1
        self.scheduler.get_maintenance.return_value = MW.construct(
531
            id="1234",
532
            start=start1.replace(microsecond=0),
533
            end=end1.replace(microsecond=0),
534
            switches=["00:00:00:00:00:00:12:23"],
535
        )
536 1
        start_new = datetime.now(pytz.utc) + timedelta(days=1, hours=3)
537 1
        payload = {
538
            "start": start_new.strftime(TIME_FMT),
539
        }
540 1
        url = f"{self.base_endpoint}/1234"
541 1
        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
            MW.construct(
548
                id="1234",
549
                start=start_new.replace(microsecond=0),
550
                end=end1.replace(microsecond=0),
551
                switches=["00:00:00:00:00:00:12:23"],
552
            )
553
        )
554
555 1
    async def test_update_mw_case_4(self, event_loop):
556
        """Test successful update."""
557 1
        self.napp.controller.loop = event_loop
558 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
559 1
        end1 = start1 + timedelta(hours=6)
560 1
        self.scheduler.get_maintenance.return_value = MW.construct(
561
            id="1234",
562
            start=start1.replace(microsecond=0),
563
            end=end1.replace(microsecond=0),
564
            switches=["00:00:00:00:00:00:12:23"],
565
        )
566 1
        start_new = datetime.now(pytz.utc) - timedelta(days=1, hours=3)
567 1
        payload = {
568
            "start": start_new.strftime(TIME_FMT),
569
        }
570 1
        url = f"{self.base_endpoint}/1234"
571 1
        response = await self.api.patch(url, json=payload)
572 1
        current_data = response.json()
573 1
        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 1
    async def test_update_mw_case_5(self, event_loop):
579
        """Test successful update."""
580 1
        self.napp.controller.loop = event_loop
581 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
582 1
        end1 = start1 + timedelta(hours=6)
583 1
        self.scheduler.get_maintenance.return_value = MW.construct(
584
            id="1234",
585
            start=start1.replace(microsecond=0),
586
            end=end1.replace(microsecond=0),
587
            switches=["00:00:00:00:00:00:12:23"],
588
        )
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
        }
595 1
        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 1
        assert current_data["description"] == "end: End before start not allowed"
600 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
601 1
        self.scheduler.update.assert_not_called()
602
603 1
    async def test_update_mw_case_6(self, event_loop):
604
        """Test successful update."""
605 1
        self.napp.controller.loop = event_loop
606 1
        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
            id="1234",
610
            start=start1.replace(microsecond=0),
611
            end=end1.replace(microsecond=0),
612
            switches=["00:00:00:00:00:00:12:23"],
613
        )
614 1
        start_new = datetime.now(pytz.utc) + timedelta(days=1, hours=3)
615 1
        payload = {
616
            "start": start_new.strftime(TIME_FMT),
617
            "switches": [],
618
            "interfaces": [],
619
            "links": [],
620
        }
621
622 1
        url = f"{self.base_endpoint}/1234"
623 1
        response = await self.api.patch(url, json=payload)
624 1
        current_data = response.json()
625 1
        assert response.status_code == 400
626 1
        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 1 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
        """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 1
        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 1
        payload = {
645
            "status": "running",
646
        }
647 1
        url = f"{self.base_endpoint}/1234"
648 1
        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
            current_data["description"]
653
            == "Updating a maintenance status is not allowed"
654
        )
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 1
        current_data = response.json()
663 1
        assert response.status_code == 404
664 1
        assert current_data["description"] == "Maintenance with id 2345 not found"
665
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
        """Test method that finishes the maintenance now."""
668 1
        start1 = datetime.now(pytz.utc) - timedelta(hours=1)
669 1
        end1 = start1 + timedelta(hours=6)
670 1
        self.scheduler.get_maintenance.return_value = MW.construct(
671
            id="1234",
672
            start=start1.replace(microsecond=0),
673
            end=end1.replace(microsecond=0),
674
            switches=["00:00:00:00:00:00:12:23"],
675
            status="running",
676
        )
677 1
        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 1
        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
            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 1
        url = f"{self.base_endpoint}/1234/end"
697 1
        response = await self.api.patch(url)
698 1
        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 1
        assert response.status_code == 400
702 1
        assert (
703
            current_data["description"] == "Maintenance window 1234 has not yet started"
704
        )
705
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 1
        self.scheduler.get_maintenance.return_value = MW.construct(
711
            id="1234",
712
            start=start1.replace(microsecond=0),
713
            end=end1.replace(microsecond=0),
714
            switches=["00:00:00:00:00:00:12:23"],
715
            status="finished",
716
        )
717 1
        url = f"{self.base_endpoint}/1234/end"
718 1
        response = await self.api.patch(url)
719 1
        current_data = response.json()
720 1
        self.scheduler.get.asssert_called_once_with("1234")
721 1
        self.scheduler.end_maintenance_early.assert_not_called()
722 1
        assert response.status_code == 400
723 1
        assert (
724
            current_data["description"]
725
            == "Maintenance window 1234 has already finished"
726
        )
727
728 1
    async def test_extend_case_1(self, event_loop):
729
        """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 1
        self.scheduler.get_maintenance.return_value = MW.construct(
734
            id="1234",
735
            start=start1.replace(microsecond=0),
736
            end=end1.replace(microsecond=0),
737
            switches=["00:00:00:00:00:00:12:23"],
738
            status="running",
739
        )
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 1
        assert response.status_code == 200
744 1
        self.scheduler.get_maintenance.called_with("1234")
745 1
        self.scheduler.update.assert_called_with(
746
            MW.construct(
747
                id="1234",
748
                start=start1.replace(microsecond=0),
749
                end=end1.replace(microsecond=0) + timedelta(minutes=45),
750
                switches=["00:00:00:00:00:00:12:23"],
751
                status="running",
752
            )
753
        )
754
755 1
    async def test_extend_case_2(self, event_loop):
756
        """Test no payload error."""
757 1
        self.napp.controller.loop = event_loop
758 1
        url = f"{self.base_endpoint}/1234/extend"
759 1
        response = await self.api.patch(url)
760 1
        assert response.status_code == 400
761 1
        current_data = response.json()
762 1
        assert "Invalid json" in current_data["description"]
763 1
        self.scheduler.update.assert_not_called()
764
765 1
    async def test_extend_case_3(self, event_loop):
766
        """Test payload without minutes."""
767 1
        self.napp.controller.loop = event_loop
768 1
        url = f"{self.base_endpoint}/1234/extend"
769 1
        payload = {"seconds": 240}
770 1
        response = await self.api.patch(url, json=payload)
771 1
        assert response.status_code == 400
772 1
        current_data = response.json()
773 1
        assert current_data["description"] == "Minutes of extension must be sent"
774 1
        self.scheduler.update.assert_not_called()
775
776 1
    async def test_extend_case_4(self, event_loop):
777
        """Test no integer extension minutes."""
778 1
        self.napp.controller.loop = event_loop
779 1
        url = f"{self.base_endpoint}/1234/extend"
780 1
        payload = {"minutes": "240"}
781 1
        response = await self.api.patch(url, json=payload)
782 1
        assert response.status_code == 400
783 1
        current_data = response.json()
784 1
        assert current_data["description"] == "Minutes of extension must be integer"
785 1
        self.scheduler.update.assert_not_called()
786
787 1 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 1
        self.napp.controller.loop = event_loop
790 1
        start1 = datetime.now(pytz.utc) + timedelta(hours=3)
791 1
        end1 = start1 + timedelta(hours=4)
792 1
        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 1
        url = f"{self.base_endpoint}/1234/extend"
800 1
        payload = {"minutes": 240}
801 1
        response = await self.api.patch(url, json=payload)
802 1
        assert response.status_code == 400
803 1
        current_data = response.json()
804 1
        assert (
805
            current_data["description"] == "Maintenance window 1234 has not yet started"
806
        )
807 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
808 1
        self.scheduler.update.assert_not_called()
809
810 1 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 1
        self.napp.controller.loop = event_loop
813 1
        start1 = datetime.now(pytz.utc) - timedelta(hours=3)
814 1
        end1 = start1 + timedelta(hours=2)
815 1
        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 1
        url = f"{self.base_endpoint}/1234/extend"
823 1
        payload = {"minutes": 240}
824 1
        response = await self.api.patch(url, json=payload)
825 1
        assert response.status_code == 400
826 1
        current_data = response.json()
827 1
        assert (
828
            current_data["description"]
829
            == "Maintenance window 1234 has already finished"
830
        )
831 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
832 1
        self.scheduler.update.assert_not_called()
833
834 1
    async def test_extend_case_7(self, event_loop):
835
        """Test no maintenace found."""
836 1
        self.napp.controller.loop = event_loop
837 1
        self.scheduler.get_maintenance.return_value = None
838 1
        url = f"{self.base_endpoint}/1235/extend"
839 1
        payload = {"minutes": 240}
840 1
        response = await self.api.patch(url, json=payload)
841 1
        assert response.status_code == 404
842 1
        current_data = response.json()
843 1
        assert current_data["description"] == "Maintenance with id 1235 not found"
844 1
        self.scheduler.get_maintenance.assert_called_once_with("1235")
845
        self.scheduler.update.assert_not_called()
846