blob: 8d7ada6a30de8f9251885477ae64f8c247dfa8e3 [file] [log] [blame]
Simon Hunt338a3b42016-04-14 09:43:52 -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 Hunt642bc452016-05-04 19:34:45 -070019import org.junit.Before;
Simon Hunt338a3b42016-04-14 09:43:52 -070020import org.junit.Test;
Simon Hunt642bc452016-05-04 19:34:45 -070021import org.onosproject.event.Event;
Simon Hunt338a3b42016-04-14 09:43:52 -070022import org.onosproject.event.EventDispatcher;
Simon Hunt58a0dd02016-05-17 11:54:23 -070023import org.onosproject.net.Device;
Simon Huntc0f20c12016-05-09 09:30:20 -070024import org.onosproject.net.DeviceId;
Simon Hunteae81ee2016-05-19 12:33:22 -070025import org.onosproject.net.Host;
26import org.onosproject.net.HostId;
Simon Hunt58a0dd02016-05-17 11:54:23 -070027import org.onosproject.net.Link;
Simon Huntc0f20c12016-05-09 09:30:20 -070028import org.onosproject.ui.model.topo.UiClusterMember;
Simon Hunt58a0dd02016-05-17 11:54:23 -070029import org.onosproject.ui.model.topo.UiDevice;
Simon Huntc13082f2016-08-03 21:20:23 -070030import org.onosproject.ui.model.topo.UiDeviceLink;
Simon Hunt642bc452016-05-04 19:34:45 -070031import org.onosproject.ui.model.topo.UiElement;
Simon Hunteae81ee2016-05-19 12:33:22 -070032import org.onosproject.ui.model.topo.UiHost;
Simon Hunt58a0dd02016-05-17 11:54:23 -070033import org.onosproject.ui.model.topo.UiLinkId;
Simon Hunt8f60ff82017-04-24 17:19:30 -070034import org.onosproject.ui.model.topo.UiModelEvent.Type;
Simon Hunt58a0dd02016-05-17 11:54:23 -070035import org.onosproject.ui.model.topo.UiRegion;
36
37import java.util.Collection;
38import java.util.Iterator;
Simon Hunt338a3b42016-04-14 09:43:52 -070039
Simon Hunt8f60ff82017-04-24 17:19:30 -070040import static org.junit.Assert.*;
Simon Hunt642bc452016-05-04 19:34:45 -070041import static org.onosproject.cluster.NodeId.nodeId;
Simon Hunteae81ee2016-05-19 12:33:22 -070042import static org.onosproject.net.PortNumber.portNumber;
Simon Hunt58a0dd02016-05-17 11:54:23 -070043import static org.onosproject.ui.model.topo.UiLinkId.uiLinkId;
Simon Hunt338a3b42016-04-14 09:43:52 -070044
45/**
46 * Unit tests for {@link ModelCache}.
47 */
Simon Hunt642bc452016-05-04 19:34:45 -070048public class ModelCacheTest extends AbstractTopoModelTest {
Simon Hunt338a3b42016-04-14 09:43:52 -070049
Simon Hunt642bc452016-05-04 19:34:45 -070050 private class TestEvDisp implements EventDispatcher {
51
52 private Event<Type, UiElement> lastEvent = null;
53 private int eventCount = 0;
54
55 @Override
56 public void post(Event event) {
57 lastEvent = event;
58 eventCount++;
59// print("Event dispatched: %s", event);
60 }
61
62 private void assertEventCount(int exp) {
63 assertEquals("unex event count", exp, eventCount);
64 }
65
66 private void assertLast(Type expEventType, String expId) {
67 assertNotNull("no last event", lastEvent);
68 assertEquals("unex event type", expEventType, lastEvent.type());
69 assertEquals("unex element ID", expId, lastEvent.subject().idAsString());
70 }
71 }
72
Simon Hunt642bc452016-05-04 19:34:45 -070073
74 private final TestEvDisp dispatcher = new TestEvDisp();
Simon Hunt338a3b42016-04-14 09:43:52 -070075
76 private ModelCache cache;
77
Simon Hunt58a0dd02016-05-17 11:54:23 -070078 private void assertContains(String msg, Collection<?> coll, Object... things) {
79 for (Object o : things) {
80 assertTrue(msg, coll.contains(o));
81 }
82 }
83
Simon Hunt642bc452016-05-04 19:34:45 -070084 @Before
85 public void setUp() {
86 cache = new ModelCache(MOCK_SERVICES, dispatcher);
87 }
88
Simon Hunt338a3b42016-04-14 09:43:52 -070089 @Test
90 public void basic() {
Simon Hunt642bc452016-05-04 19:34:45 -070091 title("basic");
Simon Hunt338a3b42016-04-14 09:43:52 -070092 print(cache);
93 assertEquals("unex # members", 0, cache.clusterMemberCount());
94 assertEquals("unex # regions", 0, cache.regionCount());
95 }
96
Simon Hunt642bc452016-05-04 19:34:45 -070097 @Test
98 public void addAndRemoveClusterMember() {
99 title("addAndRemoveClusterMember");
100 print(cache);
101 assertEquals("unex # members", 0, cache.clusterMemberCount());
102 dispatcher.assertEventCount(0);
103
Simon Huntc0f20c12016-05-09 09:30:20 -0700104 cache.addOrUpdateClusterMember(CNODE_1);
Simon Hunt642bc452016-05-04 19:34:45 -0700105 print(cache);
106 assertEquals("unex # members", 1, cache.clusterMemberCount());
107 dispatcher.assertEventCount(1);
108 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
109
Simon Huntc0f20c12016-05-09 09:30:20 -0700110 cache.removeClusterMember(CNODE_1);
Simon Hunt642bc452016-05-04 19:34:45 -0700111 print(cache);
112 assertEquals("unex # members", 0, cache.clusterMemberCount());
113 dispatcher.assertEventCount(2);
114 dispatcher.assertLast(Type.CLUSTER_MEMBER_REMOVED, C1);
115 }
116
117 @Test
Simon Hunt58a0dd02016-05-17 11:54:23 -0700118 public void nonExistentClusterMember() {
119 title("nonExistentClusterMember");
120 cache.addOrUpdateClusterMember(CNODE_1);
121 print(cache);
122 assertEquals("unex # members", 1, cache.clusterMemberCount());
123 dispatcher.assertEventCount(1);
124 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
125
126 cache.removeClusterMember(CNODE_2);
127 assertEquals("unex # members", 1, cache.clusterMemberCount());
128 dispatcher.assertEventCount(1);
129 }
130
131 @Test
Simon Hunt642bc452016-05-04 19:34:45 -0700132 public void createThreeNodeCluster() {
133 title("createThreeNodeCluster");
Simon Huntc0f20c12016-05-09 09:30:20 -0700134 cache.addOrUpdateClusterMember(CNODE_1);
Simon Hunt642bc452016-05-04 19:34:45 -0700135 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
Simon Huntc0f20c12016-05-09 09:30:20 -0700136 cache.addOrUpdateClusterMember(CNODE_2);
Simon Hunt642bc452016-05-04 19:34:45 -0700137 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C2);
Simon Huntc0f20c12016-05-09 09:30:20 -0700138 cache.addOrUpdateClusterMember(CNODE_3);
Simon Hunt642bc452016-05-04 19:34:45 -0700139 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C3);
140 dispatcher.assertEventCount(3);
141 print(cache);
142 }
143
Simon Huntc0f20c12016-05-09 09:30:20 -0700144 @Test
145 public void addNodeThenExamineIt() {
146 title("addNodeThenExamineIt");
147 cache.addOrUpdateClusterMember(CNODE_1);
148 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
149
150 UiClusterMember member = cache.accessClusterMember(nodeId(C1));
151 print(member);
152 // see AbstractUiImplTest Mock Environment for expected values...
153 assertEquals("wrong id str", C1, member.idAsString());
154 assertEquals("wrong id", nodeId(C1), member.id());
Simon Huntc0f20c12016-05-09 09:30:20 -0700155 assertEquals("not online", true, member.isOnline());
156 assertEquals("not ready", true, member.isReady());
Simon Huntc0f20c12016-05-09 09:30:20 -0700157 }
158
159
160 @Test
161 public void addNodeAndDevices() {
162 title("addNodeAndDevices");
163 cache.addOrUpdateClusterMember(CNODE_1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700164 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
Simon Huntc0f20c12016-05-09 09:30:20 -0700165 cache.addOrUpdateDevice(DEV_1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700166 dispatcher.assertLast(Type.DEVICE_ADDED_OR_UPDATED, D1);
Simon Huntc0f20c12016-05-09 09:30:20 -0700167 cache.addOrUpdateDevice(DEV_2);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700168 dispatcher.assertLast(Type.DEVICE_ADDED_OR_UPDATED, D2);
Simon Huntc0f20c12016-05-09 09:30:20 -0700169 cache.addOrUpdateDevice(DEV_3);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700170 dispatcher.assertLast(Type.DEVICE_ADDED_OR_UPDATED, D3);
171 dispatcher.assertEventCount(4);
Simon Huntc0f20c12016-05-09 09:30:20 -0700172 print(cache);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700173
174 assertEquals("unex # nodes", 1, cache.clusterMemberCount());
175 assertEquals("unex # devices", 3, cache.deviceCount());
176 cache.removeDevice(DEV_4);
177 assertEquals("unex # devices", 3, cache.deviceCount());
178 dispatcher.assertEventCount(4);
179
180 cache.removeDevice(DEV_2);
181 dispatcher.assertLast(Type.DEVICE_REMOVED, D2);
182 dispatcher.assertEventCount(5);
183
184 // check out details of device
185 UiDevice dev = cache.accessDevice(DEVID_1);
186 assertEquals("wrong id", D1, dev.idAsString());
187 assertEquals("wrong region", R1, dev.regionId().toString());
188 Device d = dev.backingDevice();
189 assertEquals("wrong serial", SERIAL, d.serialNumber());
Simon Huntc0f20c12016-05-09 09:30:20 -0700190 }
191
192 @Test
193 public void addRegions() {
194 title("addRegions");
195 cache.addOrUpdateRegion(REGION_1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700196 dispatcher.assertLast(Type.REGION_ADDED_OR_UPDATED, R1);
197 dispatcher.assertEventCount(1);
198 assertEquals("unex # regions", 1, cache.regionCount());
199
200 cache.addOrUpdateRegion(REGION_2);
201 dispatcher.assertLast(Type.REGION_ADDED_OR_UPDATED, R2);
202 dispatcher.assertEventCount(2);
203 assertEquals("unex # regions", 2, cache.regionCount());
204
Simon Huntc0f20c12016-05-09 09:30:20 -0700205 print(cache);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700206
207 cache.removeRegion(REGION_3);
208 dispatcher.assertEventCount(2);
209 assertEquals("unex # regions", 2, cache.regionCount());
210
211 cache.removeRegion(REGION_1);
212 dispatcher.assertLast(Type.REGION_REMOVED, R1);
213 dispatcher.assertEventCount(3);
214 assertEquals("unex # regions", 1, cache.regionCount());
215
216 print(cache);
217
218 UiRegion region = cache.accessRegion(REGION_2.id());
219 assertEquals("wrong id", REGION_2.id(), region.id());
220 assertEquals("unex # device IDs", 3, region.deviceIds().size());
221 assertContains("missing ID", region.deviceIds(), DEVID_4, DEVID_5, DEVID_6);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700222 }
223
224 private static final String[] LINKS_2_7 = {D2, "27", D7, "72"};
225
226 @Test
227 public void addLinks() {
228 title("addLinks");
229
230 Iterator<Link> iter = makeLinkPair(LINKS_2_7).iterator();
231 Link link1 = iter.next();
232 Link link2 = iter.next();
233 print(link1);
234 print(link2);
235
236 UiLinkId idA2B = uiLinkId(link1);
237 UiLinkId idB2A = uiLinkId(link2);
238 // remember, link IDs are canonicalized
239 assertEquals("not same link ID", idA2B, idB2A);
240
241 // we've established that the ID is the same for both
242 UiLinkId linkId = idA2B;
243
Simon Huntc13082f2016-08-03 21:20:23 -0700244 cache.addOrUpdateDeviceLink(link1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700245 dispatcher.assertLast(Type.LINK_ADDED_OR_UPDATED, linkId.toString());
246 dispatcher.assertEventCount(1);
Simon Huntc13082f2016-08-03 21:20:23 -0700247 assertEquals("unex # links", 1, cache.deviceLinkCount());
Simon Hunt58a0dd02016-05-17 11:54:23 -0700248
Simon Huntc13082f2016-08-03 21:20:23 -0700249 UiDeviceLink link = cache.accessDeviceLink(linkId);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700250 assertEquals("dev A not d2", DEVID_2, link.deviceA());
251 assertEquals("dev B not d7", DEVID_7, link.deviceB());
252 assertEquals("wrong backing link A-B", link1, link.linkAtoB());
253 assertEquals("backing link B-A?", null, link.linkBtoA());
254
Simon Huntc13082f2016-08-03 21:20:23 -0700255 cache.addOrUpdateDeviceLink(link2);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700256 dispatcher.assertLast(Type.LINK_ADDED_OR_UPDATED, linkId.toString());
257 dispatcher.assertEventCount(2);
258 // NOTE: yes! expect 1 UiLink
Simon Huntc13082f2016-08-03 21:20:23 -0700259 assertEquals("unex # links", 1, cache.deviceLinkCount());
Simon Hunt58a0dd02016-05-17 11:54:23 -0700260
Simon Huntc13082f2016-08-03 21:20:23 -0700261 link = cache.accessDeviceLink(linkId);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700262 assertEquals("dev A not d2", DEVID_2, link.deviceA());
263 assertEquals("dev B not d7", DEVID_7, link.deviceB());
264 assertEquals("wrong backing link A-B", link1, link.linkAtoB());
265 assertEquals("wrong backing link B-A", link2, link.linkBtoA());
266
267 // now remove links one at a time
Simon Huntc13082f2016-08-03 21:20:23 -0700268 cache.removeDeviceLink(link1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700269 // NOTE: yes! ADD_OR_UPDATE, since the link was updated
270 dispatcher.assertLast(Type.LINK_ADDED_OR_UPDATED, linkId.toString());
271 dispatcher.assertEventCount(3);
272 // NOTE: yes! expect 1 UiLink (still)
Simon Huntc13082f2016-08-03 21:20:23 -0700273 assertEquals("unex # links", 1, cache.deviceLinkCount());
Simon Hunt58a0dd02016-05-17 11:54:23 -0700274
Simon Huntc13082f2016-08-03 21:20:23 -0700275 link = cache.accessDeviceLink(linkId);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700276 assertEquals("dev A not d2", DEVID_2, link.deviceA());
277 assertEquals("dev B not d7", DEVID_7, link.deviceB());
278 assertEquals("backing link A-B?", null, link.linkAtoB());
279 assertEquals("wrong backing link B-A", link2, link.linkBtoA());
280
281 // remove final link
Simon Huntc13082f2016-08-03 21:20:23 -0700282 cache.removeDeviceLink(link2);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700283 dispatcher.assertLast(Type.LINK_REMOVED, linkId.toString());
284 dispatcher.assertEventCount(4);
285 // NOTE: finally link should be removed from cache
Simon Huntc13082f2016-08-03 21:20:23 -0700286 assertEquals("unex # links", 0, cache.deviceLinkCount());
Simon Huntc0f20c12016-05-09 09:30:20 -0700287 }
288
Simon Hunteae81ee2016-05-19 12:33:22 -0700289 private void assertHostLinkCounts(int nHosts, int nLinks) {
290 assertEquals("unex # hosts", nHosts, cache.hostCount());
Simon Huntc13082f2016-08-03 21:20:23 -0700291 assertEquals("unex # links", nLinks, cache.edgeLinkCount());
Simon Hunteae81ee2016-05-19 12:33:22 -0700292 }
293
294 private void assertLocation(HostId hid, DeviceId expDev, int expPort) {
295 UiHost h = cache.accessHost(hid);
296 assertEquals("unex device", expDev, h.locationDevice());
297 assertEquals("unex port", portNumber(expPort), h.locationPort());
298 }
299
300 @Test
301 public void addHosts() {
302 title("addHosts");
303
304 assertHostLinkCounts(0, 0);
305 Host hostA = createHost(DEV_1, 101, "a");
306 Host hostB = createHost(DEV_1, 102, "b");
307
308 // add a host
309 cache.addOrUpdateHost(hostA);
310 dispatcher.assertLast(Type.HOST_ADDED_OR_UPDATED, hostA.id().toString());
311 dispatcher.assertEventCount(1);
312 assertHostLinkCounts(1, 1);
313 assertLocation(hostA.id(), DEVID_1, 101);
314
315 // add a second host
316 cache.addOrUpdateHost(hostB);
317 dispatcher.assertLast(Type.HOST_ADDED_OR_UPDATED, hostB.id().toString());
318 dispatcher.assertEventCount(2);
319 assertHostLinkCounts(2, 2);
320 assertLocation(hostB.id(), DEVID_1, 102);
321
322 // update the first host
323 cache.addOrUpdateHost(hostA);
324 dispatcher.assertLast(Type.HOST_ADDED_OR_UPDATED, hostA.id().toString());
325 dispatcher.assertEventCount(3);
326 assertHostLinkCounts(2, 2);
327 assertLocation(hostA.id(), DEVID_1, 101);
328
329 print(cache.dumpString());
330
331 // remove the second host
332 cache.removeHost(hostB);
333 dispatcher.assertLast(Type.HOST_REMOVED, hostB.id().toString());
334 dispatcher.assertEventCount(4);
335 assertHostLinkCounts(1, 1);
336 assertNull("still host B?", cache.accessHost(hostB.id()));
337
338 print(cache.dumpString());
339
340 // first, verify where host A is currently residing
341 assertLocation(hostA.id(), DEVID_1, 101);
342
343 // now let's move hostA to a different port
344 Host movedHost = createHost(DEV_1, 200, "a");
345 print(hostA);
346 print(movedHost);
347
348 cache.moveHost(movedHost, hostA);
349 dispatcher.assertLast(Type.HOST_MOVED, hostA.id().toString());
350 dispatcher.assertEventCount(5);
351 assertHostLinkCounts(1, 1);
352
353 assertLocation(hostA.id(), DEVID_1, 200);
354
355 print(cache.dumpString());
356
357 // finally, let's move the host to a different device and port
358 Host movedAgain = createHost(DEV_8, 800, "a");
359
360 cache.moveHost(movedAgain, movedHost);
361 dispatcher.assertLast(Type.HOST_MOVED, hostA.id().toString());
362 dispatcher.assertEventCount(6);
363 assertHostLinkCounts(1, 1);
364
365 assertLocation(hostA.id(), DEVID_8, 800);
366
367 print(cache.dumpString());
368 }
369
370
Simon Huntc0f20c12016-05-09 09:30:20 -0700371 @Test
372 public void load() {
373 title("load");
374 cache.load();
Simon Hunt58a0dd02016-05-17 11:54:23 -0700375 print(cache.dumpString());
376
377 // See mock service bundle for expected values (AbstractTopoModelTest)
378 assertEquals("unex # cnodes", 3, cache.clusterMemberCount());
379 assertEquals("unex # regions", 3, cache.regionCount());
380 assertEquals("unex # devices", 9, cache.deviceCount());
381 assertEquals("unex # hosts", 18, cache.hostCount());
Simon Huntc13082f2016-08-03 21:20:23 -0700382 assertEquals("unex # device-links", 8, cache.deviceLinkCount());
383 assertEquals("unex # edge-links", 18, cache.edgeLinkCount());
384 assertEquals("unex # synth-links", 0, cache.synthLinkCount());
Simon Huntc0f20c12016-05-09 09:30:20 -0700385 }
Simon Hunt338a3b42016-04-14 09:43:52 -0700386}