blob: 9fad51cdfb21c1887b949e6b67701a7b6a38c450 [file] [log] [blame]
Simon Hunt642bc452016-05-04 19:34:45 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
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 */
16
17package org.onosproject.ui.impl.topo.model;
18
Simon Huntc0f20c12016-05-09 09:30:20 -070019import com.google.common.collect.ImmutableList;
Simon Hunt642bc452016-05-04 19:34:45 -070020import com.google.common.collect.ImmutableSet;
Simon Huntc0f20c12016-05-09 09:30:20 -070021import org.onlab.packet.IpAddress;
22import org.onlab.packet.MacAddress;
23import org.onlab.packet.VlanId;
Simon Hunt642bc452016-05-04 19:34:45 -070024import org.onosproject.cluster.ClusterService;
25import org.onosproject.cluster.ClusterServiceAdapter;
26import org.onosproject.cluster.ControllerNode;
Simon Huntc0f20c12016-05-09 09:30:20 -070027import org.onosproject.cluster.DefaultControllerNode;
Simon Hunt642bc452016-05-04 19:34:45 -070028import org.onosproject.cluster.NodeId;
Simon Huntc0f20c12016-05-09 09:30:20 -070029import org.onosproject.cluster.RoleInfo;
Simon Hunt642bc452016-05-04 19:34:45 -070030import org.onosproject.mastership.MastershipService;
31import org.onosproject.mastership.MastershipServiceAdapter;
Simon Huntc0f20c12016-05-09 09:30:20 -070032import org.onosproject.net.ConnectPoint;
33import org.onosproject.net.DefaultDevice;
34import org.onosproject.net.DefaultHost;
35import org.onosproject.net.DefaultLink;
36import org.onosproject.net.Device;
Simon Hunt642bc452016-05-04 19:34:45 -070037import org.onosproject.net.DeviceId;
Simon Huntc0f20c12016-05-09 09:30:20 -070038import org.onosproject.net.Host;
39import org.onosproject.net.HostId;
40import org.onosproject.net.HostLocation;
41import org.onosproject.net.Link;
42import org.onosproject.net.PortNumber;
Simon Hunt642bc452016-05-04 19:34:45 -070043import org.onosproject.net.device.DeviceService;
Simon Huntc0f20c12016-05-09 09:30:20 -070044import org.onosproject.net.device.DeviceServiceAdapter;
Simon Hunt642bc452016-05-04 19:34:45 -070045import org.onosproject.net.flow.FlowRuleService;
46import org.onosproject.net.host.HostService;
Simon Huntc0f20c12016-05-09 09:30:20 -070047import org.onosproject.net.host.HostServiceAdapter;
Simon Hunt642bc452016-05-04 19:34:45 -070048import org.onosproject.net.intent.IntentService;
49import org.onosproject.net.link.LinkService;
Simon Huntc0f20c12016-05-09 09:30:20 -070050import org.onosproject.net.link.LinkServiceAdapter;
51import org.onosproject.net.provider.ProviderId;
52import org.onosproject.net.region.DefaultRegion;
53import org.onosproject.net.region.Region;
54import org.onosproject.net.region.RegionId;
55import org.onosproject.net.region.RegionListener;
Simon Hunt642bc452016-05-04 19:34:45 -070056import org.onosproject.net.region.RegionService;
57import org.onosproject.ui.impl.AbstractUiImplTest;
58import org.onosproject.ui.model.ServiceBundle;
59
Simon Huntc0f20c12016-05-09 09:30:20 -070060import java.util.ArrayList;
61import java.util.Collections;
Simon Hunt642bc452016-05-04 19:34:45 -070062import java.util.HashMap;
Simon Huntc0f20c12016-05-09 09:30:20 -070063import java.util.HashSet;
64import java.util.List;
Simon Hunt642bc452016-05-04 19:34:45 -070065import java.util.Map;
66import java.util.Set;
67
Simon Huntc0f20c12016-05-09 09:30:20 -070068import static org.onosproject.cluster.NodeId.nodeId;
Simon Hunt642bc452016-05-04 19:34:45 -070069import static org.onosproject.net.DeviceId.deviceId;
Simon Huntc0f20c12016-05-09 09:30:20 -070070import static org.onosproject.net.HostId.hostId;
71import static org.onosproject.net.PortNumber.portNumber;
Simon Hunt642bc452016-05-04 19:34:45 -070072
73/**
74 * Base class for model test classes.
75 */
76abstract class AbstractTopoModelTest extends AbstractUiImplTest {
77
Simon Huntc0f20c12016-05-09 09:30:20 -070078 /*
79 Our mock environment:
80
81 Three controllers: C1, C2, C3
82
83 Nine devices: D1 .. D9
84
85 D4 ---+ +--- D7
86 | |
87 D5 --- D1 --- D2 --- D3 --- D8
88 | |
89 D6 ---+ +--- D9
90
91 Twelve hosts (two per D4 ... D9) H4a, H4b, H5a, H5b, ...
92
93 Regions:
94 R1 : D1, D2, D3
95 R2 : D4, D5, D6
96 R3 : D7, D8, D9
97
98 Mastership:
99 C1 : D1, D2, D3
100 C2 : D4, D5, D6
101 C3 : D7, D8, D9
102
103 Roles: (backups)
104 C1 -> C2, C3
105 C2 -> C1, C3
106 C3 -> C1, C2
107 */
108
109 protected static final String C1 = "C1";
110 protected static final String C2 = "C2";
111 protected static final String C3 = "C3";
112
113 protected static final NodeId CNID_1 = nodeId(C1);
114 protected static final NodeId CNID_2 = nodeId(C2);
115 protected static final NodeId CNID_3 = nodeId(C3);
116
117 protected static final ControllerNode CNODE_1 = cnode(CNID_1, "10.0.0.1");
118 protected static final ControllerNode CNODE_2 = cnode(CNID_2, "10.0.0.2");
119 protected static final ControllerNode CNODE_3 = cnode(CNID_3, "10.0.0.3");
120
121 protected static final String R1 = "R1";
122 protected static final String R2 = "R2";
123 protected static final String R3 = "R3";
124
125 protected static final Set<NodeId> SET_C1 = ImmutableSet.of(CNID_1);
126 protected static final Set<NodeId> SET_C2 = ImmutableSet.of(CNID_2);
127 protected static final Set<NodeId> SET_C3 = ImmutableSet.of(CNID_3);
128
129 protected static final Region REGION_1 =
130 region(R1, Region.Type.METRO, ImmutableList.of(SET_C1, SET_C2));
131 protected static final Region REGION_2 =
132 region(R2, Region.Type.CAMPUS, ImmutableList.of(SET_C2, SET_C1));
133 protected static final Region REGION_3 =
134 region(R3, Region.Type.CAMPUS, ImmutableList.of(SET_C3, SET_C1));
135
136 protected static final Set<Region> REGION_SET =
137 ImmutableSet.of(REGION_1, REGION_2, REGION_3);
138
Simon Hunt58a0dd02016-05-17 11:54:23 -0700139 protected static final String D1 = "d1";
140 protected static final String D2 = "d2";
141 protected static final String D3 = "d3";
142 protected static final String D4 = "d4";
143 protected static final String D5 = "d5";
144 protected static final String D6 = "d6";
145 protected static final String D7 = "d7";
146 protected static final String D8 = "d8";
147 protected static final String D9 = "d9";
Simon Huntc0f20c12016-05-09 09:30:20 -0700148
149 protected static final String MFR = "Mfr";
150 protected static final String HW = "h/w";
151 protected static final String SW = "s/w";
152 protected static final String SERIAL = "ser123";
153
154 protected static final DeviceId DEVID_1 = deviceId(D1);
155 protected static final DeviceId DEVID_2 = deviceId(D2);
156 protected static final DeviceId DEVID_3 = deviceId(D3);
157 protected static final DeviceId DEVID_4 = deviceId(D4);
158 protected static final DeviceId DEVID_5 = deviceId(D5);
159 protected static final DeviceId DEVID_6 = deviceId(D6);
160 protected static final DeviceId DEVID_7 = deviceId(D7);
161 protected static final DeviceId DEVID_8 = deviceId(D8);
162 protected static final DeviceId DEVID_9 = deviceId(D9);
163
164 protected static final Device DEV_1 = device(D1);
165 protected static final Device DEV_2 = device(D2);
166 protected static final Device DEV_3 = device(D3);
167 protected static final Device DEV_4 = device(D4);
168 protected static final Device DEV_5 = device(D5);
169 protected static final Device DEV_6 = device(D6);
170 protected static final Device DEV_7 = device(D7);
171 protected static final Device DEV_8 = device(D8);
172 protected static final Device DEV_9 = device(D9);
173
174 protected static final List<Device> ALL_DEVS =
175 ImmutableList.of(
176 DEV_1, DEV_2, DEV_3,
177 DEV_4, DEV_5, DEV_6,
178 DEV_7, DEV_8, DEV_9
179 );
180
181 private static final Set<DeviceId> DEVS_TRUNK =
182 ImmutableSet.of(DEVID_1, DEVID_2, DEVID_3);
183
184 private static final Set<DeviceId> DEVS_LEFT =
185 ImmutableSet.of(DEVID_4, DEVID_5, DEVID_6);
186
187 private static final Set<DeviceId> DEVS_RIGHT =
188 ImmutableSet.of(DEVID_7, DEVID_8, DEVID_9);
189
190 private static final String[][] LINK_CONNECT_DATA = {
191 {D1, "12", D2, "21"},
192 {D2, "23", D3, "32"},
193 {D4, "41", D1, "14"},
194 {D5, "51", D1, "15"},
195 {D6, "61", D1, "16"},
196 {D7, "73", D3, "37"},
197 {D8, "83", D3, "38"},
198 {D9, "93", D3, "39"},
199 };
200
201 private static final String HOST_MAC_PREFIX = "aa:00:00:00:00:";
202
203 /**
204 * Returns IP address instance for given string.
205 *
206 * @param s string
207 * @return IP address
208 */
209 protected static IpAddress ip(String s) {
210 return IpAddress.valueOf(s);
211 }
212
213 /**
214 * Returns controller node instance for given ID and IP.
215 *
216 * @param id identifier
217 * @param ip IP address
218 * @return controller node instance
219 */
220 protected static ControllerNode cnode(NodeId id, String ip) {
221 return new DefaultControllerNode(id, ip(ip));
222 }
223
224 /**
225 * Returns a region instance with specified parameters.
226 *
227 * @param id region id
228 * @param type region type
229 * @param masters ordered list of master sets
230 * @return region instance
231 */
232 protected static Region region(String id, Region.Type type,
233 List<Set<NodeId>> masters) {
234 return new DefaultRegion(RegionId.regionId(id), "Region-" + id,
235 type, masters);
236 }
237
238 /**
239 * Returns device with given ID.
240 *
241 * @param id device ID
242 * @return device instance
243 */
244 protected static Device device(String id) {
245 return new DefaultDevice(ProviderId.NONE, deviceId(id),
246 Device.Type.SWITCH, MFR, HW, SW, SERIAL, null);
247 }
248
Simon Hunt642bc452016-05-04 19:34:45 -0700249 /**
250 * Returns canned results.
Simon Huntc0f20c12016-05-09 09:30:20 -0700251 * <p>
Simon Hunt642bc452016-05-04 19:34:45 -0700252 * At some future point, we may make this "programmable", so that
Simon Huntc0f20c12016-05-09 09:30:20 -0700253 * its state can be changed over the course of a unit test.
Simon Hunt642bc452016-05-04 19:34:45 -0700254 */
255 protected static final ServiceBundle MOCK_SERVICES =
256 new ServiceBundle() {
257 @Override
258 public ClusterService cluster() {
259 return MOCK_CLUSTER;
260 }
261
262 @Override
263 public MastershipService mastership() {
264 return MOCK_MASTER;
265 }
266
267 @Override
268 public RegionService region() {
Simon Huntc0f20c12016-05-09 09:30:20 -0700269 return MOCK_REGION;
Simon Hunt642bc452016-05-04 19:34:45 -0700270 }
271
272 @Override
273 public DeviceService device() {
Simon Huntc0f20c12016-05-09 09:30:20 -0700274 return MOCK_DEVICE;
Simon Hunt642bc452016-05-04 19:34:45 -0700275 }
276
277 @Override
278 public LinkService link() {
Simon Huntc0f20c12016-05-09 09:30:20 -0700279 return MOCK_LINK;
Simon Hunt642bc452016-05-04 19:34:45 -0700280 }
281
282 @Override
283 public HostService host() {
Simon Huntc0f20c12016-05-09 09:30:20 -0700284 return MOCK_HOST;
Simon Hunt642bc452016-05-04 19:34:45 -0700285 }
286
287 @Override
288 public IntentService intent() {
289 return null;
290 }
291
292 @Override
293 public FlowRuleService flow() {
294 return null;
295 }
296 };
297
298 private static final ClusterService MOCK_CLUSTER = new MockClusterService();
299 private static final MastershipService MOCK_MASTER = new MockMasterService();
Simon Huntc0f20c12016-05-09 09:30:20 -0700300 private static final RegionService MOCK_REGION = new MockRegionService();
301 private static final DeviceService MOCK_DEVICE = new MockDeviceService();
302 private static final LinkService MOCK_LINK = new MockLinkService();
303 private static final HostService MOCK_HOST = new MockHostService();
Simon Hunt642bc452016-05-04 19:34:45 -0700304
Simon Hunt642bc452016-05-04 19:34:45 -0700305
Simon Hunt642bc452016-05-04 19:34:45 -0700306 private static class MockClusterService extends ClusterServiceAdapter {
Simon Huntc0f20c12016-05-09 09:30:20 -0700307 private final Map<NodeId, ControllerNode> nodes = new HashMap<>();
Simon Hunt642bc452016-05-04 19:34:45 -0700308 private final Map<NodeId, ControllerNode.State> states = new HashMap<>();
309
Simon Huntc0f20c12016-05-09 09:30:20 -0700310 MockClusterService() {
311 nodes.put(CNODE_1.id(), CNODE_1);
312 nodes.put(CNODE_2.id(), CNODE_2);
313 nodes.put(CNODE_3.id(), CNODE_3);
314
315 states.put(CNODE_1.id(), ControllerNode.State.READY);
316 states.put(CNODE_2.id(), ControllerNode.State.ACTIVE);
317 states.put(CNODE_3.id(), ControllerNode.State.ACTIVE);
318 }
319
320 @Override
321 public Set<ControllerNode> getNodes() {
322 return ImmutableSet.copyOf(nodes.values());
323 }
324
325 @Override
326 public ControllerNode getNode(NodeId nodeId) {
327 return nodes.get(nodeId);
328 }
Simon Hunt642bc452016-05-04 19:34:45 -0700329
330 @Override
331 public ControllerNode.State getState(NodeId nodeId) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700332 return states.get(nodeId);
Simon Hunt642bc452016-05-04 19:34:45 -0700333 }
334 }
335
Simon Hunt642bc452016-05-04 19:34:45 -0700336
337 private static class MockMasterService extends MastershipServiceAdapter {
Simon Huntc0f20c12016-05-09 09:30:20 -0700338 private final Map<NodeId, Set<DeviceId>> masterOf = new HashMap<>();
339
340 MockMasterService() {
341 masterOf.put(CNODE_1.id(), DEVS_TRUNK);
342 masterOf.put(CNODE_2.id(), DEVS_LEFT);
343 masterOf.put(CNODE_3.id(), DEVS_RIGHT);
344 }
345
346 @Override
347 public NodeId getMasterFor(DeviceId deviceId) {
348 if (DEVS_TRUNK.contains(deviceId)) {
349 return CNID_1;
350 }
351 if (DEVS_LEFT.contains(deviceId)) {
352 return CNID_2;
353 }
354 if (DEVS_RIGHT.contains(deviceId)) {
355 return CNID_3;
356 }
357 return null;
358 }
359
Simon Hunt642bc452016-05-04 19:34:45 -0700360 @Override
361 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700362 return masterOf.get(nodeId);
Simon Hunt642bc452016-05-04 19:34:45 -0700363 }
Simon Huntc0f20c12016-05-09 09:30:20 -0700364
365 @Override
366 public RoleInfo getNodesFor(DeviceId deviceId) {
367 NodeId master = null;
368 List<NodeId> backups = new ArrayList<>();
369
370 if (DEVS_TRUNK.contains(deviceId)) {
371 master = CNID_1;
372 backups.add(CNID_2);
373 backups.add(CNID_3);
374 } else if (DEVS_LEFT.contains(deviceId)) {
375 master = CNID_2;
376 backups.add(CNID_1);
377 backups.add(CNID_3);
378 } else if (DEVS_RIGHT.contains(deviceId)) {
379 master = CNID_3;
380 backups.add(CNID_1);
381 backups.add(CNID_2);
382 }
383 return new RoleInfo(master, backups);
384 }
385 }
386
387 // TODO: consider implementing RegionServiceAdapter and extending that here
388 private static class MockRegionService implements RegionService {
389
390 private final Map<RegionId, Region> lookup = new HashMap<>();
391
392 MockRegionService() {
393 lookup.put(REGION_1.id(), REGION_1);
394 lookup.put(REGION_2.id(), REGION_2);
395 lookup.put(REGION_3.id(), REGION_3);
396 }
397
398 @Override
399 public Set<Region> getRegions() {
400 return REGION_SET;
401 }
402
403 @Override
404 public Region getRegion(RegionId regionId) {
405 return lookup.get(regionId);
406 }
407
408 @Override
409 public Region getRegionForDevice(DeviceId deviceId) {
410 if (DEVS_TRUNK.contains(deviceId)) {
411 return REGION_1;
412 }
413 if (DEVS_LEFT.contains(deviceId)) {
414 return REGION_2;
415 }
416 if (DEVS_RIGHT.contains(deviceId)) {
417 return REGION_3;
418 }
419 return null;
420 }
421
422 @Override
423 public Set<DeviceId> getRegionDevices(RegionId regionId) {
424 if (REGION_1.id().equals(regionId)) {
425 return DEVS_TRUNK;
426 }
427 if (REGION_2.id().equals(regionId)) {
428 return DEVS_LEFT;
429 }
430 if (REGION_3.id().equals(regionId)) {
431 return DEVS_RIGHT;
432 }
433 return Collections.emptySet();
434 }
435
436 @Override
437 public void addListener(RegionListener listener) {
438 }
439
440 @Override
441 public void removeListener(RegionListener listener) {
442 }
443 }
444
445
446 private static class MockDeviceService extends DeviceServiceAdapter {
447 private final Map<DeviceId, Device> devices = new HashMap<>();
448
449 MockDeviceService() {
450 for (Device dev : ALL_DEVS) {
451 devices.put(dev.id(), dev);
452 }
453 }
454
455 @Override
456 public int getDeviceCount() {
457 return devices.size();
458 }
459
460 @Override
461 public Iterable<Device> getDevices() {
462 return ImmutableList.copyOf(devices.values());
463 }
464
465 @Override
466 public Device getDevice(DeviceId deviceId) {
467 return devices.get(deviceId);
468 }
469
470 }
471
Simon Hunt58a0dd02016-05-17 11:54:23 -0700472 /**
473 * Synthesizes a pair of unidirectional links between two devices. The
474 * string array should be of the form:
475 * <pre>
476 * { "device-A-id", "device-A-port", "device-B-id", "device-B-port" }
477 * </pre>
478 *
479 * @param linkPairData device ids and ports
480 * @return pair of synthesized links
481 */
482 protected static List<Link> makeLinkPair(String[] linkPairData) {
483 DeviceId devA = deviceId(linkPairData[0]);
484 PortNumber portA = portNumber(Long.valueOf(linkPairData[1]));
485 DeviceId devB = deviceId(linkPairData[2]);
486 PortNumber portB = portNumber(Long.valueOf(linkPairData[3]));
487
488 Link linkA = DefaultLink.builder()
489 .providerId(ProviderId.NONE)
490 .type(Link.Type.DIRECT)
491 .src(new ConnectPoint(devA, portA))
492 .dst(new ConnectPoint(devB, portB))
493 .build();
494
495 Link linkB = DefaultLink.builder()
496 .providerId(ProviderId.NONE)
497 .type(Link.Type.DIRECT)
498 .src(new ConnectPoint(devB, portB))
499 .dst(new ConnectPoint(devA, portA))
500 .build();
501
502 return ImmutableList.of(linkA, linkB);
503 }
Simon Huntc0f20c12016-05-09 09:30:20 -0700504
505 private static class MockLinkService extends LinkServiceAdapter {
506 private final Set<Link> links = new HashSet<>();
507
508 MockLinkService() {
509 for (String[] linkPair : LINK_CONNECT_DATA) {
Simon Hunt58a0dd02016-05-17 11:54:23 -0700510 links.addAll(makeLinkPair(linkPair));
Simon Huntc0f20c12016-05-09 09:30:20 -0700511 }
Simon Huntc0f20c12016-05-09 09:30:20 -0700512 }
513
514 @Override
515 public int getLinkCount() {
516 return links.size();
517 }
518
519 @Override
520 public Iterable<Link> getLinks() {
521 return ImmutableSet.copyOf(links);
522 }
523
524 // TODO: possibly fill out other methods if we find the model uses them
525 }
526
527
528 private static class MockHostService extends HostServiceAdapter {
529 private final Map<HostId, Host> hosts = new HashMap<>();
530
531 MockHostService() {
532 for (Device d : ALL_DEVS) {
533 // two hosts per device
534 createHosts(hosts, d);
535 }
536 }
537
538 private void createHosts(Map<HostId, Host> hosts, Device d) {
539 DeviceId deviceId = d.id();
540 String devNum = deviceId.toString().substring(1);
541
542 String ha = devNum + "a";
543 String hb = devNum + "b";
544
545 MacAddress macA = MacAddress.valueOf(HOST_MAC_PREFIX + ha);
546 MacAddress macB = MacAddress.valueOf(HOST_MAC_PREFIX + hb);
547
548 HostId hostA = hostId(String.format("%s/-1", macA));
549 HostId hostB = hostId(String.format("%s/-1", macB));
550
551 PortNumber portA = portNumber(101);
552 PortNumber portB = portNumber(102);
553
554 HostLocation locA = new HostLocation(deviceId, portA, 0);
555 HostLocation locB = new HostLocation(deviceId, portB, 0);
556
557 IpAddress ipA = ip("10." + devNum + ".0.1");
558 IpAddress ipB = ip("10." + devNum + ".0.2");
559
560 Host host = new DefaultHost(ProviderId.NONE,
561 hostA, macA, VlanId.NONE, locA,
562 ImmutableSet.of(ipA));
563 hosts.put(hostA, host);
564
565 host = new DefaultHost(ProviderId.NONE,
566 hostB, macB, VlanId.NONE, locB,
567 ImmutableSet.of(ipB));
568 hosts.put(hostB, host);
569 }
570
571 @Override
572 public int getHostCount() {
573 return hosts.size();
574 }
575
576 @Override
577 public Iterable<Host> getHosts() {
578 return ImmutableSet.copyOf(hosts.values());
579 }
580
581 @Override
582 public Host getHost(HostId hostId) {
583 return hosts.get(hostId);
584 }
585
586 // TODO: possibly fill out other methods, should the model require them
Simon Hunt642bc452016-05-04 19:34:45 -0700587 }
588
589}