Test Failed
Pull Request — master (#25)
by Vinicius
04:34
created

unit.test_main.TestMain.test_handle_port_stats()   A

Complexity

Conditions 1

Size

Total Lines 41
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 41
ccs 30
cts 30
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
    def test_handle_port_stats(self):
372 1
        """Test handle_stats_received function."""
373 1
        expected_dict = {
374
            "00:00:00:00:00:00:00:01": {
375 1
                1: {
376
                    "port_no": 1,
377 1
                    "rx_packets": 0,
378 1
                    "tx_packets": 0,
379 1
                    "rx_bytes": 0,
380 1
                    "tx_bytes": 0,
381 1
                    "rx_dropped": 0,
382 1
                    "tx_dropped": 0,
383 1
                    "rx_errors": 0,
384
                    "tx_errors": 0,
385 1
                    "rx_frame_err": 0,
386
                    "rx_over_err": 0,
387 1
                    "rx_crc_err": 0,
388
                    "collisions": 0,
389 1
                    "duration_sec": 0,
390 1
                    "duration_nsec": 0,
391
                },
392 1
            },
393 1
        }
394
395 1
        name = "kytos/of_core.port_stats"
396
        event = get_kytos_event_mock(name=name, content={})
397 1
398 1
        self.napp.handle_port_stats(event)
399 1
400 1
        assert not self.napp.port_stats_dict
401 1
402
        switch = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
403 1
        switch.id = switch.dpid
404 1
        port_stats = self._get_mocked_port_stat(port_no=1)
405
        content = {"switch": switch, "port_stats": [port_stats]}
406 1
407
        event = get_kytos_event_mock(name=name, content=content)
408 1
409 1
        self.napp.handle_port_stats(event)
410 1
411 1
        assert self.napp.port_stats_dict == expected_dict
412 1
413 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...
414 1
    async def test_table_stats_by_dpid_table_id_without_dpid(self,
415 1
                                                             mock_from_table):
416 1
        """Test table_stats rest call."""
417 1
        table_info = {
418 1
            "table_id": 10,
419
            "active_count": 20,
420 1
            "lookup_count": 30,
421 1
            "matched_count": 32768
422
            }
423
        table_stats_dict_mock = {'10': table_info}
424 1
        table_by_sw = {"00:00:00:00:00:00:00:01": table_stats_dict_mock}
425 1
        mock_from_table.return_value = table_by_sw
426 1
427 1
        endpoint = "/table/stats"
428
        url = f"{self.base_endpoint}{endpoint}"
429 1
        response = await self.api_client.get(url)
430
        assert response.status_code == 200
431 1
432 1
        expected = table_by_sw
433
        assert response.json() == expected
434 1
435 1
    @patch("napps.amlight.kytos_stats.main.Main.table_stats_by_dpid_table_id")
436
    async def test_table_stats_by_dpid_table_id_not_found(self,
437
                                                          mock_from_table):
438
        """Test table_stats rest call."""
439 1
        table_by_sw = {}
440 1
        mock_from_table.return_value = table_by_sw
441 1
        endpoint = "/flow/stats?dpid=00:00:00:00:00:00:00:01"
442
        url = f"{self.base_endpoint}{endpoint}"
443 1
        response = await self.api_client.get(url)
444
        assert response.status_code == 200
445 1
        assert len(response.json()) == 0
446 1
447
    def _patch_switch_flow(self, flow_id):
448 1
        """Helper method to patch controller to return switch/flow data."""
449
        # patching the flow_stats object in the switch
450
        flow = self._get_mocked_flow_stats()
451 1
        flow.id = flow_id
452 1
        switch = MagicMock()
453
        self.napp.controller.switches = {"1": switch}
454 1
        self.napp.controller.get_switch_by_dpid = MagicMock()
455
        self.napp.controller.get_switch_by_dpid.return_value = switch
456 1
457 1
    def _get_mocked_flow_stats(self):
458
        """Helper method to create a mock flow_stats object."""
459
        flow_stats = MagicMock()
460 1
        flow_stats.id = 123
461 1
        flow_stats.byte_count = 10
462 1
        flow_stats.duration_sec = 20
463 1
        flow_stats.duration_nsec = 30
464
        flow_stats.packet_count = 40
465 1
        return flow_stats
466
467 1
    def _get_mocked_multipart_replies_flows(self):
468 1
        """Helper method to create mock multipart replies flows"""
469
        flow = self._get_mocked_flow_base()
470 1
471
        instruction = MagicMock()
472
        flow.instructions = [instruction]
473 1
474 1
        replies_flows = [flow]
475 1
        return replies_flows
476 1
477
    def _get_mocked_multipart_replies_tables(self):
478 1
        """Helper method to create mock multipart replies tables"""
479 1
        table = MagicMock()
480
        table.table_id = 10
481 1
        table.active_count = 0
482
        table.lookup_count = 0
483
        table.matched_count = 0
484
485
        replies_tables = [table]
486 1
        return replies_tables
487 1
488 1
    def _get_mocked_port_stat(self, **kwargs):
489 1
        """Helper method to create mock port stats."""
490 1
        port_stats = MagicMock()
491
        port_stats.port_no.value = kwargs.get("port_no", 0)
492 1
        port_stats.rx_packets.value = kwargs.get("rx_packets", 0)
493 1
        port_stats.tx_packets.value = kwargs.get("tx_packets", 0)
494 1
        port_stats.rx_bytes.value = kwargs.get("rx_bytes", 0)
495 1
        port_stats.tx_bytes.value = kwargs.get("tx_bytes", 0)
496 1
        port_stats.rx_dropped.value = kwargs.get("rx_dropped", 0)
497 1
        port_stats.tx_dropped.value = kwargs.get("tx_dropped", 0)
498
        port_stats.rx_errors.value = kwargs.get("rx_errors", 0)
499 1
        port_stats.tx_errors.value = kwargs.get("tx_errors", 0)
500 1
        port_stats.rx_frame_err.value = kwargs.get("rx_frame_err", 0)
501 1
        port_stats.rx_over_err.value = kwargs.get("rx_over_err", 0)
502 1
        port_stats.rx_crc_err.value = kwargs.get("rx_crc_err", 0)
503 1
        port_stats.collisions.value = kwargs.get("collisions", 0)
504
        port_stats.duration_sec.value = kwargs.get("duration_sec", 0)
505
        port_stats.duration_nsec.value = kwargs.get("duration_nsec", 0)
506
        return port_stats
507
508
    def _get_mocked_flow_base(self):
509
        """Helper method to create a mock flow object."""
510
        flow = MagicMock()
511
        flow.id = 456
512
        flow.switch = None
513
        flow.table_id = None
514
        flow.match = None
515
        flow.priority = None
516
        flow.idle_timeout = None
517
        flow.hard_timeout = None
518
        flow.cookie = None
519
        flow.stats = self._get_mocked_flow_stats()
520
        return flow
521
522
    @patch("napps.amlight.kytos_stats.main.Main.handle_stats_reply_received")
523
    def test_handle_stats_received(self, mock_handle_stats):
524
        """Test handle_stats_received function."""
525
526
        switch_v0x04 = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
527
        replies_flows = self._get_mocked_multipart_replies_flows()
528
        name = "kytos/of_core.flow_stats.received"
529
        content = {"switch": switch_v0x04, "replies_flows": replies_flows}
530
531
        event = get_kytos_event_mock(name=name, content=content)
532
533
        self.napp.handle_stats_received(event)
534
        mock_handle_stats.assert_called_once()
535
536
    @patch("napps.amlight.kytos_stats.main.Main.handle_stats_reply_received")
537
    def test_handle_stats_received__fail(self, mock_handle_stats):
538
        """Test handle_stats_received function for
539
        fail when replies_flows is not in content."""
540
541
        switch_v0x04 = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
542
        name = "kytos/of_core.flow_stats.received"
543
        content = {"switch": switch_v0x04}
544
545
        event = get_kytos_event_mock(name=name, content=content)
546
547
        self.napp.handle_stats_received(event)
548
        mock_handle_stats.assert_not_called()
549
550
    def test_handle_stats_reply_received(self):
551
        """Test handle_stats_reply_received call."""
552
553
        flows_mock = self._get_mocked_multipart_replies_flows()
554
        self.napp.handle_stats_reply_received(flows_mock)
555
556
        assert list(self.napp.flows_stats_dict.values())[0].id == 456
557
558
    @patch("napps.amlight.kytos_stats.main.Main.handle_table_stats_received")
559
    def test_handle_table_stats_received(self, mock_handle_stats):
560
        """Test handle_table_stats_received function."""
561
562
        switch_v0x04 = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
563
        replies_tables = self._get_mocked_multipart_replies_tables()
564
        name = "kytos/of_core.table_stats.received"
565
        content = {"switch": switch_v0x04, "replies_tables": replies_tables}
566
567
        event = get_kytos_event_mock(name=name, content=content)
568
569
        self.napp.handle_table_stats_received(event)
570
        mock_handle_stats.assert_called_once()
571
572
    def test_handle_table_stats_reply_received(self):
573
        """Test handle_table_stats_reply_received call."""
574
575
        tables_mock = self._get_mocked_multipart_replies_tables()
576
        self.napp.handle_table_stats_reply_received(tables_mock)
577
        table = list(self.napp.tables_stats_dict.values())[0]
578
        assert list(table.keys())[0] == 10
579
580
    @patch("napps.amlight.kytos_stats.main.Main.flow_stats_by_dpid_flow_id")
581
    async def test_flows_counters_div_zero(self, mock_from_flow):
582
        """Test that there is no error due to division by zero."""
583
        flow_info = {
584
            "byte_count": 10,
585
            "packet_count": 20,
586
            "duration_sec": 0
587
            }
588
        flow_id = '6055f13593fad45e0b4699f49d56b105'
589
        flow_stats_dict_mock = {flow_id: flow_info}
590
        dpid = "00:00:00:00:00:00:00:01"
591
        flow_by_sw = {dpid: flow_stats_dict_mock}
592
        mock_from_flow.return_value = flow_by_sw
593
594
        self._patch_switch_flow(flow_id)
595
        endpoint = f"{self.base_endpoint}/packet_count/per_flow/{dpid}"
596
        response = await self.api_client.get(endpoint)
597
        response = response.json()
598
        assert response[0]["flow_id"] == flow_id
599
        assert response[0]["packet_per_second"] == 0
600
601
        endpoint = f"{self.base_endpoint}/bytes_count/per_flow/{dpid}"
602
        response = await self.api_client.get(endpoint)
603
        response = response.json()
604
        assert response[0]["flow_id"] == flow_id
605
        assert response[0]["bits_per_second"] == 0
606