Test Failed
Pull Request — master (#68)
by Arturo
02:39
created

TestResultsEdges.test_path9()   C

Complexity

Conditions 10

Size

Total Lines 73
Code Lines 58

Duplication

Lines 22
Ratio 30.14 %

Importance

Changes 0
Metric Value
cc 10
eloc 58
nop 1
dl 22
loc 73
rs 5.5744
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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:

Complexity

Complex classes like build.tests.integration.test_results_edges.TestResultsEdges.test_path9() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
"""Module to test the KytosGraph in graph.py."""
2
from itertools import combinations
3
4
# Core modules to import
5
from kytos.core.link import Link
6
7
# module under test
8
from tests.integration.test_results import TestResults
9
10
11
class TestResultsEdges(TestResults):
12
    """Tests for the graph class.
13
14
    Tests to see if reflexive searches and impossible searches
15
    show correct results.
16
    """
17
18
    def test_path1(self):
19
        """Tests paths between all users using unconstrained path algorithm."""
20
        combos = combinations(["User1", "User2", "User3", "User4"], 2)
21
        self.initializer()
22
23
        valid = True
24
        for point_a, point_b in combos:
25
            results = self.get_path(point_a, point_b)
26
            if not results:
27
                valid = False
28
                break
29
30
        self.assertNotEqual(valid, False)
31
32
    def test_path12(self):
33
        """Tests paths between all users using unconstrained path algorithm."""
34
        combos = combinations(["User1", "User2", "User3", "User4", "User5"], 2)
35
        self.initializer()
36
37
        valid = True
38
        for point_a, point_b in combos:
39
            results = self.get_path(point_a, point_b)
40
            if not results:
41
                valid = False
42
                break
43
44
        self.assertEqual(valid, False)
45
46
    def test_path2(self):
47
        """Tests paths between all users using constrained path algorithm,
48
        with no constraints set.
49
        """
50
        combos = combinations(["User1", "User2", "User3", "User4"], 2)
51
        self.initializer()
52
53
        for point_a, point_b in combos:
54
            results = self.get_path_constrained(point_a, point_b)
55
            self.assertNotEqual(results, [])
56
57
    def test_path3(self):
58
        """Tests paths between all users using constrained path algorithm,
59
        with the ownership constraint set to B.
60
        """
61
        combos = combinations(["User1", "User2", "User3", "User4"], 2)
62
        self.initializer()
63
64
        for point_a, point_b in combos:
65
            results = self.get_path_constrained(
66
                point_a, point_b, base=dict(ownership="B"))
67
            for result in results:
68
                for path in result["paths"]:
69
                    self.assertNotIn("S4:1", path)
70
                    self.assertNotIn("S5:2", path)
71
                    self.assertNotIn("S4:2", path)
72
                    self.assertNotIn("User1:2", path)
73
                    self.assertNotIn("S5:4", path)
74
                    self.assertNotIn("S6:2", path)
75
                    self.assertNotIn("S6:5", path)
76
                    self.assertNotIn("S10:1", path)
77
                    self.assertNotIn("S8:6", path)
78
                    self.assertNotIn("S10:2", path)
79
                    self.assertNotIn("S10:3", path)
80
                    self.assertNotIn("User2:1", path)
81
82
    def test_path4(self):
83
        """Tests paths between all users using constrained path algorithm,
84
        with the reliability constraint set to 3.
85
        """
86
        combos = combinations(["User1", "User2", "User3", "User4"], 2)
87
        self.initializer()
88
89
        for point_a, point_b in combos:
90
            results = self.get_path_constrained(
91
                point_a, point_b, base=dict(reliability=3))
92
            for result in results:
93
                for path in result["paths"]:
94
                    self.assertNotIn("S4:1", path)
95
                    self.assertNotIn("S5:2", path)
96
                    self.assertNotIn("S5:3", path)
97
                    self.assertNotIn("S6:1", path)
98
99
    def test_path5(self):
100
        """Tests paths between all users using constrained path algorithm,
101
        with the bandwidth constraint set to 100.
102
        """
103
        combos = combinations(["User1", "User2", "User3", "User4"], 2)
104
        self.initializer()
105
106
        for point_a, point_b in combos:
107
            results = self.get_path_constrained(
108
                point_a, point_b, base=dict(bandwidth=100))
109
            for result in results:
110
                for path in result["paths"]:
111
                    self.assertNotIn("S3:1", path)
112
                    self.assertNotIn("S5:1", path)
113
                    self.assertNotIn("User1:4", path)
114
                    self.assertNotIn("User4:3", path)
115
116
    def test_path6(self):
117
        """Tests paths between all users using constrained path algorithm,
118
        with the delay constraint set to 50.
119
        """
120
        combos = combinations(["User1", "User2", "User3", "User4"], 2)
121
        self.initializer()
122
123
        for point_a, point_b in combos:
124
            results = self.get_path_constrained(
125
                point_a, point_b, base=dict(delay=50))
126
            for result in results:
127
                for path in result["paths"]:
128
                    self.assertNotIn("S1:1", path)
129
                    self.assertNotIn("S2:1", path)
130
                    self.assertNotIn("S3:1", path)
131
                    self.assertNotIn("S5:1", path)
132
                    self.assertNotIn("S4:2", path)
133
                    self.assertNotIn("User1:2", path)
134
                    self.assertNotIn("S5:5", path)
135
                    self.assertNotIn("S8:2", path)
136
                    self.assertNotIn("S5:6", path)
137
                    self.assertNotIn("User1:3", path)
138
                    self.assertNotIn("S6:3", path)
139
                    self.assertNotIn("S9:1", path)
140
                    self.assertNotIn("S6:4", path)
141
                    self.assertNotIn("S9:2", path)
142
                    self.assertNotIn("S6:5", path)
143
                    self.assertNotIn("S10:1", path)
144
                    self.assertNotIn("S8:5", path)
145
                    self.assertNotIn("S9:4", path)
146
                    self.assertNotIn("User1:4", path)
147
                    self.assertNotIn("User4:3", path)
148
149
    def test_path7(self):
150
        """Tests paths between all users using constrained path algorithm,
151
        with the delay constraint set to 50, the bandwidth constraint set
152
        to 100, the reliability constraint set to 3, and the ownership
153
        constraint set to 'B'
154
        """
155
        combos = combinations(["User1", "User2", "User3", "User4"], 2)
156
        self.initializer()
157
158
        for point_a, point_b in combos:
159
            results = self.get_path_constrained(
160
                point_a, point_b, base=dict(delay=50, bandwidth=100,
161
                                            reliability=3,
162
                                            ownership="B"))
163
            for result in results:
164
                for path in result["paths"]:
165
                    # delay = 50 checks
166
                    self.assertNotIn("S1:1", path)
167
                    self.assertNotIn("S2:1", path)
168
                    self.assertNotIn("S3:1", path)
169
                    self.assertNotIn("S5:1", path)
170
                    self.assertNotIn("S4:2", path)
171
                    self.assertNotIn("User1:2", path)
172
                    self.assertNotIn("S5:5", path)
173
                    self.assertNotIn("S8:2", path)
174
                    self.assertNotIn("S5:6", path)
175
                    self.assertNotIn("User1:3", path)
176
                    self.assertNotIn("S6:3", path)
177
                    self.assertNotIn("S9:1", path)
178
                    self.assertNotIn("S6:4", path)
179
                    self.assertNotIn("S9:2", path)
180
                    self.assertNotIn("S6:5", path)
181
                    self.assertNotIn("S10:1", path)
182
                    self.assertNotIn("S8:5", path)
183
                    self.assertNotIn("S9:4", path)
184
                    self.assertNotIn("User1:4", path)
185
                    self.assertNotIn("User4:3", path)
186
187
                    # bandwidth = 100 checks
188
189
                    self.assertNotIn("S3:1", path)
190
                    self.assertNotIn("S5:1", path)
191
                    self.assertNotIn("User1:4", path)
192
                    self.assertNotIn("User4:3", path)
193
194
                    # reliability = 3 checks
195
196
                    self.assertNotIn("S4:1", path)
197
                    self.assertNotIn("S5:2", path)
198
                    self.assertNotIn("S5:3", path)
199
                    self.assertNotIn("S6:1", path)
200
201
                    # ownership = "B" checks
202
203
                    self.assertNotIn("S4:1", path)
204
                    self.assertNotIn("S5:2", path)
205
                    self.assertNotIn("S4:2", path)
206
                    self.assertNotIn("User1:2", path)
207
                    self.assertNotIn("S5:4", path)
208
                    self.assertNotIn("S6:2", path)
209
                    self.assertNotIn("S6:5", path)
210
                    self.assertNotIn("S10:1", path)
211
                    self.assertNotIn("S8:6", path)
212
                    self.assertNotIn("S10:2", path)
213
                    self.assertNotIn("S10:3", path)
214
                    self.assertNotIn("User2:1", path)
215
216
    def test_path8(self):
217
        """Tests paths between all users using constrained path algorithm,
218
        with the delay constraint set to 50, the bandwidth constraint
219
        set to 100, the reliability constraint set to 3, and the ownership
220
        constraint set to 'B'
221
222
        Tests conducted with flexibility enabled
223
        """
224
        combos = combinations(["User1", "User2", "User3", "User4"], 2)
225
        self.initializer()
226
227
        for point_a, point_b in combos:
228
            results = self.get_path_constrained(
229
                point_a, point_b, flexible=dict(delay=50, bandwidth=100,
230
                                                reliability=3,
231
                                                ownership="B"))
232
            for result in results:
233
                # delay = 50 checks
234 View Code Duplication
                if "delay" in result["metrics"]:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
235
                    for path in result["paths"]:
236
                        self.assertNotIn("S1:1", path)
237
                        self.assertNotIn("S2:1", path)
238
                        self.assertNotIn("S3:1", path)
239
                        self.assertNotIn("S5:1", path)
240
                        self.assertNotIn("S4:2", path)
241
                        self.assertNotIn("User1:2", path)
242
                        self.assertNotIn("S5:5", path)
243
                        self.assertNotIn("S8:2", path)
244
                        self.assertNotIn("S5:6", path)
245
                        self.assertNotIn("User1:3", path)
246
                        self.assertNotIn("S6:3", path)
247
                        self.assertNotIn("S9:1", path)
248
                        self.assertNotIn("S6:4", path)
249
                        self.assertNotIn("S9:2", path)
250
                        self.assertNotIn("S6:5", path)
251
                        self.assertNotIn("S10:1", path)
252
                        self.assertNotIn("S8:5", path)
253
                        self.assertNotIn("S9:4", path)
254
                        self.assertNotIn("User1:4", path)
255
                        self.assertNotIn("User4:3", path)
256
257
                # bandwidth = 100 checks
258
                if "bandwidth" in result["metrics"]:
259
                    for path in result["paths"]:
260
                        self.assertNotIn("S3:1", path)
261
                        self.assertNotIn("S5:1", path)
262
                        self.assertNotIn("User1:4", path)
263
                        self.assertNotIn("User4:3", path)
264
265
                # reliability = 3 checks
266
                if "reliability" in result["metrics"]:
267
                    for path in result["paths"]:
268
                        self.assertNotIn("S4:1", path)
269
                        self.assertNotIn("S5:2", path)
270
                        self.assertNotIn("S5:3", path)
271
                        self.assertNotIn("S6:1", path)
272
273
                # ownership = "B" checks
274
                if "ownership" in result["metrics"]:
275
                    for path in result["paths"]:
276
                        self.assertNotIn("S4:1", path)
277
                        self.assertNotIn("S5:2", path)
278
                        self.assertNotIn("S4:2", path)
279
                        self.assertNotIn("User1:2", path)
280
                        self.assertNotIn("S5:4", path)
281
                        self.assertNotIn("S6:2", path)
282
                        self.assertNotIn("S6:5", path)
283
                        self.assertNotIn("S10:1", path)
284
                        self.assertNotIn("S8:6", path)
285
                        self.assertNotIn("S10:2", path)
286
                        self.assertNotIn("S10:3", path)
287
                        self.assertNotIn("User2:1", path)
288
289
    def test_path9(self):
290
        """Tests paths between all users using constrained path algorithm,
291
        with the delay constraint set to 50, the bandwidth constraint
292
        set to 100, the reliability constraint set to 3, and the ownership
293
        constraint set to 'B'
294
295
        Tests conducted with all but ownership flexible
296
        """
297
        combos = combinations(["User1", "User2", "User3", "User4"], 2)
298
        self.initializer()
299
300
        for point_a, point_b in combos:
301
            results = self.get_path_constrained(point_a, point_b,
302
                                                base={"ownership": "B"},
303
                                                flexible={"delay": 50,
304
                                                          "bandwidth": 100,
305
                                                          "reliability": 3})
306
            for result in results:
307
                # delay = 50 checks
308 View Code Duplication
                if "delay" in result["metrics"]:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
309
                    for path in result["paths"]:
310
                        self.assertNotIn("S1:1", path)
311
                        self.assertNotIn("S2:1", path)
312
                        self.assertNotIn("S3:1", path)
313
                        self.assertNotIn("S5:1", path)
314
                        self.assertNotIn("S4:2", path)
315
                        self.assertNotIn("User1:2", path)
316
                        self.assertNotIn("S5:5", path)
317
                        self.assertNotIn("S8:2", path)
318
                        self.assertNotIn("S5:6", path)
319
                        self.assertNotIn("User1:3", path)
320
                        self.assertNotIn("S6:3", path)
321
                        self.assertNotIn("S9:1", path)
322
                        self.assertNotIn("S6:4", path)
323
                        self.assertNotIn("S9:2", path)
324
                        self.assertNotIn("S6:5", path)
325
                        self.assertNotIn("S10:1", path)
326
                        self.assertNotIn("S8:5", path)
327
                        self.assertNotIn("S9:4", path)
328
                        self.assertNotIn("User1:4", path)
329
                        self.assertNotIn("User4:3", path)
330
331
                # bandwidth = 100 checks
332
                if "bandwidth" in result["metrics"]:
333
                    for path in result["paths"]:
334
                        self.assertNotIn("S3:1", path)
335
                        self.assertNotIn("S5:1", path)
336
                        self.assertNotIn("User1:4", path)
337
                        self.assertNotIn("User4:3", path)
338
339
                # reliability = 3 checks
340
                if "reliability" in result["metrics"]:
341
                    for path in result["paths"]:
342
                        self.assertNotIn("S4:1", path)
343
                        self.assertNotIn("S5:2", path)
344
                        self.assertNotIn("S5:3", path)
345
                        self.assertNotIn("S6:1", path)
346
347
                # ownership = "B" checks
348
                self.assertIn("ownership", result["metrics"])
349
                for path in result["paths"]:
350
                    self.assertNotIn("S4:1", path)
351
                    self.assertNotIn("S5:2", path)
352
                    self.assertNotIn("S4:2", path)
353
                    self.assertNotIn("User1:2", path)
354
                    self.assertNotIn("S5:4", path)
355
                    self.assertNotIn("S6:2", path)
356
                    self.assertNotIn("S6:5", path)
357
                    self.assertNotIn("S10:1", path)
358
                    self.assertNotIn("S8:6", path)
359
                    self.assertNotIn("S10:2", path)
360
                    self.assertNotIn("S10:3", path)
361
                    self.assertNotIn("User2:1", path)
362
363
    def test_path10(self):
364
        """Tests that TypeError is generated by get_path_constrained
365
366
        Tests with ownership using an int type rather than string
367
        """
368
        self.initializer()
369
370
        with self.assertRaises(TypeError):
371
            self.get_path_constrained(
372
                "User1", "User2", base={"ownership": 1})
373
374
    @staticmethod
375
    def generate_topology():
376
        """Generates a predetermined topology"""
377
        switches = {}
378
        interfaces = {}
379
        links = {}
380
381
        TestResults.create_switch("S1", switches)
382
        TestResults.add_interfaces(2, switches["S1"], interfaces)
383
384
        TestResults.create_switch("S2", switches)
385
        TestResults.add_interfaces(2, switches["S2"], interfaces)
386
387
        TestResults.create_switch("S3", switches)
388
        TestResults.add_interfaces(6, switches["S3"], interfaces)
389
390
        TestResults.create_switch("S4", switches)
391
        TestResults.add_interfaces(2, switches["S4"], interfaces)
392
393
        TestResults.create_switch("S5", switches)
394
        TestResults.add_interfaces(6, switches["S5"], interfaces)
395
396
        TestResults.create_switch("S6", switches)
397
        TestResults.add_interfaces(5, switches["S6"], interfaces)
398
399
        TestResults.create_switch("S7", switches)
400
        TestResults.add_interfaces(2, switches["S7"], interfaces)
401
402
        TestResults.create_switch("S8", switches)
403
        TestResults.add_interfaces(8, switches["S8"], interfaces)
404
405
        TestResults.create_switch("S9", switches)
406
        TestResults.add_interfaces(4, switches["S9"], interfaces)
407
408
        TestResults.create_switch("S10", switches)
409
        TestResults.add_interfaces(3, switches["S10"], interfaces)
410
411
        TestResults.create_switch("S11", switches)
412
        TestResults.add_interfaces(3, switches["S11"], interfaces)
413
414
        TestResults.create_switch("User1", switches)
415
        TestResults.add_interfaces(4, switches["User1"], interfaces)
416
417
        TestResults.create_switch("User2", switches)
418
        TestResults.add_interfaces(2, switches["User2"], interfaces)
419
420
        TestResults.create_switch("User3", switches)
421
        TestResults.add_interfaces(2, switches["User3"], interfaces)
422
423
        TestResults.create_switch("User4", switches)
424
        TestResults.add_interfaces(3, switches["User4"], interfaces)
425
426
        TestResultsEdges._fill_links(links, interfaces)
427
428
        TestResultsEdges._add_metadata_to_links(links)
429
430
        return switches, links
431
432
    @staticmethod
433
    def _add_metadata_to_links(links):
434
        links["S1:1<->S2:1"].extend_metadata(
435
            {"reliability": 5, "bandwidth": 100, "delay": 105})
436
437
        links["S1:2<->User1:1"].extend_metadata(
438
            {"reliability": 5, "bandwidth": 100, "delay": 1})
439
440
        links["S2:2<->User4:1"].extend_metadata(
441
            {"reliability": 5, "bandwidth": 100, "delay": 10})
442
443
        links["S3:1<->S5:1"].extend_metadata(
444
            {"reliability": 5, "bandwidth": 10, "delay": 112})
445
446
        links["S3:2<->S7:1"].extend_metadata(
447
            {"reliability": 5, "bandwidth": 100, "delay": 1})
448
449
        links["S3:3<->S8:1"].extend_metadata(
450
            {"reliability": 5, "bandwidth": 100, "delay": 1})
451
452
        links["S3:4<->S11:1"].extend_metadata(
453
            {"reliability": 3, "bandwidth": 100, "delay": 6})
454
455
        links["S3:5<->User3:1"].extend_metadata(
456
            {"reliability": 5, "bandwidth": 100, "delay": 1})
457
458
        links["S3:6<->User4:2"].extend_metadata(
459
            {"reliability": 5, "bandwidth": 100, "delay": 10})
460
461
        links["S4:1<->S5:2"].extend_metadata(
462
            {"reliability": 1, "bandwidth": 100, "delay": 30,
463
             "ownership": "A"})
464
465
        links["S4:2<->User1:2"].extend_metadata(
466
            {"reliability": 3, "bandwidth": 100, "delay": 110,
467
             "ownership": "A"})
468
469
        links["S5:3<->S6:1"].extend_metadata(
470
            {"reliability": 1, "bandwidth": 100, "delay": 40})
471
472
        links["S5:4<->S6:2"].extend_metadata(
473
            {"reliability": 3, "bandwidth": 100, "delay": 40,
474
             "ownership": "A"})
475
476
        links["S5:5<->S8:2"].extend_metadata(
477
            {"reliability": 5, "bandwidth": 100, "delay": 112})
478
479
        links["S5:6<->User1:3"].extend_metadata(
480
            {"reliability": 3, "bandwidth": 100, "delay": 60})
481
482
        links["S6:3<->S9:1"].extend_metadata(
483
            {"reliability": 3, "bandwidth": 100, "delay": 60})
484
485
        links["S6:4<->S9:2"].extend_metadata(
486
            {"reliability": 5, "bandwidth": 100, "delay": 62})
487
488
        links["S6:5<->S10:1"].extend_metadata(
489
            {"bandwidth": 100, "delay": 108, "ownership": "A"})
490
491
        links["S7:2<->S8:3"].extend_metadata(
492
            {"reliability": 5, "bandwidth": 100, "delay": 1})
493
494
        links["S8:4<->S9:3"].extend_metadata(
495
            {"reliability": 3, "bandwidth": 100, "delay": 32})
496
497
        links["S8:5<->S9:4"].extend_metadata(
498
            {"reliability": 3, "bandwidth": 100, "delay": 110})
499
500
        links["S8:6<->S10:2"].extend_metadata(
501
            {"reliability": 5, "bandwidth": 100, "ownership": "A"})
502
503
        links["S8:7<->S11:2"].extend_metadata(
504
            {"reliability": 3, "bandwidth": 100, "delay": 7})
505
506
        links["S8:8<->User3:2"].extend_metadata(
507
            {"reliability": 5, "bandwidth": 100, "delay": 1})
508
509
        links["S10:3<->User2:1"].extend_metadata(
510
            {"reliability": 3, "bandwidth": 100, "delay": 10,
511
             "ownership": "A"})
512
513
        links["S11:3<->User2:2"].extend_metadata(
514
            {"reliability": 3, "bandwidth": 100, "delay": 6})
515
516
        links["User1:4<->User4:3"].extend_metadata(
517
            {"reliability": 5, "bandwidth": 10, "delay": 105})
518
519
    @staticmethod
520
    def _fill_links(links, interfaces):
521
        links["S1:1<->S2:1"] = Link(interfaces["S1:1"], interfaces["S2:1"])
522
523
        links["S1:2<->User1:1"] = Link(interfaces["S1:2"], interfaces["User1:1"])
524
525
        links["S2:2<->User4:1"] = Link(interfaces["S2:2"], interfaces["User4:1"])
526
527
        links["S3:1<->S5:1"] = Link(interfaces["S3:1"], interfaces["S5:1"])
528
529
        links["S3:2<->S7:1"] = Link(interfaces["S3:2"], interfaces["S7:1"])
530
531
        links["S3:3<->S8:1"] = Link(interfaces["S3:3"], interfaces["S8:1"])
532
533
        links["S3:4<->S11:1"] = Link(interfaces["S3:4"], interfaces["S11:1"])
534
535
        links["S3:5<->User3:1"] = Link(interfaces["S3:5"], interfaces["User3:1"])
536
537
        links["S3:6<->User4:2"] = Link(interfaces["S3:6"], interfaces["User4:2"])
538
539
        links["S4:1<->S5:2"] = Link(interfaces["S4:1"], interfaces["S5:2"])
540
541
        links["S4:2<->User1:2"] = Link(interfaces["S4:2"], interfaces["User1:2"])
542
543
        links["S5:3<->S6:1"] = Link(interfaces["S5:3"], interfaces["S6:1"])
544
545
        links["S5:4<->S6:2"] = Link(interfaces["S5:4"], interfaces["S6:2"])
546
547
        links["S5:5<->S8:2"] = Link(interfaces["S5:5"], interfaces["S8:2"])
548
549
        links["S5:6<->User1:3"] = Link(interfaces["S5:6"], interfaces["User1:3"])
550
551
        links["S6:3<->S9:1"] = Link(interfaces["S6:3"], interfaces["S9:1"])
552
553
        links["S6:4<->S9:2"] = Link(interfaces["S6:4"], interfaces["S9:2"])
554
555
        links["S6:5<->S10:1"] = Link(interfaces["S6:5"], interfaces["S10:1"])
556
557
        links["S7:2<->S8:3"] = Link(interfaces["S7:2"], interfaces["S8:3"])
558
559
        links["S8:4<->S9:3"] = Link(interfaces["S8:4"], interfaces["S9:3"])
560
561
        links["S8:5<->S9:4"] = Link(interfaces["S8:5"], interfaces["S9:4"])
562
563
        links["S8:6<->S10:2"] = Link(interfaces["S8:6"], interfaces["S10:2"])
564
565
        links["S8:7<->S11:2"] = Link(interfaces["S8:7"], interfaces["S11:2"])
566
567
        links["S8:8<->User3:2"] = Link(interfaces["S8:8"], interfaces["User3:2"])
568
569
        links["S10:3<->User2:1"] = Link(interfaces["S10:3"], interfaces["User2:1"])
570
571
        links["S11:3<->User2:2"] = Link(interfaces["S11:3"], interfaces["User2:2"])
572
573
        links["User1:4<->User4:3"] = Link(interfaces["User1:4"], interfaces["User4:3"])
574