blob: 84068bacb829d93b007418920367af458e07286a [file] [log] [blame]
Simon Hunt338a3b42016-04-14 09:43:52 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Simon Hunt338a3b42016-04-14 09:43:52 -07003 *
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 Hunt708a5b32017-08-01 15:06:04 -0700155
156 // TODO make assertions through the cluster service; state no longer
157 // cached in the UiModel...
158// assertEquals("not online", true, member.isOnline());
159// assertEquals("not ready", true, member.isReady());
Simon Huntc0f20c12016-05-09 09:30:20 -0700160 }
161
162
163 @Test
164 public void addNodeAndDevices() {
165 title("addNodeAndDevices");
166 cache.addOrUpdateClusterMember(CNODE_1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700167 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
Simon Huntc0f20c12016-05-09 09:30:20 -0700168 cache.addOrUpdateDevice(DEV_1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700169 dispatcher.assertLast(Type.DEVICE_ADDED_OR_UPDATED, D1);
Simon Huntc0f20c12016-05-09 09:30:20 -0700170 cache.addOrUpdateDevice(DEV_2);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700171 dispatcher.assertLast(Type.DEVICE_ADDED_OR_UPDATED, D2);
Simon Huntc0f20c12016-05-09 09:30:20 -0700172 cache.addOrUpdateDevice(DEV_3);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700173 dispatcher.assertLast(Type.DEVICE_ADDED_OR_UPDATED, D3);
174 dispatcher.assertEventCount(4);
Simon Huntc0f20c12016-05-09 09:30:20 -0700175 print(cache);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700176
177 assertEquals("unex # nodes", 1, cache.clusterMemberCount());
178 assertEquals("unex # devices", 3, cache.deviceCount());
179 cache.removeDevice(DEV_4);
180 assertEquals("unex # devices", 3, cache.deviceCount());
181 dispatcher.assertEventCount(4);
182
183 cache.removeDevice(DEV_2);
184 dispatcher.assertLast(Type.DEVICE_REMOVED, D2);
185 dispatcher.assertEventCount(5);
186
187 // check out details of device
188 UiDevice dev = cache.accessDevice(DEVID_1);
189 assertEquals("wrong id", D1, dev.idAsString());
190 assertEquals("wrong region", R1, dev.regionId().toString());
191 Device d = dev.backingDevice();
192 assertEquals("wrong serial", SERIAL, d.serialNumber());
Simon Huntc0f20c12016-05-09 09:30:20 -0700193 }
194
195 @Test
196 public void addRegions() {
197 title("addRegions");
198 cache.addOrUpdateRegion(REGION_1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700199 dispatcher.assertLast(Type.REGION_ADDED_OR_UPDATED, R1);
200 dispatcher.assertEventCount(1);
201 assertEquals("unex # regions", 1, cache.regionCount());
202
203 cache.addOrUpdateRegion(REGION_2);
204 dispatcher.assertLast(Type.REGION_ADDED_OR_UPDATED, R2);
205 dispatcher.assertEventCount(2);
206 assertEquals("unex # regions", 2, cache.regionCount());
207
Simon Huntc0f20c12016-05-09 09:30:20 -0700208 print(cache);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700209
210 cache.removeRegion(REGION_3);
211 dispatcher.assertEventCount(2);
212 assertEquals("unex # regions", 2, cache.regionCount());
213
214 cache.removeRegion(REGION_1);
215 dispatcher.assertLast(Type.REGION_REMOVED, R1);
216 dispatcher.assertEventCount(3);
217 assertEquals("unex # regions", 1, cache.regionCount());
218
219 print(cache);
220
221 UiRegion region = cache.accessRegion(REGION_2.id());
222 assertEquals("wrong id", REGION_2.id(), region.id());
223 assertEquals("unex # device IDs", 3, region.deviceIds().size());
224 assertContains("missing ID", region.deviceIds(), DEVID_4, DEVID_5, DEVID_6);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700225 }
226
227 private static final String[] LINKS_2_7 = {D2, "27", D7, "72"};
228
229 @Test
230 public void addLinks() {
231 title("addLinks");
232
233 Iterator<Link> iter = makeLinkPair(LINKS_2_7).iterator();
234 Link link1 = iter.next();
235 Link link2 = iter.next();
236 print(link1);
237 print(link2);
238
239 UiLinkId idA2B = uiLinkId(link1);
240 UiLinkId idB2A = uiLinkId(link2);
241 // remember, link IDs are canonicalized
242 assertEquals("not same link ID", idA2B, idB2A);
243
244 // we've established that the ID is the same for both
245 UiLinkId linkId = idA2B;
246
Simon Huntc13082f2016-08-03 21:20:23 -0700247 cache.addOrUpdateDeviceLink(link1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700248 dispatcher.assertLast(Type.LINK_ADDED_OR_UPDATED, linkId.toString());
249 dispatcher.assertEventCount(1);
Simon Huntc13082f2016-08-03 21:20:23 -0700250 assertEquals("unex # links", 1, cache.deviceLinkCount());
Simon Hunt58a0dd02016-05-17 11:54:23 -0700251
Simon Huntc13082f2016-08-03 21:20:23 -0700252 UiDeviceLink link = cache.accessDeviceLink(linkId);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700253 assertEquals("dev A not d2", DEVID_2, link.deviceA());
254 assertEquals("dev B not d7", DEVID_7, link.deviceB());
255 assertEquals("wrong backing link A-B", link1, link.linkAtoB());
256 assertEquals("backing link B-A?", null, link.linkBtoA());
257
Simon Huntc13082f2016-08-03 21:20:23 -0700258 cache.addOrUpdateDeviceLink(link2);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700259 dispatcher.assertLast(Type.LINK_ADDED_OR_UPDATED, linkId.toString());
260 dispatcher.assertEventCount(2);
261 // NOTE: yes! expect 1 UiLink
Simon Huntc13082f2016-08-03 21:20:23 -0700262 assertEquals("unex # links", 1, cache.deviceLinkCount());
Simon Hunt58a0dd02016-05-17 11:54:23 -0700263
Simon Huntc13082f2016-08-03 21:20:23 -0700264 link = cache.accessDeviceLink(linkId);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700265 assertEquals("dev A not d2", DEVID_2, link.deviceA());
266 assertEquals("dev B not d7", DEVID_7, link.deviceB());
267 assertEquals("wrong backing link A-B", link1, link.linkAtoB());
268 assertEquals("wrong backing link B-A", link2, link.linkBtoA());
269
270 // now remove links one at a time
Simon Huntc13082f2016-08-03 21:20:23 -0700271 cache.removeDeviceLink(link1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700272 // NOTE: yes! ADD_OR_UPDATE, since the link was updated
273 dispatcher.assertLast(Type.LINK_ADDED_OR_UPDATED, linkId.toString());
274 dispatcher.assertEventCount(3);
275 // NOTE: yes! expect 1 UiLink (still)
Simon Huntc13082f2016-08-03 21:20:23 -0700276 assertEquals("unex # links", 1, cache.deviceLinkCount());
Simon Hunt58a0dd02016-05-17 11:54:23 -0700277
Simon Huntc13082f2016-08-03 21:20:23 -0700278 link = cache.accessDeviceLink(linkId);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700279 assertEquals("dev A not d2", DEVID_2, link.deviceA());
280 assertEquals("dev B not d7", DEVID_7, link.deviceB());
281 assertEquals("backing link A-B?", null, link.linkAtoB());
282 assertEquals("wrong backing link B-A", link2, link.linkBtoA());
283
284 // remove final link
Simon Huntc13082f2016-08-03 21:20:23 -0700285 cache.removeDeviceLink(link2);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700286 dispatcher.assertLast(Type.LINK_REMOVED, linkId.toString());
287 dispatcher.assertEventCount(4);
288 // NOTE: finally link should be removed from cache
Simon Huntc13082f2016-08-03 21:20:23 -0700289 assertEquals("unex # links", 0, cache.deviceLinkCount());
Simon Huntc0f20c12016-05-09 09:30:20 -0700290 }
291
Simon Hunteae81ee2016-05-19 12:33:22 -0700292 private void assertHostLinkCounts(int nHosts, int nLinks) {
293 assertEquals("unex # hosts", nHosts, cache.hostCount());
Simon Huntc13082f2016-08-03 21:20:23 -0700294 assertEquals("unex # links", nLinks, cache.edgeLinkCount());
Simon Hunteae81ee2016-05-19 12:33:22 -0700295 }
296
297 private void assertLocation(HostId hid, DeviceId expDev, int expPort) {
298 UiHost h = cache.accessHost(hid);
299 assertEquals("unex device", expDev, h.locationDevice());
300 assertEquals("unex port", portNumber(expPort), h.locationPort());
301 }
302
303 @Test
304 public void addHosts() {
305 title("addHosts");
306
307 assertHostLinkCounts(0, 0);
308 Host hostA = createHost(DEV_1, 101, "a");
309 Host hostB = createHost(DEV_1, 102, "b");
310
311 // add a host
312 cache.addOrUpdateHost(hostA);
313 dispatcher.assertLast(Type.HOST_ADDED_OR_UPDATED, hostA.id().toString());
314 dispatcher.assertEventCount(1);
315 assertHostLinkCounts(1, 1);
316 assertLocation(hostA.id(), DEVID_1, 101);
317
318 // add a second host
319 cache.addOrUpdateHost(hostB);
320 dispatcher.assertLast(Type.HOST_ADDED_OR_UPDATED, hostB.id().toString());
321 dispatcher.assertEventCount(2);
322 assertHostLinkCounts(2, 2);
323 assertLocation(hostB.id(), DEVID_1, 102);
324
325 // update the first host
326 cache.addOrUpdateHost(hostA);
327 dispatcher.assertLast(Type.HOST_ADDED_OR_UPDATED, hostA.id().toString());
328 dispatcher.assertEventCount(3);
329 assertHostLinkCounts(2, 2);
330 assertLocation(hostA.id(), DEVID_1, 101);
331
332 print(cache.dumpString());
333
334 // remove the second host
335 cache.removeHost(hostB);
336 dispatcher.assertLast(Type.HOST_REMOVED, hostB.id().toString());
337 dispatcher.assertEventCount(4);
338 assertHostLinkCounts(1, 1);
339 assertNull("still host B?", cache.accessHost(hostB.id()));
340
341 print(cache.dumpString());
342
343 // first, verify where host A is currently residing
344 assertLocation(hostA.id(), DEVID_1, 101);
345
346 // now let's move hostA to a different port
347 Host movedHost = createHost(DEV_1, 200, "a");
348 print(hostA);
349 print(movedHost);
350
351 cache.moveHost(movedHost, hostA);
352 dispatcher.assertLast(Type.HOST_MOVED, hostA.id().toString());
353 dispatcher.assertEventCount(5);
354 assertHostLinkCounts(1, 1);
355
356 assertLocation(hostA.id(), DEVID_1, 200);
357
358 print(cache.dumpString());
359
360 // finally, let's move the host to a different device and port
361 Host movedAgain = createHost(DEV_8, 800, "a");
362
363 cache.moveHost(movedAgain, movedHost);
364 dispatcher.assertLast(Type.HOST_MOVED, hostA.id().toString());
365 dispatcher.assertEventCount(6);
366 assertHostLinkCounts(1, 1);
367
368 assertLocation(hostA.id(), DEVID_8, 800);
369
370 print(cache.dumpString());
371 }
372
373
Simon Huntc0f20c12016-05-09 09:30:20 -0700374 @Test
375 public void load() {
376 title("load");
377 cache.load();
Simon Hunt58a0dd02016-05-17 11:54:23 -0700378 print(cache.dumpString());
379
380 // See mock service bundle for expected values (AbstractTopoModelTest)
381 assertEquals("unex # cnodes", 3, cache.clusterMemberCount());
382 assertEquals("unex # regions", 3, cache.regionCount());
383 assertEquals("unex # devices", 9, cache.deviceCount());
384 assertEquals("unex # hosts", 18, cache.hostCount());
Simon Huntc13082f2016-08-03 21:20:23 -0700385 assertEquals("unex # device-links", 8, cache.deviceLinkCount());
386 assertEquals("unex # edge-links", 18, cache.edgeLinkCount());
387 assertEquals("unex # synth-links", 0, cache.synthLinkCount());
Simon Huntc0f20c12016-05-09 09:30:20 -0700388 }
Simon Hunt338a3b42016-04-14 09:43:52 -0700389}