blob: 5ebc0d66f19cb85aa3578f10dd1f9f1f0b94faef [file] [log] [blame]
Sean Condonf4f54a12018-10-10 23:25:46 +01001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the 'License');
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an 'AS IS' BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Sean Condonc13d9562019-04-18 13:24:42 +010016import {async, ComponentFixture, TestBed} from '@angular/core/testing';
Sean Condonf4f54a12018-10-10 23:25:46 +010017
Sean Condonc13d9562019-04-18 13:24:42 +010018import {ForceSvgComponent} from './forcesvg.component';
Sean Condon64060ff2019-05-30 15:48:11 +010019import {
20 FnService, IconService,
21 LionService,
22 LogService, SvgUtilService,
23 UrlFnService,
24 WebSocketService
Sean Condon3dd062f2020-04-14 09:25:00 +010025} from 'org_onosproject_onos/web/gui2-fw-lib/public_api';
Sean Condon0c577f62018-11-18 22:40:05 +000026import {DraggableDirective} from './draggable/draggable.directive';
27import {ActivatedRoute, Params} from '@angular/router';
28import {of} from 'rxjs';
Sean Condonff85fbe2019-03-16 14:28:46 +000029import {DeviceNodeSvgComponent} from './visuals/devicenodesvg/devicenodesvg.component';
30import {SubRegionNodeSvgComponent} from './visuals/subregionnodesvg/subregionnodesvg.component';
31import {HostNodeSvgComponent} from './visuals/hostnodesvg/hostnodesvg.component';
32import {LinkSvgComponent} from './visuals/linksvg/linksvg.component';
Sean Condonf9ff66a2020-03-23 08:40:55 +000033import {Device, Host, Link, LinkType, LinkHighlight, Region} from './models';
Sean Condon64060ff2019-05-30 15:48:11 +010034import {ChangeDetectorRef, SimpleChange} from '@angular/core';
35import {TopologyService} from '../../topology.service';
Sean Condon590b34b2019-12-04 18:44:37 +000036import {BadgeSvgComponent} from './visuals/badgesvg/badgesvg.component';
Sean Condon0c577f62018-11-18 22:40:05 +000037
Sean Condon4ceeae72021-10-21 15:37:11 +010038export const test_module_topo2CurrentRegion = `{
39 "event": "topo2CurrentRegion",
40 "payload": {
41 "id": "(root)",
42 "subregions": [],
43 "links": [
44 {
45 "id": "00:AA:00:00:00:03/None~of:0000000000000205/6",
46 "epA": "00:AA:00:00:00:03/None",
47 "epB": "of:0000000000000205",
48 "type": "UiEdgeLink",
49 "portB": "6",
50 "rollup": [
51 {
52 "id": "00:AA:00:00:00:03/None~of:0000000000000205/6",
53 "epA": "00:AA:00:00:00:03/None",
54 "epB": "of:0000000000000205",
55 "type": "UiEdgeLink",
56 "portB": "6"
57 }
58 ]
59 },
60 {
61 "id": "of:0000000000000205/3~of:0000000000000227/5",
62 "epA": "of:0000000000000205/3",
63 "epB": "of:0000000000000227/5",
64 "type": "UiDeviceLink",
65 "portA": "3",
66 "portB": "5",
67 "rollup": [
68 {
69 "id": "of:0000000000000205/3~of:0000000000000227/5",
70 "epA": "of:0000000000000205/3",
71 "epB": "of:0000000000000227/5",
72 "type": "UiDeviceLink",
73 "portA": "3",
74 "portB": "5"
75 }
76 ]
77 },
78 {
79 "id": "of:0000000000000206/2~of:0000000000000226/8",
80 "epA": "of:0000000000000206/2",
81 "epB": "of:0000000000000226/8",
82 "type": "UiDeviceLink",
83 "portA": "2",
84 "portB": "8",
85 "rollup": [
86 {
87 "id": "of:0000000000000206/2~of:0000000000000226/8",
88 "epA": "of:0000000000000206/2",
89 "epB": "of:0000000000000226/8",
90 "type": "UiDeviceLink",
91 "portA": "2",
92 "portB": "8"
93 }
94 ]
95 },
96 {
97 "id": "00:BB:00:00:00:05/None~of:0000000000000203/7",
98 "epA": "00:BB:00:00:00:05/None",
99 "epB": "of:0000000000000203",
100 "type": "UiEdgeLink",
101 "portB": "7",
102 "rollup": [
103 {
104 "id": "00:BB:00:00:00:05/None~of:0000000000000203/7",
105 "epA": "00:BB:00:00:00:05/None",
106 "epB": "of:0000000000000203",
107 "type": "UiEdgeLink",
108 "portB": "7"
109 }
110 ]
111 },
112 {
113 "id": "00:DD:00:00:00:01/None~of:0000000000000207/3",
114 "epA": "00:DD:00:00:00:01/None",
115 "epB": "of:0000000000000207",
116 "type": "UiEdgeLink",
117 "portB": "3",
118 "rollup": [
119 {
120 "id": "00:DD:00:00:00:01/None~of:0000000000000207/3",
121 "epA": "00:DD:00:00:00:01/None",
122 "epB": "of:0000000000000207",
123 "type": "UiEdgeLink",
124 "portB": "3"
125 }
126 ]
127 },
128 {
129 "id": "of:0000000000000203/1~of:0000000000000226/1",
130 "epA": "of:0000000000000203/1",
131 "epB": "of:0000000000000226/1",
132 "type": "UiDeviceLink",
133 "portA": "1",
134 "portB": "1",
135 "rollup": [
136 {
137 "id": "of:0000000000000203/1~of:0000000000000226/1",
138 "epA": "of:0000000000000203/1",
139 "epB": "of:0000000000000226/1",
140 "type": "UiDeviceLink",
141 "portA": "1",
142 "portB": "1"
143 }
144 ]
145 },
146 {
147 "id": "of:0000000000000207/2~of:0000000000000247/1",
148 "epA": "of:0000000000000207/2",
149 "epB": "of:0000000000000247/1",
150 "type": "UiDeviceLink",
151 "portA": "2",
152 "portB": "1",
153 "rollup": [
154 {
155 "id": "of:0000000000000207/2~of:0000000000000247/1",
156 "epA": "of:0000000000000207/2",
157 "epB": "of:0000000000000247/1",
158 "type": "UiDeviceLink",
159 "portA": "2",
160 "portB": "1"
161 }
162 ]
163 },
164 {
165 "id": "00:99:66:00:00:01/None~of:0000000000000205/10",
166 "epA": "00:99:66:00:00:01/None",
167 "epB": "of:0000000000000205",
168 "type": "UiEdgeLink",
169 "portB": "10",
170 "rollup": [
171 {
172 "id": "00:99:66:00:00:01/None~of:0000000000000205/10",
173 "epA": "00:99:66:00:00:01/None",
174 "epB": "of:0000000000000205",
175 "type": "UiEdgeLink",
176 "portB": "10"
177 }
178 ]
179 },
180 {
181 "id": "of:0000000000000208/1~of:0000000000000246/2",
182 "epA": "of:0000000000000208/1",
183 "epB": "of:0000000000000246/2",
184 "type": "UiDeviceLink",
185 "portA": "1",
186 "portB": "2",
187 "rollup": [
188 {
189 "id": "of:0000000000000208/1~of:0000000000000246/2",
190 "epA": "of:0000000000000208/1",
191 "epB": "of:0000000000000246/2",
192 "type": "UiDeviceLink",
193 "portA": "1",
194 "portB": "2"
195 }
196 ]
197 },
198 {
199 "id": "of:0000000000000206/1~of:0000000000000226/7",
200 "epA": "of:0000000000000206/1",
201 "epB": "of:0000000000000226/7",
202 "type": "UiDeviceLink",
203 "portA": "1",
204 "portB": "7",
205 "rollup": [
206 {
207 "id": "of:0000000000000206/1~of:0000000000000226/7",
208 "epA": "of:0000000000000206/1",
209 "epB": "of:0000000000000226/7",
210 "type": "UiDeviceLink",
211 "portA": "1",
212 "portB": "7"
213 }
214 ]
215 },
216 {
217 "id": "of:0000000000000226/9~of:0000000000000246/3",
218 "epA": "of:0000000000000226/9",
219 "epB": "of:0000000000000246/3",
220 "type": "UiDeviceLink",
221 "portA": "9",
222 "portB": "3",
223 "rollup": [
224 {
225 "id": "of:0000000000000226/9~of:0000000000000246/3",
226 "epA": "of:0000000000000226/9",
227 "epB": "of:0000000000000246/3",
228 "type": "UiDeviceLink",
229 "portA": "9",
230 "portB": "3"
231 }
232 ]
233 },
234 {
235 "id": "00:AA:00:00:00:04/None~of:0000000000000205/7",
236 "epA": "00:AA:00:00:00:04/None",
237 "epB": "of:0000000000000205",
238 "type": "UiEdgeLink",
239 "portB": "7",
240 "rollup": [
241 {
242 "id": "00:AA:00:00:00:04/None~of:0000000000000205/7",
243 "epA": "00:AA:00:00:00:04/None",
244 "epB": "of:0000000000000205",
245 "type": "UiEdgeLink",
246 "portB": "7"
247 }
248 ]
249 },
250 {
251 "id": "00:88:00:00:00:03/110~of:0000000000000205/11",
252 "epA": "00:88:00:00:00:03/110",
253 "epB": "of:0000000000000205",
254 "type": "UiEdgeLink",
255 "portB": "11",
256 "rollup": [
257 {
258 "id": "00:88:00:00:00:03/110~of:0000000000000205/11",
259 "epA": "00:88:00:00:00:03/110",
260 "epB": "of:0000000000000205",
261 "type": "UiEdgeLink",
262 "portB": "11"
263 }
264 ]
265 },
266 {
267 "id": "of:0000000000000204/1~of:0000000000000226/3",
268 "epA": "of:0000000000000204/1",
269 "epB": "of:0000000000000226/3",
270 "type": "UiDeviceLink",
271 "portA": "1",
272 "portB": "3",
273 "rollup": [
274 {
275 "id": "of:0000000000000204/1~of:0000000000000226/3",
276 "epA": "of:0000000000000204/1",
277 "epB": "of:0000000000000226/3",
278 "type": "UiDeviceLink",
279 "portA": "1",
280 "portB": "3"
281 }
282 ]
283 },
284 {
285 "id": "of:0000000000000203/2~of:0000000000000226/2",
286 "epA": "of:0000000000000203/2",
287 "epB": "of:0000000000000226/2",
288 "type": "UiDeviceLink",
289 "portA": "2",
290 "portB": "2",
291 "rollup": [
292 {
293 "id": "of:0000000000000203/2~of:0000000000000226/2",
294 "epA": "of:0000000000000203/2",
295 "epB": "of:0000000000000226/2",
296 "type": "UiDeviceLink",
297 "portA": "2",
298 "portB": "2"
299 }
300 ]
301 },
302 {
303 "id": "00:88:00:00:00:01/None~of:0000000000000205/12",
304 "epA": "00:88:00:00:00:01/None",
305 "epB": "of:0000000000000205",
306 "type": "UiEdgeLink",
307 "portB": "12",
308 "rollup": [
309 {
310 "id": "00:88:00:00:00:01/None~of:0000000000000205/12",
311 "epA": "00:88:00:00:00:01/None",
312 "epB": "of:0000000000000205",
313 "type": "UiEdgeLink",
314 "portB": "12"
315 }
316 ]
317 },
318 {
319 "id": "00:88:00:00:00:04/160~of:0000000000000206/6",
320 "epA": "00:88:00:00:00:04/160",
321 "epB": "of:0000000000000206",
322 "type": "UiEdgeLink",
323 "portB": "6",
324 "rollup": [
325 {
326 "id": "00:88:00:00:00:04/160~of:0000000000000206/6",
327 "epA": "00:88:00:00:00:04/160",
328 "epB": "of:0000000000000206",
329 "type": "UiEdgeLink",
330 "portB": "6"
331 }
332 ]
333 },
334 {
335 "id": "00:DD:00:00:00:02/None~of:0000000000000208/3",
336 "epA": "00:DD:00:00:00:02/None",
337 "epB": "of:0000000000000208",
338 "type": "UiEdgeLink",
339 "portB": "3",
340 "rollup": [
341 {
342 "id": "00:DD:00:00:00:02/None~of:0000000000000208/3",
343 "epA": "00:DD:00:00:00:02/None",
344 "epB": "of:0000000000000208",
345 "type": "UiEdgeLink",
346 "portB": "3"
347 }
348 ]
349 },
350 {
351 "id": "of:0000000000000203/3~of:0000000000000227/1",
352 "epA": "of:0000000000000203/3",
353 "epB": "of:0000000000000227/1",
354 "type": "UiDeviceLink",
355 "portA": "3",
356 "portB": "1",
357 "rollup": [
358 {
359 "id": "of:0000000000000203/3~of:0000000000000227/1",
360 "epA": "of:0000000000000203/3",
361 "epB": "of:0000000000000227/1",
362 "type": "UiDeviceLink",
363 "portA": "3",
364 "portB": "1"
365 }
366 ]
367 },
368 {
369 "id": "of:0000000000000208/2~of:0000000000000247/2",
370 "epA": "of:0000000000000208/2",
371 "epB": "of:0000000000000247/2",
372 "type": "UiDeviceLink",
373 "portA": "2",
374 "portB": "2",
375 "rollup": [
376 {
377 "id": "of:0000000000000208/2~of:0000000000000247/2",
378 "epA": "of:0000000000000208/2",
379 "epB": "of:0000000000000247/2",
380 "type": "UiDeviceLink",
381 "portA": "2",
382 "portB": "2"
383 }
384 ]
385 },
386 {
387 "id": "of:0000000000000205/1~of:0000000000000226/5",
388 "epA": "of:0000000000000205/1",
389 "epB": "of:0000000000000226/5",
390 "type": "UiDeviceLink",
391 "portA": "1",
392 "portB": "5",
393 "rollup": [
394 {
395 "id": "of:0000000000000205/1~of:0000000000000226/5",
396 "epA": "of:0000000000000205/1",
397 "epB": "of:0000000000000226/5",
398 "type": "UiDeviceLink",
399 "portA": "1",
400 "portB": "5"
401 }
402 ]
403 },
404 {
405 "id": "of:0000000000000204/2~of:0000000000000226/4",
406 "epA": "of:0000000000000204/2",
407 "epB": "of:0000000000000226/4",
408 "type": "UiDeviceLink",
409 "portA": "2",
410 "portB": "4",
411 "rollup": [
412 {
413 "id": "of:0000000000000204/2~of:0000000000000226/4",
414 "epA": "of:0000000000000204/2",
415 "epB": "of:0000000000000226/4",
416 "type": "UiDeviceLink",
417 "portA": "2",
418 "portB": "4"
419 }
420 ]
421 },
422 {
423 "id": "00:AA:00:00:00:01/None~of:0000000000000204/6",
424 "epA": "00:AA:00:00:00:01/None",
425 "epB": "of:0000000000000204",
426 "type": "UiEdgeLink",
427 "portB": "6",
428 "rollup": [
429 {
430 "id": "00:AA:00:00:00:01/None~of:0000000000000204/6",
431 "epA": "00:AA:00:00:00:01/None",
432 "epB": "of:0000000000000204",
433 "type": "UiEdgeLink",
434 "portB": "6"
435 }
436 ]
437 },
438 {
439 "id": "00:BB:00:00:00:03/None~of:0000000000000205/8",
440 "epA": "00:BB:00:00:00:03/None",
441 "epB": "of:0000000000000205",
442 "type": "UiEdgeLink",
443 "portB": "8",
444 "rollup": [
445 {
446 "id": "00:BB:00:00:00:03/None~of:0000000000000205/8",
447 "epA": "00:BB:00:00:00:03/None",
448 "epB": "of:0000000000000205",
449 "type": "UiEdgeLink",
450 "portB": "8"
451 }
452 ]
453 },
454 {
455 "id": "of:0000000000000206/4~of:0000000000000227/8",
456 "epA": "of:0000000000000206/4",
457 "epB": "of:0000000000000227/8",
458 "type": "UiDeviceLink",
459 "portA": "4",
460 "portB": "8",
461 "rollup": [
462 {
463 "id": "of:0000000000000206/4~of:0000000000000227/8",
464 "epA": "of:0000000000000206/4",
465 "epB": "of:0000000000000227/8",
466 "type": "UiDeviceLink",
467 "portA": "4",
468 "portB": "8"
469 }
470 ]
471 },
472 {
473 "id": "00:AA:00:00:00:05/None~of:0000000000000203/6",
474 "epA": "00:AA:00:00:00:05/None",
475 "epB": "of:0000000000000203",
476 "type": "UiEdgeLink",
477 "portB": "6",
478 "rollup": [
479 {
480 "id": "00:AA:00:00:00:05/None~of:0000000000000203/6",
481 "epA": "00:AA:00:00:00:05/None",
482 "epB": "of:0000000000000203",
483 "type": "UiEdgeLink",
484 "portB": "6"
485 }
486 ]
487 },
488 {
489 "id": "of:0000000000000205/5~of:0000000000000206/5",
490 "epA": "of:0000000000000205/5",
491 "epB": "of:0000000000000206/5",
492 "type": "UiDeviceLink",
493 "portA": "5",
494 "portB": "5",
495 "rollup": [
496 {
497 "id": "of:0000000000000205/5~of:0000000000000206/5",
498 "epA": "of:0000000000000205/5",
499 "epB": "of:0000000000000206/5",
500 "type": "UiDeviceLink",
501 "portA": "5",
502 "portB": "5"
503 }
504 ]
505 },
506 {
507 "id": "00:BB:00:00:00:02/None~of:0000000000000204/9",
508 "epA": "00:BB:00:00:00:02/None",
509 "epB": "of:0000000000000204",
510 "type": "UiEdgeLink",
511 "portB": "9",
512 "rollup": [
513 {
514 "id": "00:BB:00:00:00:02/None~of:0000000000000204/9",
515 "epA": "00:BB:00:00:00:02/None",
516 "epB": "of:0000000000000204",
517 "type": "UiEdgeLink",
518 "portB": "9"
519 }
520 ]
521 },
522 {
523 "id": "of:0000000000000204/3~of:0000000000000227/3",
524 "epA": "of:0000000000000204/3",
525 "epB": "of:0000000000000227/3",
526 "type": "UiDeviceLink",
527 "portA": "3",
528 "portB": "3",
529 "rollup": [
530 {
531 "id": "of:0000000000000204/3~of:0000000000000227/3",
532 "epA": "of:0000000000000204/3",
533 "epB": "of:0000000000000227/3",
534 "type": "UiDeviceLink",
535 "portA": "3",
536 "portB": "3"
537 }
538 ]
539 },
540 {
541 "id": "00:EE:00:00:00:01/None~of:0000000000000207/4",
542 "epA": "00:EE:00:00:00:01/None",
543 "epB": "of:0000000000000207",
544 "type": "UiEdgeLink",
545 "portB": "4",
546 "rollup": [
547 {
548 "id": "00:EE:00:00:00:01/None~of:0000000000000207/4",
549 "epA": "00:EE:00:00:00:01/None",
550 "epB": "of:0000000000000207",
551 "type": "UiEdgeLink",
552 "portB": "4"
553 }
554 ]
555 },
556 {
557 "id": "of:0000000000000203/4~of:0000000000000227/2",
558 "epA": "of:0000000000000203/4",
559 "epB": "of:0000000000000227/2",
560 "type": "UiDeviceLink",
561 "portA": "4",
562 "portB": "2",
563 "rollup": [
564 {
565 "id": "of:0000000000000203/4~of:0000000000000227/2",
566 "epA": "of:0000000000000203/4",
567 "epB": "of:0000000000000227/2",
568 "type": "UiDeviceLink",
569 "portA": "4",
570 "portB": "2"
571 }
572 ]
573 },
574 {
575 "id": "of:0000000000000205/2~of:0000000000000226/6",
576 "epA": "of:0000000000000205/2",
577 "epB": "of:0000000000000226/6",
578 "type": "UiDeviceLink",
579 "portA": "2",
580 "portB": "6",
581 "rollup": [
582 {
583 "id": "of:0000000000000205/2~of:0000000000000226/6",
584 "epA": "of:0000000000000205/2",
585 "epB": "of:0000000000000226/6",
586 "type": "UiDeviceLink",
587 "portA": "2",
588 "portB": "6"
589 }
590 ]
591 },
592 {
593 "id": "00:99:00:00:00:01/None~of:0000000000000205/10",
594 "epA": "00:99:00:00:00:01/None",
595 "epB": "of:0000000000000205",
596 "type": "UiEdgeLink",
597 "portB": "10",
598 "rollup": [
599 {
600 "id": "00:99:00:00:00:01/None~of:0000000000000205/10",
601 "epA": "00:99:00:00:00:01/None",
602 "epB": "of:0000000000000205",
603 "type": "UiEdgeLink",
604 "portB": "10"
605 }
606 ]
607 },
608 {
609 "id": "of:0000000000000205/4~of:0000000000000227/6",
610 "epA": "of:0000000000000205/4",
611 "epB": "of:0000000000000227/6",
612 "type": "UiDeviceLink",
613 "portA": "4",
614 "portB": "6",
615 "rollup": [
616 {
617 "id": "of:0000000000000205/4~of:0000000000000227/6",
618 "epA": "of:0000000000000205/4",
619 "epB": "of:0000000000000227/6",
620 "type": "UiDeviceLink",
621 "portA": "4",
622 "portB": "6"
623 }
624 ]
625 },
626 {
627 "id": "of:0000000000000206/3~of:0000000000000227/7",
628 "epA": "of:0000000000000206/3",
629 "epB": "of:0000000000000227/7",
630 "type": "UiDeviceLink",
631 "portA": "3",
632 "portB": "7",
633 "rollup": [
634 {
635 "id": "of:0000000000000206/3~of:0000000000000227/7",
636 "epA": "of:0000000000000206/3",
637 "epB": "of:0000000000000227/7",
638 "type": "UiDeviceLink",
639 "portA": "3",
640 "portB": "7"
641 }
642 ]
643 },
644 {
645 "id": "00:BB:00:00:00:04/None~of:0000000000000205/9",
646 "epA": "00:BB:00:00:00:04/None",
647 "epB": "of:0000000000000205",
648 "type": "UiEdgeLink",
649 "portB": "9",
650 "rollup": [
651 {
652 "id": "00:BB:00:00:00:04/None~of:0000000000000205/9",
653 "epA": "00:BB:00:00:00:04/None",
654 "epB": "of:0000000000000205",
655 "type": "UiEdgeLink",
656 "portB": "9"
657 }
658 ]
659 },
660 {
661 "id": "00:AA:00:00:00:02/None~of:0000000000000204/7",
662 "epA": "00:AA:00:00:00:02/None",
663 "epB": "of:0000000000000204",
664 "type": "UiEdgeLink",
665 "portB": "7",
666 "rollup": [
667 {
668 "id": "00:AA:00:00:00:02/None~of:0000000000000204/7",
669 "epA": "00:AA:00:00:00:02/None",
670 "epB": "of:0000000000000204",
671 "type": "UiEdgeLink",
672 "portB": "7"
673 }
674 ]
675 },
676 {
677 "id": "00:BB:00:00:00:01/None~of:0000000000000204/8",
678 "epA": "00:BB:00:00:00:01/None",
679 "epB": "of:0000000000000204",
680 "type": "UiEdgeLink",
681 "portB": "8",
682 "rollup": [
683 {
684 "id": "00:BB:00:00:00:01/None~of:0000000000000204/8",
685 "epA": "00:BB:00:00:00:01/None",
686 "epB": "of:0000000000000204",
687 "type": "UiEdgeLink",
688 "portB": "8"
689 }
690 ]
691 },
692 {
693 "id": "of:0000000000000207/1~of:0000000000000246/1",
694 "epA": "of:0000000000000207/1",
695 "epB": "of:0000000000000246/1",
696 "type": "UiDeviceLink",
697 "portA": "1",
698 "portB": "1",
699 "rollup": [
700 {
701 "id": "of:0000000000000207/1~of:0000000000000246/1",
702 "epA": "of:0000000000000207/1",
703 "epB": "of:0000000000000246/1",
704 "type": "UiDeviceLink",
705 "portA": "1",
706 "portB": "1"
707 }
708 ]
709 },
710 {
711 "id": "00:88:00:00:00:02/None~of:0000000000000206/7",
712 "epA": "00:88:00:00:00:02/None",
713 "epB": "of:0000000000000206",
714 "type": "UiEdgeLink",
715 "portB": "7",
716 "rollup": [
717 {
718 "id": "00:88:00:00:00:02/None~of:0000000000000206/7",
719 "epA": "00:88:00:00:00:02/None",
720 "epB": "of:0000000000000206",
721 "type": "UiEdgeLink",
722 "portB": "7"
723 }
724 ]
725 },
726 {
727 "id": "00:EE:00:00:00:02/None~of:0000000000000208/4",
728 "epA": "00:EE:00:00:00:02/None",
729 "epB": "of:0000000000000208",
730 "type": "UiEdgeLink",
731 "portB": "4",
732 "rollup": [
733 {
734 "id": "00:EE:00:00:00:02/None~of:0000000000000208/4",
735 "epA": "00:EE:00:00:00:02/None",
736 "epB": "of:0000000000000208",
737 "type": "UiEdgeLink",
738 "portB": "4"
739 }
740 ]
741 },
742 {
743 "id": "of:0000000000000204/4~of:0000000000000227/4",
744 "epA": "of:0000000000000204/4",
745 "epB": "of:0000000000000227/4",
746 "type": "UiDeviceLink",
747 "portA": "4",
748 "portB": "4",
749 "rollup": [
750 {
751 "id": "of:0000000000000204/4~of:0000000000000227/4",
752 "epA": "of:0000000000000204/4",
753 "epB": "of:0000000000000227/4",
754 "type": "UiDeviceLink",
755 "portA": "4",
756 "portB": "4"
757 }
758 ]
759 },
760 {
761 "id": "of:0000000000000203/5~of:0000000000000204/5",
762 "epA": "of:0000000000000203/5",
763 "epB": "of:0000000000000204/5",
764 "type": "UiDeviceLink",
765 "portA": "5",
766 "portB": "5",
767 "rollup": [
768 {
769 "id": "of:0000000000000203/5~of:0000000000000204/5",
770 "epA": "of:0000000000000203/5",
771 "epB": "of:0000000000000204/5",
772 "type": "UiDeviceLink",
773 "portA": "5",
774 "portB": "5"
775 }
776 ]
777 },
778 {
779 "id": "of:0000000000000227/9~of:0000000000000247/3",
780 "epA": "of:0000000000000227/9",
781 "epB": "of:0000000000000247/3",
782 "type": "UiDeviceLink",
783 "portA": "9",
784 "portB": "3",
785 "rollup": [
786 {
787 "id": "of:0000000000000227/9~of:0000000000000247/3",
788 "epA": "of:0000000000000227/9",
789 "epB": "of:0000000000000247/3",
790 "type": "UiDeviceLink",
791 "portA": "9",
792 "portB": "3"
793 }
794 ]
795 }
796 ],
797 "devices": [
798 [],
799 [],
800 [
801 {
802 "id": "of:0000000000000246",
803 "nodeType": "device",
804 "type": "switch",
805 "online": true,
806 "master": "10.192.19.68",
807 "layer": "def",
808 "props": {
809 "managementAddress": "10.192.19.69",
810 "protocol": "OF_13",
811 "driver": "ofdpa-ovs",
812 "latitude": "40.15",
813 "name": "s246",
814 "locType": "geo",
815 "channelId": "10.192.19.69:59980",
816 "longitude": "-121.679"
817 },
818 "location": {
819 "locType": "geo",
820 "latOrY": 40.15,
821 "longOrX": -121.679
822 }
823 },
824 {
825 "id": "of:0000000000000206",
826 "nodeType": "device",
827 "type": "switch",
828 "online": true,
829 "master": "10.192.19.68",
830 "layer": "def",
831 "props": {
832 "managementAddress": "10.192.19.69",
833 "protocol": "OF_13",
834 "driver": "ofdpa-ovs",
835 "latitude": "36.766",
836 "name": "s206",
837 "locType": "geo",
838 "channelId": "10.192.19.69:59975",
839 "longitude": "-92.029"
840 },
841 "location": {
842 "locType": "geo",
843 "latOrY": 36.766,
844 "longOrX": -92.029
845 }
846 },
847 {
848 "id": "of:0000000000000227",
849 "nodeType": "device",
850 "type": "switch",
851 "online": true,
852 "master": "10.192.19.68",
853 "layer": "def",
854 "props": {
855 "managementAddress": "10.192.19.69",
856 "protocol": "OF_13",
857 "driver": "ofdpa-ovs",
858 "latitude": "44.205",
859 "name": "s227",
860 "locType": "geo",
861 "channelId": "10.192.19.69:59979",
862 "longitude": "-96.359"
863 },
864 "location": {
865 "locType": "geo",
866 "latOrY": 44.205,
867 "longOrX": -96.359
868 }
869 },
870 {
871 "id": "of:0000000000000208",
872 "nodeType": "device",
873 "type": "switch",
874 "online": true,
875 "master": "10.192.19.68",
876 "layer": "def",
877 "props": {
878 "managementAddress": "10.192.19.69",
879 "protocol": "OF_13",
880 "driver": "ofdpa-ovs",
881 "latitude": "36.766",
882 "name": "s208",
883 "locType": "geo",
884 "channelId": "10.192.19.69:59977",
885 "longitude": "-116.029"
886 },
887 "location": {
888 "locType": "geo",
889 "latOrY": 36.766,
890 "longOrX": -116.029
891 }
892 },
893 {
894 "id": "of:0000000000000205",
895 "nodeType": "device",
896 "type": "switch",
897 "online": true,
898 "master": "10.192.19.68",
899 "layer": "def",
900 "props": {
901 "managementAddress": "10.192.19.69",
902 "protocol": "OF_13",
903 "driver": "ofdpa-ovs",
904 "latitude": "36.766",
905 "name": "s205",
906 "locType": "geo",
907 "channelId": "10.192.19.69:59974",
908 "longitude": "-96.89"
909 },
910 "location": {
911 "locType": "geo",
912 "latOrY": 36.766,
913 "longOrX": -96.89
914 }
915 },
916 {
917 "id": "of:0000000000000247",
918 "nodeType": "device",
919 "type": "switch",
920 "online": true,
921 "master": "10.192.19.68",
922 "layer": "def",
923 "props": {
924 "managementAddress": "10.192.19.69",
925 "protocol": "OF_13",
926 "driver": "ofdpa-ovs",
927 "latitude": "40.205",
928 "name": "s247",
929 "locType": "geo",
930 "channelId": "10.192.19.69:59981",
931 "longitude": "-117.359"
932 },
933 "location": {
934 "locType": "geo",
935 "latOrY": 40.205,
936 "longOrX": -117.359
937 }
938 },
939 {
940 "id": "of:0000000000000226",
941 "nodeType": "device",
942 "type": "switch",
943 "online": true,
944 "master": "10.192.19.68",
945 "layer": "def",
946 "props": {
947 "managementAddress": "10.192.19.69",
948 "protocol": "OF_13",
949 "driver": "ofdpa-ovs",
950 "latitude": "44.15",
951 "name": "s226",
952 "locType": "geo",
953 "channelId": "10.192.19.69:59978",
954 "longitude": "-107.679"
955 },
956 "location": {
957 "locType": "geo",
958 "latOrY": 44.15,
959 "longOrX": -107.679
960 }
961 },
962 {
963 "id": "of:0000000000000203",
964 "nodeType": "device",
965 "type": "switch",
966 "online": true,
967 "master": "10.192.19.68",
968 "layer": "def",
969 "props": {
970 "managementAddress": "10.192.19.69",
971 "protocol": "OF_13",
972 "driver": "ofdpa-ovs",
973 "latitude": "36.766",
974 "name": "s203",
975 "locType": "geo",
976 "channelId": "10.192.19.69:59972",
977 "longitude": "-111.359"
978 },
979 "location": {
980 "locType": "geo",
981 "latOrY": 36.766,
982 "longOrX": -111.359
983 }
984 },
985 {
986 "id": "of:0000000000000204",
987 "nodeType": "device",
988 "type": "switch",
989 "online": true,
990 "master": "10.192.19.68",
991 "layer": "def",
992 "props": {
993 "managementAddress": "10.192.19.69",
994 "protocol": "OF_13",
995 "driver": "ofdpa-ovs",
996 "latitude": "36.766",
997 "name": "s204",
998 "locType": "geo",
999 "channelId": "10.192.19.69:59973",
1000 "longitude": "-106.359"
1001 },
1002 "location": {
1003 "locType": "geo",
1004 "latOrY": 36.766,
1005 "longOrX": -106.359
1006 }
1007 },
1008 {
1009 "id": "of:0000000000000207",
1010 "nodeType": "device",
1011 "type": "switch",
1012 "online": true,
1013 "master": "10.192.19.68",
1014 "layer": "def",
1015 "props": {
1016 "managementAddress": "10.192.19.69",
1017 "protocol": "OF_13",
1018 "driver": "ofdpa-ovs",
1019 "latitude": "36.766",
1020 "name": "s207",
1021 "locType": "geo",
1022 "channelId": "10.192.19.69:59976",
1023 "longitude": "-122.359"
1024 },
1025 "location": {
1026 "locType": "geo",
1027 "latOrY": 36.766,
1028 "longOrX": -122.359
1029 }
1030 }
1031 ]
1032 ],
1033 "hosts": [
1034 [],
1035 [],
1036 [
1037 {
1038 "id": "00:88:00:00:00:03/110",
1039 "nodeType": "host",
1040 "layer": "def",
1041 "ips": [
1042 "fe80::288:ff:fe00:3",
1043 "2000::102",
1044 "10.0.1.2"
1045 ],
1046 "props": {},
1047 "configured": false
1048 },
1049 {
1050 "id": "00:DD:00:00:00:01/None",
1051 "nodeType": "host",
1052 "layer": "def",
1053 "ips": [],
1054 "props": {},
1055 "configured": false
1056 },
1057 {
1058 "id": "00:88:00:00:00:04/160",
1059 "nodeType": "host",
1060 "layer": "def",
1061 "ips": [
1062 "fe80::288:ff:fe00:4",
1063 "10.0.6.2",
1064 "2000::602"
1065 ],
1066 "props": {},
1067 "configured": false
1068 },
1069 {
1070 "id": "00:BB:00:00:00:02/None",
1071 "nodeType": "host",
1072 "layer": "def",
1073 "ips": [
1074 "fe80::2bb:ff:fe00:2"
1075 ],
1076 "props": {},
1077 "configured": false
1078 },
1079 {
1080 "id": "00:AA:00:00:00:05/None",
1081 "nodeType": "host",
1082 "layer": "def",
1083 "ips": [],
1084 "props": {},
1085 "configured": false
1086 },
1087 {
1088 "id": "00:88:00:00:00:01/None",
1089 "nodeType": "host",
1090 "layer": "def",
1091 "ips": [
1092 "fe80::288:ff:fe00:1",
1093 "2000::101",
1094 "10.0.1.1"
1095 ],
1096 "props": {},
1097 "configured": false
1098 },
1099 {
1100 "id": "00:AA:00:00:00:01/None",
1101 "nodeType": "host",
1102 "layer": "def",
1103 "ips": [],
1104 "props": {},
1105 "configured": false
1106 },
1107 {
1108 "id": "00:AA:00:00:00:03/None",
1109 "nodeType": "host",
1110 "layer": "def",
1111 "ips": [],
1112 "props": {},
1113 "configured": false
1114 },
1115 {
1116 "id": "00:BB:00:00:00:04/None",
1117 "nodeType": "host",
1118 "layer": "def",
1119 "ips": [
1120 "fe80::2bb:ff:fe00:4"
1121 ],
1122 "props": {},
1123 "configured": false
1124 },
1125 {
1126 "id": "00:EE:00:00:00:02/None",
1127 "nodeType": "host",
1128 "layer": "def",
1129 "ips": [
1130 "fe80::2ee:ff:fe00:2"
1131 ],
1132 "props": {},
1133 "configured": false
1134 },
1135 {
1136 "id": "00:99:00:00:00:01/None",
1137 "nodeType": "host",
1138 "layer": "def",
1139 "ips": [
1140 "10.0.3.253",
1141 "fe80::299:ff:fe00:1"
1142 ],
1143 "props": {},
1144 "configured": false
1145 },
1146 {
1147 "id": "00:99:66:00:00:01/None",
1148 "nodeType": "host",
1149 "layer": "def",
1150 "ips": [
1151 "fe80::299:66ff:fe00:1",
1152 "2000::3fd"
1153 ],
1154 "props": {},
1155 "configured": false
1156 },
1157 {
1158 "id": "00:EE:00:00:00:01/None",
1159 "nodeType": "host",
1160 "layer": "def",
1161 "ips": [
1162 "fe80::2ee:ff:fe00:1"
1163 ],
1164 "props": {},
1165 "configured": false
1166 },
1167 {
1168 "id": "00:BB:00:00:00:01/None",
1169 "nodeType": "host",
1170 "layer": "def",
1171 "ips": [
1172 "fe80::2bb:ff:fe00:1"
1173 ],
1174 "props": {},
1175 "configured": false
1176 },
1177 {
1178 "id": "00:BB:00:00:00:03/None",
1179 "nodeType": "host",
1180 "layer": "def",
1181 "ips": [
1182 "fe80::2bb:ff:fe00:3"
1183 ],
1184 "props": {},
1185 "configured": false
1186 },
1187 {
1188 "id": "00:AA:00:00:00:04/None",
1189 "nodeType": "host",
1190 "layer": "def",
1191 "ips": [],
1192 "props": {},
1193 "configured": false
1194 },
1195 {
1196 "id": "00:BB:00:00:00:05/None",
1197 "nodeType": "host",
1198 "layer": "def",
1199 "ips": [
1200 "fe80::2bb:ff:fe00:5"
1201 ],
1202 "props": {},
1203 "configured": false
1204 },
1205 {
1206 "id": "00:88:00:00:00:02/None",
1207 "nodeType": "host",
1208 "layer": "def",
1209 "ips": [
1210 "fe80::288:ff:fe00:2",
1211 "2000::601",
1212 "10.0.6.1"
1213 ],
1214 "props": {},
1215 "configured": false
1216 },
1217 {
1218 "id": "00:AA:00:00:00:02/None",
1219 "nodeType": "host",
1220 "layer": "def",
1221 "ips": [],
1222 "props": {},
1223 "configured": false
1224 },
1225 {
1226 "id": "00:DD:00:00:00:02/None",
1227 "nodeType": "host",
1228 "layer": "def",
1229 "ips": [],
1230 "props": {},
1231 "configured": false
1232 }
1233 ]
1234 ],
1235 "layerOrder": [
1236 "opt",
1237 "pkt",
1238 "def"
1239 ]
1240 }
1241}`;
1242
1243const test_OdtnConfig_topo2CurrentRegion = `{
1244 "event": "topo2CurrentRegion",
1245 "payload": {
1246 "id": "(root)",
1247 "subregions": [],
1248 "links": [
1249 {
1250 "id": "netconf:127.0.0.1:11002/201~netconf:127.0.0.1:11003/201",
1251 "epA": "netconf:127.0.0.1:11002/201",
1252 "epB": "netconf:127.0.0.1:11003/201",
1253 "type": "UiDeviceLink",
1254 "portA": "201",
1255 "portB": "201",
1256 "rollup": [
1257 {
1258 "id": "netconf:127.0.0.1:11002/201~netconf:127.0.0.1:11003/201",
1259 "epA": "netconf:127.0.0.1:11002/201",
1260 "epB": "netconf:127.0.0.1:11003/201",
1261 "type": "UiDeviceLink",
1262 "portA": "201",
1263 "portB": "201"
1264 }
1265 ]
1266 },
1267 {
1268 "id": "netconf:127.0.0.1:11002/202~netconf:127.0.0.1:11003/202",
1269 "epA": "netconf:127.0.0.1:11002/202",
1270 "epB": "netconf:127.0.0.1:11003/202",
1271 "type": "UiDeviceLink",
1272 "portA": "202",
1273 "portB": "202",
1274 "rollup": [
1275 {
1276 "id": "netconf:127.0.0.1:11002/202~netconf:127.0.0.1:11003/202",
1277 "epA": "netconf:127.0.0.1:11002/202",
1278 "epB": "netconf:127.0.0.1:11003/202",
1279 "type": "UiDeviceLink",
1280 "portA": "202",
1281 "portB": "202"
1282 }
1283 ]
1284 },
1285 {
1286 "id": "netconf:127.0.0.1:11002/203~netconf:127.0.0.1:11003/203",
1287 "epA": "netconf:127.0.0.1:11002/203",
1288 "epB": "netconf:127.0.0.1:11003/203",
1289 "type": "UiDeviceLink",
1290 "portA": "203",
1291 "portB": "203",
1292 "rollup": [
1293 {
1294 "id": "netconf:127.0.0.1:11002/203~netconf:127.0.0.1:11003/203",
1295 "epA": "netconf:127.0.0.1:11002/203",
1296 "epB": "netconf:127.0.0.1:11003/203",
1297 "type": "UiDeviceLink",
1298 "portA": "203",
1299 "portB": "203"
1300 }
1301 ]
1302 },
1303 {
1304 "id": "netconf:127.0.0.1:11002/204~netconf:127.0.0.1:11003/204",
1305 "epA": "netconf:127.0.0.1:11002/204",
1306 "epB": "netconf:127.0.0.1:11003/204",
1307 "type": "UiDeviceLink",
1308 "portA": "204",
1309 "portB": "204",
1310 "rollup": [
1311 {
1312 "id": "netconf:127.0.0.1:11002/204~netconf:127.0.0.1:11003/204",
1313 "epA": "netconf:127.0.0.1:11002/204",
1314 "epB": "netconf:127.0.0.1:11003/204",
1315 "type": "UiDeviceLink",
1316 "portA": "204",
1317 "portB": "204"
1318 }
1319 ]
1320 },
1321 {
1322 "id": "netconf:127.0.0.1:11002/205~netconf:127.0.0.1:11003/205",
1323 "epA": "netconf:127.0.0.1:11002/205",
1324 "epB": "netconf:127.0.0.1:11003/205",
1325 "type": "UiDeviceLink",
1326 "portA": "205",
1327 "portB": "205",
1328 "rollup": [
1329 {
1330 "id": "netconf:127.0.0.1:11002/205~netconf:127.0.0.1:11003/205",
1331 "epA": "netconf:127.0.0.1:11002/205",
1332 "epB": "netconf:127.0.0.1:11003/205",
1333 "type": "UiDeviceLink",
1334 "portA": "205",
1335 "portB": "205"
1336 }
1337 ]
1338 },
1339 {
1340 "id": "netconf:127.0.0.1:11002/206~netconf:127.0.0.1:11003/206",
1341 "epA": "netconf:127.0.0.1:11002/206",
1342 "epB": "netconf:127.0.0.1:11003/206",
1343 "type": "UiDeviceLink",
1344 "portA": "206",
1345 "portB": "206",
1346 "rollup": [
1347 {
1348 "id": "netconf:127.0.0.1:11002/206~netconf:127.0.0.1:11003/206",
1349 "epA": "netconf:127.0.0.1:11002/206",
1350 "epB": "netconf:127.0.0.1:11003/206",
1351 "type": "UiDeviceLink",
1352 "portA": "206",
1353 "portB": "206"
1354 }
1355 ]
1356 }
1357 ],
1358 "devices": [
1359 [],
1360 [],
1361 [
1362 {
1363 "id": "netconf:127.0.0.1:11002",
1364 "nodeType": "device",
1365 "type": "terminal_device",
1366 "online": true,
1367 "master": "127.0.0.1",
1368 "layer": "def",
1369 "props": {
1370 "ipaddress": "127.0.0.1",
1371 "protocol": "NETCONF",
1372 "driver": "cassini-ocnos",
1373 "port": "11002",
1374 "name": "cassini2",
1375 "locType": "none"
1376 }
1377 },
1378 {
1379 "id": "netconf:127.0.0.1:11003",
1380 "nodeType": "device",
1381 "type": "terminal_device",
1382 "online": true,
1383 "master": "127.0.0.1",
1384 "layer": "def",
1385 "props": {
1386 "ipaddress": "127.0.0.1",
1387 "protocol": "NETCONF",
1388 "driver": "cassini-ocnos",
1389 "port": "11003",
1390 "name": "cassini1",
1391 "locType": "none"
1392 }
1393 }
1394 ]
1395 ],
1396 "hosts": [
1397 [],
1398 [],
1399 []
1400 ],
1401 "layerOrder": [
1402 "opt",
1403 "pkt",
1404 "def"
1405 ]
1406 }
1407}`;
1408
1409const topo2Highlights_base_data = `{
1410 "event": "topo2CurrentRegion",
1411 "payload": {
1412 "id": "(root)",
1413 "subregions": [],
1414 "links": [
1415 {
1416 "id": "device:leaf1/1~device:spine1/1",
1417 "epA": "device:leaf1/1",
1418 "epB": "device:spine1/1",
1419 "type": "UiDeviceLink",
1420 "portA": "1",
1421 "portB": "1",
1422 "rollup": [
1423 {
1424 "id": "device:leaf1/1~device:spine1/1",
1425 "epA": "device:leaf1/1",
1426 "epB": "device:spine1/1",
1427 "type": "UiDeviceLink",
1428 "portA": "1",
1429 "portB": "1"
1430 }
1431 ]
1432 },
1433 {
1434 "id": "device:leaf2/2~device:spine2/2",
1435 "epA": "device:leaf2/2",
1436 "epB": "device:spine2/2",
1437 "type": "UiDeviceLink",
1438 "portA": "2",
1439 "portB": "2",
1440 "rollup": [
1441 {
1442 "id": "device:leaf2/2~device:spine2/2",
1443 "epA": "device:leaf2/2",
1444 "epB": "device:spine2/2",
1445 "type": "UiDeviceLink",
1446 "portA": "2",
1447 "portB": "2"
1448 }
1449 ]
1450 },
1451 {
1452 "id": "00:00:00:00:00:1A/None~device:leaf1/3",
1453 "epA": "00:00:00:00:00:1A/None",
1454 "epB": "device:leaf1",
1455 "type": "UiEdgeLink",
1456 "portB": "3",
1457 "rollup": [
1458 {
1459 "id": "00:00:00:00:00:1A/None~device:leaf1/3",
1460 "epA": "00:00:00:00:00:1A/None",
1461 "epB": "device:leaf1",
1462 "type": "UiEdgeLink",
1463 "portB": "3"
1464 }
1465 ]
1466 },
1467 {
1468 "id": "00:00:00:00:00:30/None~device:leaf2/3",
1469 "epA": "00:00:00:00:00:30/None",
1470 "epB": "device:leaf2",
1471 "type": "UiEdgeLink",
1472 "portB": "3",
1473 "rollup": [
1474 {
1475 "id": "00:00:00:00:00:30/None~device:leaf2/3",
1476 "epA": "00:00:00:00:00:30/None",
1477 "epB": "device:leaf2",
1478 "type": "UiEdgeLink",
1479 "portB": "3"
1480 }
1481 ]
1482 },
1483 {
1484 "id": "device:leaf1/2~device:spine2/1",
1485 "epA": "device:leaf1/2",
1486 "epB": "device:spine2/1",
1487 "type": "UiDeviceLink",
1488 "portA": "2",
1489 "portB": "1",
1490 "rollup": [
1491 {
1492 "id": "device:leaf1/2~device:spine2/1",
1493 "epA": "device:leaf1/2",
1494 "epB": "device:spine2/1",
1495 "type": "UiDeviceLink",
1496 "portA": "2",
1497 "portB": "1"
1498 }
1499 ]
1500 },
1501 {
1502 "id": "device:leaf2/1~device:spine1/2",
1503 "epA": "device:leaf2/1",
1504 "epB": "device:spine1/2",
1505 "type": "UiDeviceLink",
1506 "portA": "1",
1507 "portB": "2",
1508 "rollup": [
1509 {
1510 "id": "device:leaf2/1~device:spine1/2",
1511 "epA": "device:leaf2/1",
1512 "epB": "device:spine1/2",
1513 "type": "UiDeviceLink",
1514 "portA": "1",
1515 "portB": "2"
1516 }
1517 ]
1518 },
1519 {
1520 "id": "00:00:00:00:00:20/None~device:leaf1/6",
1521 "epA": "00:00:00:00:00:20/None",
1522 "epB": "device:leaf1",
1523 "type": "UiEdgeLink",
1524 "portB": "6",
1525 "rollup": [
1526 {
1527 "id": "00:00:00:00:00:20/None~device:leaf1/6",
1528 "epA": "00:00:00:00:00:20/None",
1529 "epB": "device:leaf1",
1530 "type": "UiEdgeLink",
1531 "portB": "6"
1532 }
1533 ]
1534 },
1535 {
1536 "id": "00:00:00:00:00:1C/None~device:leaf1/5",
1537 "epA": "00:00:00:00:00:1C/None",
1538 "epB": "device:leaf1",
1539 "type": "UiEdgeLink",
1540 "portB": "5",
1541 "rollup": [
1542 {
1543 "id": "00:00:00:00:00:1C/None~device:leaf1/5",
1544 "epA": "00:00:00:00:00:1C/None",
1545 "epB": "device:leaf1",
1546 "type": "UiEdgeLink",
1547 "portB": "5"
1548 }
1549 ]
1550 },
1551 {
1552 "id": "00:00:00:00:00:1B/None~device:leaf1/4",
1553 "epA": "00:00:00:00:00:1B/None",
1554 "epB": "device:leaf1",
1555 "type": "UiEdgeLink",
1556 "portB": "4",
1557 "rollup": [
1558 {
1559 "id": "00:00:00:00:00:1B/None~device:leaf1/4",
1560 "epA": "00:00:00:00:00:1B/None",
1561 "epB": "device:leaf1",
1562 "type": "UiEdgeLink",
1563 "portB": "4"
1564 }
1565 ]
1566 }
1567 ],
1568 "devices": [
1569 [],
1570 [],
1571 [
1572 {
1573 "id": "device:spine1",
1574 "nodeType": "device",
1575 "type": "switch",
1576 "online": true,
1577 "master": "172.24.0.3",
1578 "layer": "def",
1579 "props": {
1580 "managementAddress": "grpc://mininet:50003?device_id=1",
1581 "protocol": "P4Runtime, gNMI, gNOI",
1582 "gridX": "400.0",
1583 "gridY": "400.0",
1584 "driver": "stratum-bmv2",
1585 "name": "device:spine1",
1586 "p4DeviceId": "1",
1587 "locType": "grid"
1588 },
1589 "location": {
1590 "locType": "grid",
1591 "latOrY": 400.0,
1592 "longOrX": 400.0
1593 }
1594 },
1595 {
1596 "id": "device:spine2",
1597 "nodeType": "device",
1598 "type": "switch",
1599 "online": true,
1600 "master": "172.24.0.3",
1601 "layer": "def",
1602 "props": {
1603 "managementAddress": "grpc://mininet:50004?device_id=1",
1604 "protocol": "P4Runtime, gNMI, gNOI",
1605 "gridX": "600.0",
1606 "gridY": "400.0",
1607 "driver": "stratum-bmv2",
1608 "name": "device:spine2",
1609 "p4DeviceId": "1",
1610 "locType": "grid"
1611 },
1612 "location": {
1613 "locType": "grid",
1614 "latOrY": 400.0,
1615 "longOrX": 600.0
1616 }
1617 },
1618 {
1619 "id": "device:leaf2",
1620 "nodeType": "device",
1621 "type": "switch",
1622 "online": true,
1623 "master": "172.24.0.3",
1624 "layer": "def",
1625 "props": {
1626 "managementAddress": "grpc://mininet:50002?device_id=1",
1627 "protocol": "P4Runtime, gNMI, gNOI",
1628 "gridX": "800.0",
1629 "gridY": "600.0",
1630 "driver": "stratum-bmv2",
1631 "name": "device:leaf2",
1632 "p4DeviceId": "1",
1633 "locType": "grid"
1634 },
1635 "location": {
1636 "locType": "grid",
1637 "latOrY": 600.0,
1638 "longOrX": 800.0
1639 }
1640 },
1641 {
1642 "id": "device:leaf1",
1643 "nodeType": "device",
1644 "type": "switch",
1645 "online": true,
1646 "master": "172.24.0.3",
1647 "layer": "def",
1648 "props": {
1649 "managementAddress": "grpc://mininet:50001?device_id=1",
1650 "protocol": "P4Runtime, gNMI, gNOI",
1651 "gridX": "200.0",
1652 "gridY": "600.0",
1653 "driver": "stratum-bmv2",
1654 "name": "device:leaf1",
1655 "p4DeviceId": "1",
1656 "locType": "grid"
1657 },
1658 "location": {
1659 "locType": "grid",
1660 "latOrY": 600.0,
1661 "longOrX": 200.0
1662 }
1663 }
1664 ]
1665 ],
1666 "hosts": [
1667 [],
1668 [],
1669 [
1670 {
1671 "id": "00:00:00:00:00:30/None",
1672 "nodeType": "host",
1673 "layer": "def",
1674 "ips": [
1675 "2001:2:3::1"
1676 ],
1677 "props": {
1678 "gridX": "750.0",
1679 "gridY": "700.0",
1680 "latitude": null,
1681 "name": "h3",
1682 "locType": "grid",
1683 "longitude": null
1684 },
1685 "location": {
1686 "locType": "grid",
1687 "latOrY": 700.0,
1688 "longOrX": 750.0
1689 },
1690 "configured": false
1691 },
1692 {
1693 "id": "00:00:00:00:00:1A/None",
1694 "nodeType": "host",
1695 "layer": "def",
1696 "ips": [
1697 "2001:1:1::a"
1698 ],
1699 "props": {
1700 "gridX": "100.0",
1701 "gridY": "700.0",
1702 "latitude": null,
1703 "name": "h1a",
1704 "locType": "grid",
1705 "longitude": null
1706 },
1707 "location": {
1708 "locType": "grid",
1709 "latOrY": 700.0,
1710 "longOrX": 100.0
1711 },
1712 "configured": false
1713 },
1714 {
1715 "id": "00:00:00:00:00:1B/None",
1716 "nodeType": "host",
1717 "layer": "def",
1718 "ips": [
1719 "2001:1:1::b"
1720 ],
1721 "props": {
1722 "gridX": "100.0",
1723 "gridY": "800.0",
1724 "latitude": null,
1725 "name": "h1b",
1726 "locType": "grid",
1727 "longitude": null
1728 },
1729 "location": {
1730 "locType": "grid",
1731 "latOrY": 800.0,
1732 "longOrX": 100.0
1733 },
1734 "configured": false
1735 },
1736 {
1737 "id": "00:00:00:00:00:1C/None",
1738 "nodeType": "host",
1739 "layer": "def",
1740 "ips": [
1741 "2001:1:1::c"
1742 ],
1743 "props": {
1744 "gridX": "250.0",
1745 "gridY": "800.0",
1746 "latitude": null,
1747 "name": "h1c",
1748 "locType": "grid",
1749 "longitude": null
1750 },
1751 "location": {
1752 "locType": "grid",
1753 "latOrY": 800.0,
1754 "longOrX": 250.0
1755 },
1756 "configured": false
1757 },
1758 {
1759 "id": "00:00:00:00:00:20/None",
1760 "nodeType": "host",
1761 "layer": "def",
1762 "ips": [
1763 "2001:1:2::1"
1764 ],
1765 "props": {
1766 "gridX": "400.0",
1767 "gridY": "700.0",
1768 "latitude": null,
1769 "name": "h2",
1770 "locType": "grid",
1771 "longitude": null
1772 },
1773 "location": {
1774 "locType": "grid",
1775 "latOrY": 700.0,
1776 "longOrX": 400.0
1777 },
1778 "configured": false
1779 }
1780 ]
1781 ],
1782 "layerOrder": [
1783 "opt",
1784 "pkt",
1785 "def"
1786 ]
1787 }
1788}`;
1789
1790const topo2Highlights_sample = `
1791{
1792 "event": "topo2Highlights",
1793 "payload": {
1794 "devices": [],
1795 "hosts": [],
1796 "links": [
1797 {
1798 "id": "device:leaf2/2~device:spine2/2",
1799 "label": "964.91 Kbps",
1800 "css": "secondary port-traffic-green"
1801 },
1802 {
1803 "id": "device:leaf1/1~device:spine1/1",
1804 "label": "3.92 Mbps",
1805 "css": "secondary port-traffic-yellow"
1806 },
1807 {
1808 "id": "00:00:00:00:00:30/None~device:leaf2/3",
1809 "label": "4.46 Mbps",
1810 "css": "secondary port-traffic-yellow"
1811 },
1812 {
1813 "id": "device:leaf2/1~device:spine1/2",
1814 "label": "3.53 Mbps",
1815 "css": "secondary port-traffic-yellow"
1816 },
1817 {
1818 "id": "device:leaf1/2~device:spine2/1",
1819 "label": "1.06 Mbps",
1820 "css": "secondary port-traffic-yellow"
1821 },
1822 {
1823 "id": "00:00:00:00:00:20/None~device:leaf1/6",
1824 "label": "4.98 Mbps",
1825 "css": "secondary port-traffic-yellow"
1826 }
1827 ]
1828 }
1829}`;
1830
Sean Condon0c577f62018-11-18 22:40:05 +00001831class MockActivatedRoute extends ActivatedRoute {
1832 constructor(params: Params) {
1833 super();
1834 this.queryParams = of(params);
1835 }
1836}
1837
Sean Condon64060ff2019-05-30 15:48:11 +01001838class MockIconService {
1839 loadIconDef() { }
1840}
1841
1842class MockSvgUtilService {
1843
1844 cat7() {
1845 const tcid = 'd3utilTestCard';
1846
1847 function getColor(id, muted, theme) {
1848 // NOTE: since we are lazily assigning domain ids, we need to
1849 // get the color from all 4 scales, to keep the domains
1850 // in sync.
1851 const ln = '#5b99d2';
1852 const lm = '#9ebedf';
1853 const dn = '#5b99d2';
1854 const dm = '#9ebedf';
1855 if (theme === 'dark') {
1856 return muted ? dm : dn;
1857 } else {
1858 return muted ? lm : ln;
1859 }
1860 }
1861
1862 return {
1863 // testCard: testCard,
1864 getColor: getColor,
1865 };
1866 }
1867}
1868
1869class MockUrlFnService { }
1870
1871class MockWebSocketService {
1872 createWebSocket() { }
1873 isConnected() { return false; }
1874 unbindHandlers() { }
1875 bindHandlers() { }
1876}
1877
1878class MockTopologyService {
1879 public instancesIndex: Map<string, number>;
1880 constructor() {
1881 this.instancesIndex = new Map();
1882 }
1883}
1884
Sean Condonf4f54a12018-10-10 23:25:46 +01001885describe('ForceSvgComponent', () => {
Sean Condon71910542019-02-16 18:16:42 +00001886 let fs: FnService;
Sean Condon0c577f62018-11-18 22:40:05 +00001887 let ar: MockActivatedRoute;
1888 let windowMock: Window;
1889 let logServiceSpy: jasmine.SpyObj<LogService>;
Sean Condonf4f54a12018-10-10 23:25:46 +01001890 let component: ForceSvgComponent;
1891 let fixture: ComponentFixture<ForceSvgComponent>;
Sean Condon4ceeae72021-10-21 15:37:11 +01001892 const openflowSampleData = JSON.parse(test_module_topo2CurrentRegion);
Sean Condonb77768e2019-05-04 20:23:42 +01001893 const openflowRegionData: Region = <Region><unknown>(openflowSampleData.payload);
1894
Sean Condon4ceeae72021-10-21 15:37:11 +01001895 const odtnSampleData = JSON.parse(test_OdtnConfig_topo2CurrentRegion);
Sean Condonb77768e2019-05-04 20:23:42 +01001896 const odtnRegionData: Region = <Region><unknown>(odtnSampleData.payload);
1897
Sean Condon4ceeae72021-10-21 15:37:11 +01001898 const topo2BaseData = JSON.parse(topo2Highlights_base_data);
Sean Condonf9ff66a2020-03-23 08:40:55 +00001899 const topo2BaseRegionData: Region = <Region><unknown>(topo2BaseData.payload);
1900
Sean Condon4ceeae72021-10-21 15:37:11 +01001901 const highlightSampleData = JSON.parse(topo2Highlights_sample);
Sean Condonf9ff66a2020-03-23 08:40:55 +00001902 const linkHightlights: LinkHighlight[] = <LinkHighlight[]><unknown>(highlightSampleData.payload.links);
1903
Sean Condonc13d9562019-04-18 13:24:42 +01001904 const emptyRegion: Region = <Region>{devices: [ [], [], [] ], hosts: [ [], [], [] ], links: []};
Sean Condonf4f54a12018-10-10 23:25:46 +01001905
Sean Condon64060ff2019-05-30 15:48:11 +01001906 beforeEach(() => {
Sean Condon0c577f62018-11-18 22:40:05 +00001907 const logSpy = jasmine.createSpyObj('LogService', ['info', 'debug', 'warn', 'error']);
1908 ar = new MockActivatedRoute({ 'debug': 'txrx' });
1909
1910 windowMock = <any>{
1911 location: <any>{
1912 hostname: 'foo',
1913 host: 'foo',
1914 port: '80',
1915 protocol: 'http',
1916 search: { debug: 'true' },
1917 href: 'ws://foo:123/onos/ui/websock/path',
1918 absUrl: 'ws://foo:123/onos/ui/websock/path'
1919 }
1920 };
1921
Sean Condon64060ff2019-05-30 15:48:11 +01001922 const bundleObj = {
1923 'core.view.Topo': {
1924 test: 'test1'
1925 }
1926 };
1927 const mockLion = (key) => {
1928 return bundleObj[key] || '%' + key + '%';
1929 };
1930
Sean Condon71910542019-02-16 18:16:42 +00001931 fs = new FnService(ar, logSpy, windowMock);
1932
Sean Condonf4f54a12018-10-10 23:25:46 +01001933 TestBed.configureTestingModule({
Sean Condon0c577f62018-11-18 22:40:05 +00001934 declarations: [
1935 ForceSvgComponent,
1936 DeviceNodeSvgComponent,
1937 HostNodeSvgComponent,
1938 SubRegionNodeSvgComponent,
Sean Condon50855cf2018-12-23 15:37:42 +00001939 LinkSvgComponent,
Sean Condon590b34b2019-12-04 18:44:37 +00001940 DraggableDirective,
1941 BadgeSvgComponent
Sean Condon0c577f62018-11-18 22:40:05 +00001942 ],
1943 providers: [
1944 { provide: LogService, useValue: logSpy },
Sean Condon64060ff2019-05-30 15:48:11 +01001945 { provide: ActivatedRoute, useValue: ar },
1946 { provide: FnService, useValue: fs },
1947 { provide: ChangeDetectorRef, useClass: ChangeDetectorRef },
1948 { provide: UrlFnService, useClass: MockUrlFnService },
1949 { provide: WebSocketService, useClass: MockWebSocketService },
1950 { provide: LionService, useFactory: (() => {
1951 return {
1952 bundle: ((bundleId) => mockLion),
1953 ubercache: new Array(),
1954 loadCbs: new Map<string, () => void>([])
1955 };
1956 })
1957 },
1958 { provide: IconService, useClass: MockIconService },
1959 { provide: SvgUtilService, useClass: MockSvgUtilService },
1960 { provide: TopologyService, useClass: MockTopologyService },
Sean Condon71910542019-02-16 18:16:42 +00001961 { provide: 'Window', useValue: windowMock },
Sean Condon0c577f62018-11-18 22:40:05 +00001962 ]
Sean Condonf4f54a12018-10-10 23:25:46 +01001963 })
1964 .compileComponents();
Sean Condon0c577f62018-11-18 22:40:05 +00001965 logServiceSpy = TestBed.get(LogService);
Sean Condonf4f54a12018-10-10 23:25:46 +01001966
Sean Condonf4f54a12018-10-10 23:25:46 +01001967 fixture = TestBed.createComponent(ForceSvgComponent);
Sean Condon0c577f62018-11-18 22:40:05 +00001968 component = fixture.debugElement.componentInstance;
Sean Condonf4f54a12018-10-10 23:25:46 +01001969 fixture.detectChanges();
1970 });
1971
1972 it('should create', () => {
1973 expect(component).toBeTruthy();
1974 });
Sean Condonc13d9562019-04-18 13:24:42 +01001975
Sean Condonb77768e2019-05-04 20:23:42 +01001976 it('load sample files', () => {
1977 expect(openflowSampleData).toBeTruthy();
1978 expect(openflowSampleData.payload).toBeTruthy();
1979 expect(openflowSampleData.payload.id).toBe('(root)');
1980
1981 expect(odtnSampleData).toBeTruthy();
1982 expect(odtnSampleData.payload).toBeTruthy();
1983 expect(odtnSampleData.payload.id).toBe('(root)');
Sean Condonc13d9562019-04-18 13:24:42 +01001984 });
1985
1986 it('should read sample data payload as Region', () => {
Sean Condonb77768e2019-05-04 20:23:42 +01001987 expect(openflowRegionData).toBeTruthy();
Sean Condonc13d9562019-04-18 13:24:42 +01001988 // console.log(regionData);
Sean Condonb77768e2019-05-04 20:23:42 +01001989 expect(openflowRegionData.id).toBe('(root)');
1990 expect(openflowRegionData.devices).toBeTruthy();
1991 expect(openflowRegionData.devices.length).toBe(3);
1992 expect(openflowRegionData.devices[2].length).toBe(10);
1993 expect(openflowRegionData.hosts.length).toBe(3);
1994 expect(openflowRegionData.hosts[2].length).toBe(20);
1995 expect(openflowRegionData.links.length).toBe(44);
Sean Condonc13d9562019-04-18 13:24:42 +01001996 });
1997
1998 it('should read device246 correctly', () => {
Sean Condonb77768e2019-05-04 20:23:42 +01001999 const device246: Device = openflowRegionData.devices[2][0];
Sean Condonc13d9562019-04-18 13:24:42 +01002000 expect(device246.id).toBe('of:0000000000000246');
2001 expect(device246.nodeType).toBe('device');
2002 expect(device246.type).toBe('switch');
2003 expect(device246.online).toBe(true);
2004 expect(device246.master).toBe('10.192.19.68');
2005 expect(device246.layer).toBe('def');
2006
2007 expect(device246.props.managementAddress).toBe('10.192.19.69');
2008 expect(device246.props.protocol).toBe('OF_13');
2009 expect(device246.props.driver).toBe('ofdpa-ovs');
2010 expect(device246.props.latitude).toBe('40.15');
2011 expect(device246.props.name).toBe('s246');
2012 expect(device246.props.locType).toBe('geo');
2013 expect(device246.props.channelId).toBe('10.192.19.69:59980');
2014 expect(device246.props.longitude).toBe('-121.679');
2015
2016 expect(device246.location.locType).toBe('geo');
2017 expect(device246.location.latOrY).toBe(40.15);
2018 expect(device246.location.longOrX).toBe(-121.679);
2019 });
2020
2021 it('should read host 3 correctly', () => {
Sean Condonb77768e2019-05-04 20:23:42 +01002022 const host3: Host = openflowRegionData.hosts[2][0];
Sean Condonc13d9562019-04-18 13:24:42 +01002023 expect(host3.id).toBe('00:88:00:00:00:03/110');
2024 expect(host3.nodeType).toBe('host');
2025 expect(host3.layer).toBe('def');
2026 expect(host3.configured).toBe(false);
2027 expect(host3.ips.length).toBe(3);
2028 expect(host3.ips[0]).toBe('fe80::288:ff:fe00:3');
2029 expect(host3.ips[1]).toBe('2000::102');
2030 expect(host3.ips[2]).toBe('10.0.1.2');
2031 });
2032
2033 it('should read link 3-205 correctly', () => {
Sean Condonb77768e2019-05-04 20:23:42 +01002034 const link3_205: Link = openflowRegionData.links[0];
Sean Condonc13d9562019-04-18 13:24:42 +01002035 expect(link3_205.id).toBe('00:AA:00:00:00:03/None~of:0000000000000205/6');
2036 expect(link3_205.epA).toBe('00:AA:00:00:00:03/None');
2037 expect(link3_205.epB).toBe('of:0000000000000205');
2038 expect(String(LinkType[link3_205.type])).toBe('2');
2039 expect(link3_205.portA).toBe(undefined);
2040 expect(link3_205.portB).toBe('6');
2041
2042 expect(link3_205.rollup).toBeTruthy();
2043 expect(link3_205.rollup.length).toBe(1);
2044 expect(link3_205.rollup[0].id).toBe('00:AA:00:00:00:03/None~of:0000000000000205/6');
2045 expect(link3_205.rollup[0].epA).toBe('00:AA:00:00:00:03/None');
2046 expect(link3_205.rollup[0].epB).toBe('of:0000000000000205');
2047 expect(String(LinkType[link3_205.rollup[0].type])).toBe('2');
2048 expect(link3_205.rollup[0].portA).toBe(undefined);
2049 expect(link3_205.rollup[0].portB).toBe('6');
2050
2051 });
2052
2053 it('should handle regionData change - empty Region', () => {
2054 component.ngOnChanges(
2055 {'regionData' : new SimpleChange(<Region>{}, emptyRegion, true)});
2056
2057 expect(component.graph.nodes.length).toBe(0);
2058 });
2059
Sean Condonb77768e2019-05-04 20:23:42 +01002060 it('should know how to format names', () => {
2061 expect(ForceSvgComponent.extractNodeName('00:AA:00:00:00:03/None', undefined))
Sean Condonc13d9562019-04-18 13:24:42 +01002062 .toEqual('00:AA:00:00:00:03/None');
2063
Sean Condonb77768e2019-05-04 20:23:42 +01002064 expect(ForceSvgComponent.extractNodeName('00:AA:00:00:00:03/161', '161'))
2065 .toEqual('00:AA:00:00:00:03');
Sean Condonc13d9562019-04-18 13:24:42 +01002066
Sean Condonb77768e2019-05-04 20:23:42 +01002067 // Like epB of first example in sampleData file - endPtStr contains port number
2068 expect(ForceSvgComponent.extractNodeName('of:0000000000000206/6', '6'))
2069 .toEqual('of:0000000000000206');
2070
2071 // Like epB of second example in sampleData file - endPtStr does not contain port number
2072 expect(ForceSvgComponent.extractNodeName('of:0000000000000206', '6'))
Sean Condonc13d9562019-04-18 13:24:42 +01002073 .toEqual('of:0000000000000206');
2074 });
2075
Sean Condonb77768e2019-05-04 20:23:42 +01002076 it('should handle openflow regionData change - sample Region', () => {
2077 component.regionData = openflowRegionData;
Sean Condonc13d9562019-04-18 13:24:42 +01002078 component.ngOnChanges(
Sean Condonb77768e2019-05-04 20:23:42 +01002079 {'regionData' : new SimpleChange(<Region>{}, openflowRegionData, true)});
Sean Condonc13d9562019-04-18 13:24:42 +01002080
2081 expect(component.graph.nodes.length).toBe(30);
2082
2083 expect(component.graph.links.length).toBe(44);
2084
2085 });
Sean Condonb77768e2019-05-04 20:23:42 +01002086
2087 it('should handle odtn regionData change - sample odtn Region', () => {
2088 component.regionData = odtnRegionData;
2089 component.ngOnChanges(
2090 {'regionData' : new SimpleChange(<Region>{}, odtnRegionData, true)});
2091
2092 expect(component.graph.nodes.length).toBe(2);
2093
2094 expect(component.graph.links.length).toBe(6);
2095
2096 });
Sean Condonf9ff66a2020-03-23 08:40:55 +00002097
2098 it('should handle highlights and match them to existing links', () => {
2099 component.regionData = topo2BaseRegionData;
2100 component.ngOnChanges(
2101 {'regionData' : new SimpleChange(<Region>{}, topo2BaseRegionData, true)});
2102
2103 expect(component.graph.links.length).toBe(9);
2104
2105 expect(linkHightlights.length).toBe(6);
2106
2107 // should be able to find all of the highlighted links in the original data set
2108 linkHightlights.forEach((lh: LinkHighlight) => {
2109 const foundLink = component.graph.links.find((l: Link) => l.id === Link.linkIdFromShowHighlights(lh.id));
2110 expect(foundLink).toBeDefined();
2111 });
2112 });
Sean Condonf4f54a12018-10-10 23:25:46 +01002113});