Test Failed
Pull Request — master (#25)
by Vinicius
03:58
created

unit.test_main.TestMain.test_on_port_stats()   A

Complexity

Conditions 1

Size

Total Lines 41
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 41
ccs 31
cts 31
cp 1
rs 9.16
c 0
b 0
f 0
cc 1
nop 1
crap 1
1
"""Module to test the main napp file."""
2 1
from unittest.mock import MagicMock, patch
3 1
from kytos.lib.helpers import (
4
    get_controller_mock,
5
    get_test_client,
6
    get_kytos_event_mock,
7
    get_switch_mock,
8
)
9 1
from napps.amlight.kytos_stats.main import Main
10
11
12
# pylint: disable=too-many-public-methods, too-many-lines
13 1
class TestMain:
14
    """Test the Main class."""
15
16 1
    def setup_method(self):
17
        """Execute steps before each tests."""
18 1
        controller = get_controller_mock()
19 1
        self.napp = Main(controller)
20 1
        self.api_client = get_test_client(controller, self.napp)
21 1
        self.base_endpoint = "amlight/kytos_stats/v1"
22
23 1
    def test_get_event_listeners(self):
24
        """Verify all event listeners registered."""
25 1
        expected_events = [
26
            'kytos/of_core.flow_stats.received',
27
            'kytos/of_core.table_stats.received',
28
            'kytos/of_core.port_stats',
29 1
        ]
30
        actual_events = self.napp.listeners()
31 1
32 1
        for _event in expected_events:
33
            assert _event in actual_events
34 1
35
    def test_execute(self):
36
        """Test execute."""
37 1
38
    def test_shutdown(self):
39
        """Test shutdown."""
40 1
41
    def test_flow_from_id(self):
42 1
        """Test flow_from_id function"""
43 1
        flow = self._get_mocked_flow_base()
44
        self.napp.flows_stats_dict = {
45
            flow.id: flow
46 1
        }
47 1
        results = self.napp.flow_from_id(flow.id)
48
        assert results.id == flow.id
49 1
50
    def test_flow_from_id__fail(self):
51 1
        """Test flow_from_id function"""
52 1
        flow = self._get_mocked_flow_base()
53
        self.napp.flows_stats_dict = {
54
            flow.id: flow
55 1
        }
56 1
        results = self.napp.flow_from_id('1')
57
        assert results is None
58 1
59
    def test_flow_from_id__empty(self):
60 1
        """Test flow_from_id function when flows_stats_dict is empty"""
61 1
        self.napp.flows_stats_dict = {}
62 1
        results = self.napp.flow_from_id('1')
63
        assert results is None
64 1
65
    async def test_packet_count_not_found(self):
66 1
        """Test packet_count rest call with wrong flow_id."""
67 1
        flow_id = "123456789"
68 1
        endpoint = f"{self.base_endpoint}/packet_count/{flow_id}"
69
        response = await self.api_client.get(endpoint)
70
        assert response.status_code == 404
71
        assert response.json()["description"] == "Flow does not exist"
72 1
73 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.flow_from_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
74
    async def test_packet_count(self, mock_from_flow):
75 1
        """Test packet_count rest call."""
76 1
        flow_id = '1'
77
        mock_from_flow.return_value = self._get_mocked_flow_base()
78 1
79 1
        self._patch_switch_flow(flow_id)
80 1
        endpoint = f"{self.base_endpoint}/packet_count/{flow_id}"
81 1
        response = await self.api_client.get(endpoint)
82 1
        assert response.status_code == 200
83 1
        json_response = response.json()
84 1
        assert json_response["flow_id"] == flow_id
85 1
        assert json_response["packet_counter"] == 40
86
        assert json_response["packet_per_second"] == 2.0
87 1
88
    async def test_bytes_count_not_found(self):
89 1
        """Test bytes_count rest call with wrong flow_id."""
90 1
        flow_id = "123456789"
91 1
        endpoint = f"{self.base_endpoint}/bytes_count/{flow_id}"
92
        response = await self.api_client.get(endpoint)
93
        assert response.status_code == 404
94
        assert response.json()["description"] == "Flow does not exist"
95 1
96 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.flow_from_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
97
    async def test_bytes_count(self, mock_from_flow):
98 1
        """Test bytes_count rest call."""
99 1
        flow_id = '1'
100 1
        mock_from_flow.return_value = self._get_mocked_flow_base()
101
        self._patch_switch_flow(flow_id)
102 1
103 1
        endpoint = f"{self.base_endpoint}/bytes_count/{flow_id}"
104 1
        response = await self.api_client.get(endpoint)
105 1
        assert response.status_code == 200
106 1
        json_response = response.json()
107 1
        assert json_response["flow_id"] == flow_id
108 1
        assert json_response["bytes_counter"] == 10
109
        assert json_response["bits_per_second"] == 4.0
110 1
111
    async def test_packet_count_per_flow_empty(self):
112 1
        """Test packet_count rest call with a flow that does not exist ."""
113 1
        flow_id = "123456789"
114 1
        endpoint = f"{self.base_endpoint}/packet_count/per_flow/{flow_id}"
115 1
        response = await self.api_client.get(endpoint)
116 1
        assert response.status_code == 200
117
        assert len(response.json()) == 0
118 1
119 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.flow_stats_by_dpid_flow_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
120
    async def test_packet_count_per_flow(self, mock_from_flow):
121 1
        """Test packet_count_per_flow rest call."""
122
        flow_info = {
123
            "byte_count": 10,
124
            "duration_sec": 20,
125
            "duration_nsec": 30,
126
            "packet_count": 40,
127
            "cookie": 12310228866111668291,
128
            "match": {"in_port": 1},
129
            "priority": 32768
130 1
            }
131 1
        flow_id = '6055f13593fad45e0b4699f49d56b105'
132 1
        flow_stats_dict_mock = {flow_id: flow_info}
133 1
        dpid = "00:00:00:00:00:00:00:01"
134 1
        flow_by_sw = {dpid: flow_stats_dict_mock}
135
        mock_from_flow.return_value = flow_by_sw
136 1
137 1
        self._patch_switch_flow(flow_id)
138 1
        endpoint = f"{self.base_endpoint}/packet_count/per_flow/{dpid}"
139
        response = await self.api_client.get(endpoint)
140 1
141 1
        json_response = response.json()
142 1
        assert json_response[0]["flow_id"] == flow_id
143 1
        assert json_response[0]["packet_counter"] == 40
144
        assert json_response[0]["packet_per_second"] == 2.0
145 1
146
    async def test_bytes_count_per_flow__empty(self):
147 1
        """Test bytes_count rest call with a flow that does not exist ."""
148 1
        flow_id = "123456789"
149 1
        endpoint = f"{self.base_endpoint}/bytes_count/per_flow/{flow_id}"
150 1
        response = await self.api_client.get(endpoint)
151 1
        assert response.status_code == 200
152
        assert len(response.json()) == 0
153 1
154 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.flow_stats_by_dpid_flow_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
155
    async def test_bytes_count_per_flow(self, mock_from_flow):
156 1
        """Test bytes_count_per_flow rest call."""
157
        flow_info = {
158
            "byte_count": 10,
159
            "duration_sec": 20,
160
            "duration_nsec": 30,
161
            "packet_count": 40,
162
            "cookie": 12310228866111668291,
163
            "match": {"in_port": 1},
164
            "priority": 32768
165 1
            }
166 1
        flow_id = '6055f13593fad45e0b4699f49d56b105'
167 1
        flow_stats_dict_mock = {flow_id: flow_info}
168 1
        dpid = "00:00:00:00:00:00:00:01"
169 1
        flow_by_sw = {dpid: flow_stats_dict_mock}
170
        mock_from_flow.return_value = flow_by_sw
171 1
172
        self._patch_switch_flow(flow_id)
173 1
174 1
        endpoint = f"{self.base_endpoint}/bytes_count/per_flow/{dpid}"
175 1
        response = await self.api_client.get(endpoint)
176
        assert response.status_code == 200
177 1
178 1
        json_response = response.json()
179 1
        assert json_response[0]["flow_id"] == flow_id
180 1
        assert json_response[0]["bytes_counter"] == 10
181
        assert json_response[0]["bits_per_second"] == 4.0
182 1
183 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.flow_stats_by_dpid_flow_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
184
    async def test_flows_counters_packet(self, mock_from_flow):
185 1
        """Test flows_counters function for packet"""
186
        flow_info = {
187
            "byte_count": 10,
188
            "duration_sec": 20,
189
            "duration_nsec": 30,
190
            "packet_count": 40,
191
            "cookie": 12310228866111668291,
192
            "match": {"in_port": 1},
193
            "priority": 32768
194 1
            }
195 1
        flow_id = '6055f13593fad45e0b4699f49d56b105'
196 1
        flow_stats_dict_mock = {flow_id: flow_info}
197 1
        dpid = "00:00:00:00:00:00:00:01"
198 1
        flow_by_sw = {dpid: flow_stats_dict_mock}
199
        mock_from_flow.return_value = flow_by_sw
200 1
201 1
        endpoint = f"{self.base_endpoint}/packet_count/per_flow/{dpid}"
202 1
        response = await self.api_client.get(endpoint)
203 1
        assert response.status_code == 200
204
        assert len(response.json()) == 1
205 1
206 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.flow_stats_by_dpid_flow_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
207
    async def test_flows_counters_bytes(self, mock_from_flow):
208 1
        """Test flows_counters function for bytes"""
209
        flow_info = {
210
            "byte_count": 10,
211
            "duration_sec": 20,
212
            "duration_nsec": 30,
213
            "packet_count": 40,
214
            "cookie": 12310228866111668291,
215
            "match": {"in_port": 1},
216
            "priority": 32768
217 1
            }
218 1
        flow_id = '6055f13593fad45e0b4699f49d56b105'
219 1
        flow_stats_dict_mock = {flow_id: flow_info}
220 1
        dpid = "00:00:00:00:00:00:00:01"
221 1
        flow_by_sw = {dpid: flow_stats_dict_mock}
222
        mock_from_flow.return_value = flow_by_sw
223 1
224 1
        endpoint = f"{self.base_endpoint}/bytes_count/per_flow/{dpid}"
225 1
        response = await self.api_client.get(endpoint)
226 1
        assert response.status_code == 200
227
        assert len(response.json()) == 1
228 1
229 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.flow_stats_by_dpid_flow_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
230
    async def test_flow_stats_by_dpid_flow_id(self, mock_from_flow):
231 1
        """Test flow_stats rest call."""
232
        flow_info = {
233
            "byte_count": 10,
234
            "duration_sec": 20,
235
            "duration_nsec": 30,
236
            "packet_count": 40,
237
            "cookie": 12310228866111668291,
238
            "match": {"in_port": 1},
239
            "priority": 32768
240 1
            }
241 1
        flow_stats_dict_mock = {'6055f13593fad45e0b4699f49d56b105': flow_info}
242 1
        flow_by_sw = {"00:00:00:00:00:00:00:01": flow_stats_dict_mock}
243
        mock_from_flow.return_value = flow_by_sw
244 1
245 1
        endpoint = "/flow/stats?dpid=00:00:00:00:00:00:00:01"
246 1
        url = f"{self.base_endpoint}{endpoint}"
247 1
        response = await self.api_client.get(url)
248 1
        assert response.status_code == 200
249 1
        expected = flow_by_sw
250
        assert response.json() == expected
251 1
252 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.flow_stats_by_dpid_flow_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
253
    async def test_flow_stats_by_dpid_flow_id_without_dpid(self,
254
                                                           mock_from_flow):
255 1
        """Test flow_stats rest call."""
256
        flow_info = {
257
            "byte_count": 10,
258
            "duration_sec": 20,
259
            "duration_nsec": 30,
260
            "packet_count": 40,
261
            "cookie": 12310228866111668291,
262
            "match": {"in_port": 1},
263
            "priority": 32768
264 1
            }
265 1
        flow_stats_dict_mock = {'6055f13593fad45e0b4699f49d56b105': flow_info}
266 1
        flow_by_sw = {"00:00:00:00:00:00:00:01": flow_stats_dict_mock}
267
        mock_from_flow.return_value = flow_by_sw
268 1
269 1
        endpoint = "/flow/stats"
270 1
        url = f"{self.base_endpoint}{endpoint}"
271 1
        response = await self.api_client.get(url)
272
        assert response.status_code == 200
273 1
274 1
        expected = flow_by_sw
275
        assert response.json() == expected
276 1
277 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.flow_stats_by_dpid_flow_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
278
    async def test_flow_stats_by_dpid_flow_id_with_dpid(self, mock_from_flow):
279 1
        """Test flow_stats rest call."""
280
        flow_info = {
281
            "byte_count": 10,
282
            "duration_sec": 20,
283
            "duration_nsec": 30,
284
            "packet_count": 40,
285
            "cookie": 12310228866111668291,
286
            "match": {"in_port": 1},
287
            "priority": 32768
288 1
            }
289 1
        flow_stats_dict_mock = {'6055f13593fad45e0b4699f49d56b105': flow_info}
290 1
        flow_by_sw = {"00:00:00:00:00:00:00:01": flow_stats_dict_mock}
291
        mock_from_flow.return_value = flow_by_sw
292 1
293 1
        endpoint = "/flow/stats?dpid=00:00:00:00:00:00:00:01"
294 1
        url = f"{self.base_endpoint}{endpoint}"
295 1
        response = await self.api_client.get(url)
296
        assert response.status_code == 200
297 1
298 1
        expected = flow_by_sw
299
        assert response.json() == expected
300 1
301 1
    @patch("napps.amlight.kytos_stats.main.Main.flow_stats_by_dpid_flow_id")
302
    async def test_flow_stats_by_dpid_flow_id_not_found(self, mock_from_flow):
303 1
        """Test flow_stats rest call."""
304 1
        flow_by_sw = {}
305 1
        mock_from_flow.return_value = flow_by_sw
306 1
        endpoint = "/flow/stats?dpid=00:00:00:00:00:00:00:01"
307 1
        url = f"{self.base_endpoint}{endpoint}"
308 1
        response = await self.api_client.get(url)
309 1
        assert response.status_code == 200
310
        assert len(response.json()) == 0
311 1
312 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.table_stats_by_dpid_table_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
313
    async def test_table_stats_by_dpid_table_id(self, mock_from_table):
314 1
        """Test table_stats rest call."""
315
        table_info = {
316
            "table_id": 10,
317
            "active_count": 20,
318
            "lookup_count": 30,
319
            "matched_count": 32768
320 1
            }
321 1
        table_stats_dict_mock = {'10': table_info}
322 1
        table_by_sw = {"00:00:00:00:00:00:00:01": table_stats_dict_mock}
323
        mock_from_table.return_value = table_by_sw
324 1
325 1
        endpoint = "/table/stats?dpid=00:00:00:00:00:00:00:01&table=10"
326 1
        url = f"{self.base_endpoint}{endpoint}"
327 1
        response = await self.api_client.get(url)
328 1
        assert response.status_code == 200
329 1
        expected = table_by_sw
330
        assert response.json() == expected
331 1
332 1
    async def test_port_stats_filter(self):
333
        """Test table_stats rest call."""
334
        self.napp.port_stats_dict = {
335 1
            "0x1": {
336
                1: {
337
                    "port_no": 1,
338
                },
339
                2: {
340
                    "port_no": 2,
341 1
                },
342 1
            },
343 1
            "0x2": {
344
                99: {
345 1
                    "port_no": 99,
346 1
                },
347 1
            },
348 1
        }
349
        expected_result = {}
350 1
        for dpid, sw in self.napp.port_stats_dict.items():
351 1
            expected_result[dpid] = {}
352
            for port_no, port in sw.items():
353 1
                expected_result[dpid][str(port_no)] = port
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable str does not seem to be defined.
Loading history...
354 1
355
        endpoint = "/port/stats"
356
        url = f"{self.base_endpoint}{endpoint}"
357 1
        response = await self.api_client.get(url)
358 1
        assert response.status_code == 200
359 1
        assert response.json() == expected_result
360 1
361 1
        endpoint = "/port/stats?dpid=0x1&port=1"
362 1
        url = f"{self.base_endpoint}{endpoint}"
363 1
        response = await self.api_client.get(url)
364
        assert response.status_code == 200
365 1
        data = response.json()
366
        assert len(data) == 1
367
        assert "0x1" in data
368 1
        assert len(data["0x1"]) == 1
369 1
        assert "1" in data["0x1"]
370 1
371 1
        endpoint = "/port/stats?dpid=0x1&port=a"
372 1
        url = f"{self.base_endpoint}{endpoint}"
373 1
        response = await self.api_client.get(url)
374
        assert response.status_code == 400
375 1
        data = response.json()
376
        desc = data["description"]
377 1
        assert "'port' value is supposed to be an integer" in desc
378 1
379 1
    async def test_on_port_stats(self):
380 1
        """Test handle_stats_received function."""
381 1
        expected_dict = {
382 1
            "00:00:00:00:00:00:00:01": {
383 1
                1: {
384
                    "port_no": 1,
385 1
                    "rx_packets": 0,
386
                    "tx_packets": 0,
387 1
                    "rx_bytes": 0,
388
                    "tx_bytes": 0,
389 1
                    "rx_dropped": 0,
390 1
                    "tx_dropped": 0,
391
                    "rx_errors": 0,
392 1
                    "tx_errors": 0,
393 1
                    "rx_frame_err": 0,
394
                    "rx_over_err": 0,
395 1
                    "rx_crc_err": 0,
396
                    "collisions": 0,
397 1
                    "duration_sec": 0,
398 1
                    "duration_nsec": 0,
399 1
                },
400 1
            },
401 1
        }
402
403 1
        name = "kytos/of_core.port_stats"
404 1
        event = get_kytos_event_mock(name=name, content={})
405
406 1
        await self.napp.on_port_stats(event)
407
408 1
        assert not self.napp.port_stats_dict
409 1
410 1
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
411 1
        switch.id = switch.dpid
412 1
        port_stats = self._get_mocked_port_stat(port_no=1)
413 1
        content = {"switch": switch, "port_stats": [port_stats]}
414 1
415 1
        event = get_kytos_event_mock(name=name, content=content)
416 1
417 1
        await self.napp.on_port_stats(event)
418 1
419
        assert self.napp.port_stats_dict == expected_dict
420 1
421 1 View Code Duplication
    @patch("napps.amlight.kytos_stats.main.Main.table_stats_by_dpid_table_id")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
422
    async def test_table_stats_by_dpid_table_id_without_dpid(self,
423
                                                             mock_from_table):
424 1
        """Test table_stats rest call."""
425 1
        table_info = {
426 1
            "table_id": 10,
427 1
            "active_count": 20,
428
            "lookup_count": 30,
429 1
            "matched_count": 32768
430
            }
431 1
        table_stats_dict_mock = {'10': table_info}
432 1
        table_by_sw = {"00:00:00:00:00:00:00:01": table_stats_dict_mock}
433
        mock_from_table.return_value = table_by_sw
434 1
435 1
        endpoint = "/table/stats"
436
        url = f"{self.base_endpoint}{endpoint}"
437
        response = await self.api_client.get(url)
438
        assert response.status_code == 200
439 1
440 1
        expected = table_by_sw
441 1
        assert response.json() == expected
442
443 1
    @patch("napps.amlight.kytos_stats.main.Main.table_stats_by_dpid_table_id")
444
    async def test_table_stats_by_dpid_table_id_not_found(self,
445 1
                                                          mock_from_table):
446 1
        """Test table_stats rest call."""
447
        table_by_sw = {}
448 1
        mock_from_table.return_value = table_by_sw
449
        endpoint = "/flow/stats?dpid=00:00:00:00:00:00:00:01"
450
        url = f"{self.base_endpoint}{endpoint}"
451 1
        response = await self.api_client.get(url)
452 1
        assert response.status_code == 200
453
        assert len(response.json()) == 0
454 1
455
    def _patch_switch_flow(self, flow_id):
456 1
        """Helper method to patch controller to return switch/flow data."""
457 1
        # patching the flow_stats object in the switch
458
        flow = self._get_mocked_flow_stats()
459
        flow.id = flow_id
460 1
        switch = MagicMock()
461 1
        self.napp.controller.switches = {"1": switch}
462 1
        self.napp.controller.get_switch_by_dpid = MagicMock()
463 1
        self.napp.controller.get_switch_by_dpid.return_value = switch
464
465 1
    def _get_mocked_flow_stats(self):
466
        """Helper method to create a mock flow_stats object."""
467 1
        flow_stats = MagicMock()
468 1
        flow_stats.id = 123
469
        flow_stats.byte_count = 10
470 1
        flow_stats.duration_sec = 20
471
        flow_stats.duration_nsec = 30
472
        flow_stats.packet_count = 40
473 1
        return flow_stats
474 1
475 1
    def _get_mocked_multipart_replies_flows(self):
476 1
        """Helper method to create mock multipart replies flows"""
477
        flow = self._get_mocked_flow_base()
478 1
479 1
        instruction = MagicMock()
480
        flow.instructions = [instruction]
481 1
482
        replies_flows = [flow]
483
        return replies_flows
484
485
    def _get_mocked_multipart_replies_tables(self):
486 1
        """Helper method to create mock multipart replies tables"""
487 1
        table = MagicMock()
488 1
        table.table_id = 10
489 1
        table.active_count = 0
490 1
        table.lookup_count = 0
491
        table.matched_count = 0
492 1
493 1
        replies_tables = [table]
494 1
        return replies_tables
495 1
496 1
    def _get_mocked_port_stat(self, **kwargs):
497 1
        """Helper method to create mock port stats."""
498
        port_stats = MagicMock()
499 1
        port_stats.port_no.value = kwargs.get("port_no", 0)
500 1
        port_stats.rx_packets.value = kwargs.get("rx_packets", 0)
501 1
        port_stats.tx_packets.value = kwargs.get("tx_packets", 0)
502 1
        port_stats.rx_bytes.value = kwargs.get("rx_bytes", 0)
503 1
        port_stats.tx_bytes.value = kwargs.get("tx_bytes", 0)
504
        port_stats.rx_dropped.value = kwargs.get("rx_dropped", 0)
505
        port_stats.tx_dropped.value = kwargs.get("tx_dropped", 0)
506
        port_stats.rx_errors.value = kwargs.get("rx_errors", 0)
507
        port_stats.tx_errors.value = kwargs.get("tx_errors", 0)
508
        port_stats.rx_frame_err.value = kwargs.get("rx_frame_err", 0)
509
        port_stats.rx_over_err.value = kwargs.get("rx_over_err", 0)
510
        port_stats.rx_crc_err.value = kwargs.get("rx_crc_err", 0)
511
        port_stats.collisions.value = kwargs.get("collisions", 0)
512
        port_stats.duration_sec.value = kwargs.get("duration_sec", 0)
513
        port_stats.duration_nsec.value = kwargs.get("duration_nsec", 0)
514
        return port_stats
515
516
    def _get_mocked_flow_base(self):
517
        """Helper method to create a mock flow object."""
518
        flow = MagicMock()
519
        flow.id = 456
520
        flow.switch = None
521
        flow.table_id = None
522
        flow.match = None
523
        flow.priority = None
524
        flow.idle_timeout = None
525
        flow.hard_timeout = None
526
        flow.cookie = None
527
        flow.stats = self._get_mocked_flow_stats()
528
        return flow
529
530
    @patch("napps.amlight.kytos_stats.main.Main.handle_stats_reply_received")
531
    def test_handle_stats_received(self, mock_handle_stats):
532
        """Test handle_stats_received function."""
533
534
        switch_v0x04 = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
535
        replies_flows = self._get_mocked_multipart_replies_flows()
536
        name = "kytos/of_core.flow_stats.received"
537
        content = {"switch": switch_v0x04, "replies_flows": replies_flows}
538
539
        event = get_kytos_event_mock(name=name, content=content)
540
541
        self.napp.handle_stats_received(event)
542
        mock_handle_stats.assert_called_once()
543
544
    @patch("napps.amlight.kytos_stats.main.Main.handle_stats_reply_received")
545
    def test_handle_stats_received__fail(self, mock_handle_stats):
546
        """Test handle_stats_received function for
547
        fail when replies_flows is not in content."""
548
549
        switch_v0x04 = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
550
        name = "kytos/of_core.flow_stats.received"
551
        content = {"switch": switch_v0x04}
552
553
        event = get_kytos_event_mock(name=name, content=content)
554
555
        self.napp.handle_stats_received(event)
556
        mock_handle_stats.assert_not_called()
557
558
    def test_handle_stats_reply_received(self):
559
        """Test handle_stats_reply_received call."""
560
561
        flows_mock = self._get_mocked_multipart_replies_flows()
562
        self.napp.handle_stats_reply_received(flows_mock)
563
564
        assert list(self.napp.flows_stats_dict.values())[0].id == 456
565
566
    @patch("napps.amlight.kytos_stats.main.Main.handle_table_stats_received")
567
    def test_handle_table_stats_received(self, mock_handle_stats):
568
        """Test handle_table_stats_received function."""
569
570
        switch_v0x04 = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
571
        replies_tables = self._get_mocked_multipart_replies_tables()
572
        name = "kytos/of_core.table_stats.received"
573
        content = {"switch": switch_v0x04, "replies_tables": replies_tables}
574
575
        event = get_kytos_event_mock(name=name, content=content)
576
577
        self.napp.handle_table_stats_received(event)
578
        mock_handle_stats.assert_called_once()
579
580
    def test_handle_table_stats_reply_received(self):
581
        """Test handle_table_stats_reply_received call."""
582
583
        tables_mock = self._get_mocked_multipart_replies_tables()
584
        self.napp.handle_table_stats_reply_received(tables_mock)
585
        table = list(self.napp.tables_stats_dict.values())[0]
586
        assert list(table.keys())[0] == 10
587
588
    @patch("napps.amlight.kytos_stats.main.Main.flow_stats_by_dpid_flow_id")
589
    async def test_flows_counters_div_zero(self, mock_from_flow):
590
        """Test that there is no error due to division by zero."""
591
        flow_info = {
592
            "byte_count": 10,
593
            "packet_count": 20,
594
            "duration_sec": 0
595
            }
596
        flow_id = '6055f13593fad45e0b4699f49d56b105'
597
        flow_stats_dict_mock = {flow_id: flow_info}
598
        dpid = "00:00:00:00:00:00:00:01"
599
        flow_by_sw = {dpid: flow_stats_dict_mock}
600
        mock_from_flow.return_value = flow_by_sw
601
602
        self._patch_switch_flow(flow_id)
603
        endpoint = f"{self.base_endpoint}/packet_count/per_flow/{dpid}"
604
        response = await self.api_client.get(endpoint)
605
        response = response.json()
606
        assert response[0]["flow_id"] == flow_id
607
        assert response[0]["packet_per_second"] == 0
608
609
        endpoint = f"{self.base_endpoint}/bytes_count/per_flow/{dpid}"
610
        response = await self.api_client.get(endpoint)
611
        response = response.json()
612
        assert response[0]["flow_id"] == flow_id
613
        assert response[0]["bits_per_second"] == 0
614