Test Failed
Pull Request — master (#114)
by Aldo
03:48
created

TestTracePath.test_send_trace_probe()   B

Complexity

Conditions 1

Size

Total Lines 57
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 37
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 40
nop 5
dl 0
loc 57
ccs 37
cts 37
cp 1
crap 1
rs 8.92
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
"""
2
    Test tracing.trace_entries
3
"""
4
5 1
from unittest.mock import MagicMock, patch
6 1
import time
7 1
import pytest
8 1
from napps.amlight.sdntrace.tracing.trace_msg import TraceMsg
9 1
from napps.amlight.sdntrace.tracing.trace_manager import TraceManager
10 1
from napps.amlight.sdntrace.tracing.tracer import TracePath
11
from napps.amlight.sdntrace.tracing.rest import FormatRest
12 1
from napps.amlight.sdntrace.shared.switches import Switches
13
14
from kytos.lib.helpers import get_controller_mock
15
16
17 1
# pylint: disable=too-many-public-methods, too-many-lines,
18
# pylint: disable=protected-access, too-many-locals
19
class TestTracePath:
20 1
    """Test all combinations for DPID"""
21 1
22
    @pytest.fixture(autouse=True)
23
    def commomn_patches(self, request):
24
        """This function handles setup and cleanup for patches"""
25
        # This fixture sets up the common patches,
26
        # and a finalizer is added using addfinalizer to stop
27
        # the common patches after each test. This ensures that the cleanup
28
        # is performed after each test, and additional patch decorators
29 1
        # can be used within individual test functions.
30 1
31
        patcher = patch("kytos.core.helpers.run_on_thread", lambda x: x)
32 1
        mock_patch = patcher.start()
33
34 1
        _ = request.function.__name__
35 1
36
        def cleanup():
37 1
            patcher.stop()
38 1
39
        request.addfinalizer(cleanup)
40 1
        return mock_patch
41
42 1
    def setup_method(self):
43
        """Set up before each test method"""
44 1
        TraceManager.run_traces = MagicMock()
45 1
        self.trace_manager = TraceManager(controller=get_controller_mock())
46 1
47 1
        # This variable is used to initiate the Singleton class so
48 1
        # these tests can run on their own.
49
        self._auxiliar = Switches(MagicMock())
50
51
    @patch("napps.amlight.sdntrace.shared.colors.Colors.get_switch_color")
52
    @patch("napps.amlight.sdntrace.shared.colors.Colors.aget_switch_color")
53 1
    @patch("napps.amlight.sdntrace.shared.switches.Switches.get_switch")
54
    @patch("napps.amlight.sdntrace.tracing.tracer.TracePath.tracepath_loop")
55 1
    async def test_tracepath(
56 1
        self,
57 1
        mock_trace_loop,
58
        mock_get_switch,
59
        mock_aswitch_colors,
60 1
        mock_switch_colors,
61
    ):
62
        """Test tracepath initial result item. Mocking tracepath loop
63 1
        to get just one step."""
64
        mock_switch_colors.return_value = "ee:ee:ee:ee:ee:01"
65
        mock_aswitch_colors.return_value = "ee:ee:ee:ee:ee:01"
66 1
67 1
        switch = MagicMock()
68 1
        switch.dpid = "00:00:00:00:00:00:00:01"
69 1
        mock_get_switch.return_value = switch
70 1
71
        # Mock tracepath loop to create only the initial result item
72 1
        mock_trace_loop.return_value = True
73 1
74
        # Trace id to recover the result
75
        trace_id = 111
76 1
77
        # Creating trace entries
78 1
        eth = {"dl_vlan": 100}
79 1
        dpid = {"dpid": "00:00:00:00:00:00:00:01", "in_port": 1}
80 1
        switch = {"switch": dpid, "eth": eth}
81 1
        entries = {"trace": switch}
82 1
        trace_entries = self.trace_manager.is_entry_valid(entries)
83
84 1
        tracer = TracePath(self.trace_manager, trace_id, trace_entries)
85 1
        await tracer.tracepath()
86 1
87 1
        # Retrieve trace result created from tracepath
88 1
        result = self.trace_manager.get_result(trace_id)
89
90 1
        assert result["request_id"] == 111
91 1
        assert len(result["result"]) == 1
92 1
        assert result["result"][0]["type"] == "starting"
93 1
        assert result["result"][0]["dpid"] == dpid["dpid"]
94 1
        assert result["result"][0]["port"] == dpid["in_port"]
95
96
        assert result["request"]["trace"]["switch"]["dpid"] == dpid["dpid"]
97
        assert result["request"]["trace"]["switch"]["in_port"] == dpid["in_port"]
98
        assert result["request"]["trace"]["eth"]["dl_vlan"] == eth["dl_vlan"]
99 1
        assert mock_switch_colors.call_count == 1
100
        assert mock_aswitch_colors.call_count == 1
101
102 1
    @patch("napps.amlight.sdntrace.shared.colors.Colors.aget_switch_color")
103 1
    @patch("napps.amlight.sdntrace.shared.colors.Colors.get_switch_color")
104 1
    @patch("napps.amlight.sdntrace.shared.switches.Switches.get_switch")
105 1
    @patch("napps.amlight.sdntrace.tracing.tracer.TracePath.tracepath_loop")
106
    async def test_tracepath_result(
107 1
        self, mock_trace_loop, mock_get_switch, mock_switch_colors, mock_aswitch_colors
108
    ):
109
        """Test tracepath initial result item. Patching the tracepath loop
110 1
        to test multiple steps."""
111
        mock_switch_colors.return_value = "ee:ee:ee:ee:ee:01"
112
        mock_aswitch_colors.return_value = "ee:ee:ee:ee:ee:01"
113 1
114 1
        # Patch Switches.get_switch
115 1
        def wrap_get_switch(dpid):
116 1
            switch = MagicMock()
117 1
            switch.dpid = dpid
118
            return switch
119 1
120
        mock_get_switch.side_effect = wrap_get_switch
121
122
        # Trace id to recover the result
123 1
        trace_id = 111
124 1
125 1
        # Creating trace entries
126
        eth = {"dl_vlan": 100}
127
        dpid = {"dpid": "00:00:00:00:00:00:00:01", "in_port": 1}
128
        switch = {"switch": dpid, "eth": eth}
129
        entries = {"trace": switch}
130
        trace_entries = self.trace_manager.is_entry_valid(entries)
131 1
132
        tracer = TracePath(self.trace_manager, trace_id, trace_entries)
133 1
134
        # Patch tracepath loop to create a second result item
135
        # pylint: disable=unused-argument
136 1
        def wrap_tracepath_loop(entries, color, switch):
137
            rest = FormatRest()
138
            rest.add_trace_step(
139 1
                tracer.trace_result,
140
                trace_type="trace",
141 1
                dpid="00:00:00:00:00:00:00:03",
142 1
                port=3,
143 1
            )
144 1
            return True
145 1
146
        mock_trace_loop.side_effect = wrap_tracepath_loop
147 1
148 1
        # Execute tracepath
149 1
        await tracer.tracepath()
150
151 1
        # Retrieve trace result created from tracepath
152 1
        result = self.trace_manager.get_result(trace_id)
153 1
154 1
        assert result["request_id"] == 111
155 1
        assert len(result["result"]) == 2
156
        assert result["result"][0]["type"] == "starting"
157 1
        assert result["result"][0]["dpid"] == dpid["dpid"]
158 1
        assert result["result"][0]["port"] == dpid["in_port"]
159 1
160 1
        assert result["result"][1]["type"] == "trace"
161 1
        assert result["result"][1]["dpid"] == "00:00:00:00:00:00:00:03"
162 1
        assert result["result"][1]["port"] == 3
163
164
        assert result["request"]["trace"]["switch"]["dpid"] == dpid["dpid"]
165
        assert result["request"]["trace"]["switch"]["in_port"] == dpid["in_port"]
166
        assert result["request"]["trace"]["eth"]["dl_vlan"] == eth["dl_vlan"]
167
        assert mock_switch_colors.call_count == 1
168
        assert mock_aswitch_colors.call_count == 1
169
170
    @patch("napps.amlight.sdntrace.shared.colors.Colors.get_switch_color")
171 1
    @patch("napps.amlight.sdntrace.shared.switches.Switches.get_switch")
172
    @patch("napps.amlight.sdntrace.tracing.tracer.TracePath.tracepath_loop")
173 1
    @patch("napps.amlight.sdntrace.tracing.tracer.send_packet_out")
174
    async def test_send_trace_probe(
175 1
        self,
176 1
        mock_send_packet_out,
177 1
        mock_trace_loop,
178
        mock_get_switch,
179
        mock_switch_colors,
180 1
    ):
181
        """Test send_trace_probe send and receive."""
182
        mock_switch_colors.return_value = "ee:ee:ee:ee:ee:01"
183 1
184 1
        mock_send_packet_out.return_value = True
185 1
186 1
        switch_obj = MagicMock()
187 1
        switch_obj.dpid = "00:00:00:00:00:00:00:01"
188 1
        mock_get_switch.return_value = switch_obj
189 1
190 1
        # Mock tracepath loop to create only the initial result item
191 1
        mock_trace_loop.return_value = True
192
193
        # Creating a fake packet in
194 1
        msg = TraceMsg()
195
        msg.request_id = 111
196
        pkt_in = {}
197 1
        pkt_in["dpid"] = "00:00:00:00:00:00:00:01"
198 1
        pkt_in["in_port"] = 1
199 1
        pkt_in["msg"] = msg
200 1
        pkt_in["ethernet"] = "fake_ethernet_object"
201 1
        pkt_in["event"] = "fake_event_object"
202
        self.trace_manager.trace_pkt_in = [pkt_in]
203 1
204
        # Trace id to recover the result
205 1
        trace_id = 111
206 1
207
        # Creating trace entries
208 1
        eth = {"dl_vlan": 100, "dl_type": 2048}
209
        dpid = {"dpid": "00:00:00:00:00:00:00:01", "in_port": 1}
210 1
        switch = {"switch": dpid, "eth": eth}
211
        entries = {"trace": switch}
212 1
        trace_entries = self.trace_manager.is_entry_valid(entries)
213 1
214 1
        tracer = TracePath(self.trace_manager, trace_id, trace_entries)
215 1
216 1
        in_port = 1
217
        probe_pkt = MagicMock()
218 1
219 1
        result = await tracer.send_trace_probe(switch_obj, in_port, probe_pkt)
220 1
221 1
        mock_send_packet_out.assert_called_once()
222 1
223 1
        assert result[0]["dpid"] == "00:00:00:00:00:00:00:01"
224
        assert result[0]["port"] == 1
225
        assert result[1] == "fake_event_object"
226
        mock_switch_colors.assert_called_once()
227
228
    @patch("napps.amlight.sdntrace.shared.colors.Colors.get_switch_color")
229
    @patch("napps.amlight.sdntrace.shared.switches.Switches.get_switch")
230
    @patch("napps.amlight.sdntrace.tracing.tracer.TracePath.tracepath_loop")
231
    @patch("napps.amlight.sdntrace.tracing.tracer.send_packet_out")
232 1
    async def test_send_trace_probe_timeout(
233 1
        self,
234
        mock_send_packet_out,
235 1
        mock_trace_loop,
236 1
        mock_get_switch,
237 1
        mock_aswitch_colors,
238
    ):
239
        """Test send_trace_probe with timeout."""
240 1
        mock_aswitch_colors.return_value = "ee:ee:ee:ee:ee:01"
241
        mock_send_packet_out.return_value = True
242
243 1
        switch_obj = MagicMock()
244
        switch_obj.dpid = "00:00:00:00:00:00:00:01"
245
        mock_get_switch.return_value = switch_obj
246 1
247
        # Mock tracepath loop to create only the initial result item
248
        mock_trace_loop.return_value = True
249 1
250 1
        # Creating a fake packet in
251 1
        self.trace_manager.trace_pkt_in = []
252 1
253 1
        # Trace id to recover the result
254
        trace_id = 111
255 1
256
        # Creating trace entries
257 1
        timeout = 1
258 1
        eth = {"dl_vlan": 100, "dl_type": 2048}
259
        dpid = {"dpid": "00:00:00:00:00:00:00:01", "in_port": 1}
260 1
        switch = {"switch": dpid, "eth": eth, "timeout": timeout}
261
        entries = {"trace": switch}
262 1
        trace_entries = self.trace_manager.is_entry_valid(entries)
263
264 1
        tracer = TracePath(self.trace_manager, trace_id, trace_entries)
265 1
266 1
        in_port = 1
267 1
        probe_pkt = MagicMock()
268
269 1
        expected_time = timeout * 3
270 1
        start_time = time.time()
271 1
        result = await tracer.send_trace_probe(switch_obj, in_port, probe_pkt)
272 1
        actual_time = time.time() - start_time
273
274 1
        assert mock_send_packet_out.call_count == 3
275
        assert expected_time < actual_time, "Trace was too fast."
276
277 1
        assert result[0] == "timeout"
278 1
        assert result[1] is False
279 1
        mock_aswitch_colors.assert_called_once()
280 1
281
    @patch("napps.amlight.sdntrace.shared.colors.Colors.get_switch_color")
282 1
    @patch("napps.amlight.sdntrace.shared.switches.Switches.get_switch")
283
    def test_check_loop(self, mock_get_switch, mock_switch_colors):
284
        """Test check_loop with loop detection."""
285 1
        mock_switch_colors.return_value = "ee:ee:ee:ee:ee:01"
286
287
        # Patch Switches.get_switch
288 1
        def wrap_get_switch(dpid):
289 1
            switch = MagicMock()
290 1
            switch.dpid = dpid
291 1
            return switch
292 1
293
        mock_get_switch.side_effect = wrap_get_switch
294 1
295
        # Trace id to recover the result
296
        trace_id = 111
297 1
298 1
        # Creating trace entries
299
        eth = {"dl_vlan": 100, "dl_type": 2048}
300
        dpid = {"dpid": "00:00:00:00:00:00:00:01", "in_port": 1}
301
        switch = {"switch": dpid, "eth": eth}
302
        entries = {"trace": switch}
303
        trace_entries = self.trace_manager.is_entry_valid(entries)
304 1
305
        tracer = TracePath(self.trace_manager, trace_id, trace_entries)
306
307
        # Patch tracepath loop to create a second result item
308
        rest = FormatRest()
309
        rest.add_trace_step(
310 1
            tracer.trace_result,
311
            trace_type="trace",
312
            dpid="00:00:00:00:00:00:00:01",
313
            port=1,
314
        )
315
        rest.add_trace_step(
316 1
            tracer.trace_result,
317
            trace_type="trace",
318
            dpid="00:00:00:00:00:00:00:02",
319
            port=2,
320
        )
321
        rest.add_trace_step(
322
            tracer.trace_result,
323 1
            trace_type="trace",
324 1
            dpid="00:00:00:00:00:00:00:03",
325 1
            port=3,
326 1
        )
327
        rest.add_trace_step(
328 1
            tracer.trace_result,
329 1
            trace_type="trace",
330 1
            dpid="00:00:00:00:00:00:00:01",
331 1
            port=1,
332
        )
333 1
334
        result = tracer.check_loop()
335
        mock_switch_colors.assert_called_once()
336 1
        assert result is True
337 1
338 1
    @patch("napps.amlight.sdntrace.shared.colors.Colors.get_switch_color")
339 1
    @patch("napps.amlight.sdntrace.shared.switches.Switches.get_switch")
340
    def test_check_loop_false(self, mock_get_switch, mock_switch_colors):
341 1
        """Test check_loop with no loop detection."""
342
        mock_switch_colors.return_value = "ee:ee:ee:ee:ee:01"
343
344 1
        # Patch Switches.get_switch
345
        def wrap_get_switch(dpid):
346
            switch = MagicMock()
347 1
            switch.dpid = dpid
348 1
            return switch
349 1
350 1
        mock_get_switch.side_effect = wrap_get_switch
351 1
352
        # Trace id to recover the result
353 1
        trace_id = 111
354
355
        # Creating trace entries
356 1
        eth = {"dl_vlan": 100, "dl_type": 2048}
357 1
        dpid = {"dpid": "00:00:00:00:00:00:00:01", "in_port": 1}
358
        switch = {"switch": dpid, "eth": eth}
359
        entries = {"trace": switch}
360
        trace_entries = self.trace_manager.is_entry_valid(entries)
361
362
        tracer = TracePath(self.trace_manager, trace_id, trace_entries)
363 1
364
        # Patch tracepath loop to create a second result item
365
        rest = FormatRest()
366
        rest.add_trace_step(
367
            tracer.trace_result,
368
            trace_type="trace",
369
            dpid="00:00:00:00:00:00:00:01",
370 1
            port=1,
371 1
        )
372 1
        rest.add_trace_step(
373 1
            tracer.trace_result,
374
            trace_type="trace",
375 1
            dpid="00:00:00:00:00:00:00:02",
376 1
            port=2,
377 1
        )
378 1
379
        result = tracer.check_loop()
380
        mock_switch_colors.assert_called_once()
381
        assert result == 0
382 1
383
    @patch("napps.amlight.sdntrace.shared.colors.Colors.get_switch_color")
384
    @patch("napps.amlight.sdntrace.shared.switches.Switches.get_switch")
385 1
    def test_check_loop_port_different(self, mock_get_switch, mock_switch_colors):
386 1
        """Test check_loop with same switch and different port."""
387 1
        mock_switch_colors.return_value = "ee:ee:ee:ee:ee:01"
388 1
389
        # Patch Switches.get_switch
390 1
        def wrap_get_switch(dpid):
391
            switch = MagicMock()
392
            switch.dpid = dpid
393 1
            return switch
394
395
        mock_get_switch.side_effect = wrap_get_switch
396 1
397 1
        # Trace id to recover the result
398 1
        trace_id = 111
399 1
400 1
        # Creating trace entries
401
        eth = {"dl_vlan": 100, "dl_type": 2048}
402 1
        dpid = {"dpid": "00:00:00:00:00:00:00:01", "in_port": 1}
403
        switch = {"switch": dpid, "eth": eth}
404
        entries = {"trace": switch}
405 1
        trace_entries = self.trace_manager.is_entry_valid(entries)
406 1
407
        tracer = TracePath(self.trace_manager, trace_id, trace_entries)
408
409
        # Patch tracepath loop to create a second result item
410
        rest = FormatRest()
411
        rest.add_trace_step(
412 1
            tracer.trace_result,
413
            trace_type="trace",
414
            dpid="00:00:00:00:00:00:00:01",
415
            port=1,
416
        )
417
        rest.add_trace_step(
418 1
            tracer.trace_result,
419
            trace_type="trace",
420
            dpid="00:00:00:00:00:00:00:02",
421
            port=2,
422
        )
423
        rest.add_trace_step(
424
            tracer.trace_result,
425 1
            trace_type="trace",
426 1
            dpid="00:00:00:00:00:00:00:01",
427 1
            port=10,
428 1
        )
429
430 1
        result = tracer.check_loop()
431 1
        mock_switch_colors.assert_called_once()
432 1
        assert result == 0
433 1
434 1 View Code Duplication
    @patch("napps.amlight.sdntrace.shared.colors.Colors.get_switch_color")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
435 1
    @patch("napps.amlight.sdntrace.shared.switches.Switches.get_switch")
436
    @patch("napps.amlight.sdntrace.tracing.tracer.TracePath.send_trace_probe")
437
    @patch("napps.amlight.sdntrace.tracing.tracer.prepare_next_packet")
438
    async def test_tracepath_loop(
439
        self,
440
        mock_next_packet,
441
        mock_probe,
442
        mock_get_switch,
443
        mock_switch_colors,
444
    ):
445 1
        """Test tracepath loop method. This test force the return
446
        after one normal trace."""
447
        mock_switch_colors.return_value = "ee:ee:ee:ee:ee:01"
448 1
449 1
        # Patch Switches.get_switch
450 1
        def wrap_get_switch(dpid):
451 1
            switch = MagicMock()
452
            switch.dpid = dpid
453 1
            return switch
454
455 1
        mock_get_switch.side_effect = wrap_get_switch
456
457
        mock_probe.return_value = [
458
            {"dpid": "00:00:00:00:00:00:00:01", "port": 1},
459
            "fake_event_object",
460
        ]
461 1
462
        # Trace id to recover the result
463
        trace_id = 111
464 1
465 1
        # Creating trace entries
466 1
        eth = {"dl_vlan": 100}
467 1
        dpid = {"dpid": "00:00:00:00:00:00:00:01", "in_port": 1}
468 1
        switch = {"switch": dpid, "eth": eth}
469
        entries = {"trace": switch}
470 1
        trace_entries = self.trace_manager.is_entry_valid(entries)
471
472
        tracer = TracePath(self.trace_manager, trace_id, trace_entries)
473
474 1
        # Mock the next packt to stop the trace loop
475 1
        # pylint: disable=unused-argument
476 1
        def wrap_next_packet(entries, result, packet_in):
477
            tracer.trace_ended = True
478 1
            return "", "", ""
479
480 1
        mock_next_packet.side_effect = wrap_next_packet
481
482
        color = {"color_field": "dl_src", "color_value": "ee:ee:ee:ee:01:2c"}
483 1
484 1
        # Execute tracepath
485
        await tracer.tracepath_loop(trace_entries, color, switch)
486 1
        result = tracer.trace_result
487 1
488 1
        mock_probe.assert_called_once()
489 1
        mock_switch_colors.assert_called_once()
490 1
        assert result[0]["type"] == "trace"
491
        assert result[0]["dpid"] == "00:00:00:00:00:00:00:01"
492 1
493 1
    @patch("napps.amlight.sdntrace.shared.colors.Colors.get_switch_color")
494 1
    @patch("napps.amlight.sdntrace.shared.switches.Switches.get_switch")
495 1
    @patch("napps.amlight.sdntrace.tracing.tracer.TracePath.send_trace_probe")
496 1
    async def test_tracepath_loop_timeout(
497
        self,
498
        mock_probe,
499
        mock_get_switch,
500 1
        mock_switch_colors,
501
    ):
502
        """Test tracepath loop method finishing with timeout."""
503 1
        mock_switch_colors.return_value = "ee:ee:ee:ee:ee:01"
504 1
505 1
        # Patch Switches.get_switch
506 1
        def wrap_get_switch(dpid):
507
            switch = MagicMock()
508 1
            switch.dpid = dpid
509
            return switch
510 1
511
        mock_get_switch.side_effect = wrap_get_switch
512
513 1
        mock_probe.return_value = ["timeout", "fake_event_object"]
514
515
        # Trace id to recover the result
516 1
        trace_id = 111
517 1
518 1
        # Creating trace entries
519 1
        eth = {"dl_vlan": 100}
520 1
        dpid = {"dpid": "00:00:00:00:00:00:00:01", "in_port": 1}
521
        switch = {"switch": dpid, "eth": eth}
522 1
        entries = {"trace": switch}
523
        trace_entries = self.trace_manager.is_entry_valid(entries)
524
525 1
        color = {"color_field": "dl_src", "color_value": "ee:ee:ee:ee:01:2c"}
526 1
527
        # Execute tracepath
528 1
        tracer = TracePath(self.trace_manager, trace_id, trace_entries)
529
        await tracer.tracepath_loop(trace_entries, color, switch)
530 1
531 1
        result = tracer.trace_result
532 1
533 1
        mock_probe.assert_called_once()
534 1
        mock_switch_colors.assert_called_once()
535 1
        assert result[0]["type"] == "last"
536
        assert result[0]["reason"] == "done"
537 1
        assert result[0]["msg"] == "none"
538 1
539 1 View Code Duplication
    @patch("napps.amlight.sdntrace.shared.colors.Colors.get_switch_color")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
540 1
    @patch("napps.amlight.sdntrace.shared.switches.Switches.get_switch")
541 1
    @patch("napps.amlight.sdntrace.tracing.tracer.TracePath.send_trace_probe")
542 1
    @patch("napps.amlight.sdntrace.tracing.tracer.prepare_next_packet")
543 1
    @patch("napps.amlight.sdntrace.tracing.tracer.TracePath.check_loop")
544
    async def test_tracepath_loop_with_loop(
545
        self,
546
        mock_check_loop,
547
        mock_next_packet,
548
        mock_probe,
549
        mock_get_switch,
550
        mock_switch_colors,
551
    ):
552
        """Test tracepath loop method finishing with a loop."""
553 1
        mock_switch_colors.return_value = "ee:ee:ee:ee:ee:01"
554 1
        mock_check_loop.return_value = True
555
556
        # Patch Switches.get_switch
557 1
        def wrap_get_switch(dpid):
558 1
            switch = MagicMock()
559 1
            switch.dpid = dpid
560 1
            return switch
561
562 1
        mock_get_switch.side_effect = wrap_get_switch
563
564 1
        mock_probe.return_value = [
565
            {"dpid": "00:00:00:00:00:00:00:01", "port": 1},
566
            "fake_event_object",
567
        ]
568
569
        # Trace id to recover the result
570 1
        trace_id = 111
571
572
        # Creating trace entries
573 1
        eth = {"dl_vlan": 100}
574 1
        dpid = {"dpid": "00:00:00:00:00:00:00:01", "in_port": 1}
575 1
        switch = {"switch": dpid, "eth": eth}
576 1
        entries = {"trace": switch}
577 1
        trace_entries = self.trace_manager.is_entry_valid(entries)
578
579 1
        tracer = TracePath(self.trace_manager, trace_id, trace_entries)
580
581
        # Mock the next packt to stop the trace loop
582
        # pylint: disable=unused-argument
583 1
        def wrap_next_packet(entries, result, packet_in):
584
            tracer.trace_ended = True
585
            return "", "", ""
586
587 1
        mock_next_packet.side_effect = wrap_next_packet
588
589 1
        color = {"color_field": "dl_src", "color_value": "ee:ee:ee:ee:01:2c"}
590
591
        # Execute tracepath
592 1
        await tracer.tracepath_loop(trace_entries, color, switch)
593 1
        result = tracer.trace_result
594
595 1
        mock_check_loop.assert_called_once()
596 1
        mock_next_packet.assert_not_called()
597 1
        mock_probe.assert_called_once()
598 1
        assert mock_get_switch.call_count == 3
599 1
        mock_switch_colors.assert_called_once()
600 1
601
        assert result[0]["type"] == "trace"
602
        assert result[0]["dpid"] == "00:00:00:00:00:00:00:01"
603