blob: 606756b40d6eccbf8313c291083a71c0e903031b [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;
28import org.onosproject.net.region.Region;
Thomas Vachuska8c0b18a2017-04-14 16:27:33 -070029import org.onosproject.ui.model.topo.UiModelEvent.Type;
Simon Huntc0f20c12016-05-09 09:30:20 -070030import org.onosproject.ui.model.topo.UiClusterMember;
Simon Hunt58a0dd02016-05-17 11:54:23 -070031import org.onosproject.ui.model.topo.UiDevice;
Simon Huntc13082f2016-08-03 21:20:23 -070032import org.onosproject.ui.model.topo.UiDeviceLink;
Simon Hunt642bc452016-05-04 19:34:45 -070033import org.onosproject.ui.model.topo.UiElement;
Simon Hunteae81ee2016-05-19 12:33:22 -070034import org.onosproject.ui.model.topo.UiHost;
Simon Hunt58a0dd02016-05-17 11:54:23 -070035import org.onosproject.ui.model.topo.UiLinkId;
36import org.onosproject.ui.model.topo.UiRegion;
37
38import java.util.Collection;
39import java.util.Iterator;
Simon Hunt338a3b42016-04-14 09:43:52 -070040
41import static org.junit.Assert.assertEquals;
Simon Hunt642bc452016-05-04 19:34:45 -070042import static org.junit.Assert.assertNotNull;
Simon Hunteae81ee2016-05-19 12:33:22 -070043import static org.junit.Assert.assertNull;
Simon Huntc0f20c12016-05-09 09:30:20 -070044import static org.junit.Assert.assertTrue;
Simon Hunt642bc452016-05-04 19:34:45 -070045import static org.onosproject.cluster.NodeId.nodeId;
Simon Hunteae81ee2016-05-19 12:33:22 -070046import static org.onosproject.net.PortNumber.portNumber;
Simon Hunt58a0dd02016-05-17 11:54:23 -070047import static org.onosproject.ui.model.topo.UiLinkId.uiLinkId;
Simon Hunt338a3b42016-04-14 09:43:52 -070048
49/**
50 * Unit tests for {@link ModelCache}.
51 */
Simon Hunt642bc452016-05-04 19:34:45 -070052public class ModelCacheTest extends AbstractTopoModelTest {
Simon Hunt338a3b42016-04-14 09:43:52 -070053
Simon Hunt642bc452016-05-04 19:34:45 -070054 private class TestEvDisp implements EventDispatcher {
55
56 private Event<Type, UiElement> lastEvent = null;
57 private int eventCount = 0;
58
59 @Override
60 public void post(Event event) {
61 lastEvent = event;
62 eventCount++;
63// print("Event dispatched: %s", event);
64 }
65
66 private void assertEventCount(int exp) {
67 assertEquals("unex event count", exp, eventCount);
68 }
69
70 private void assertLast(Type expEventType, String expId) {
71 assertNotNull("no last event", lastEvent);
72 assertEquals("unex event type", expEventType, lastEvent.type());
73 assertEquals("unex element ID", expId, lastEvent.subject().idAsString());
74 }
75 }
76
Simon Hunt642bc452016-05-04 19:34:45 -070077
78 private final TestEvDisp dispatcher = new TestEvDisp();
Simon Hunt338a3b42016-04-14 09:43:52 -070079
80 private ModelCache cache;
81
Simon Hunt58a0dd02016-05-17 11:54:23 -070082 private void assertContains(String msg, Collection<?> coll, Object... things) {
83 for (Object o : things) {
84 assertTrue(msg, coll.contains(o));
85 }
86 }
87
Simon Hunt642bc452016-05-04 19:34:45 -070088 @Before
89 public void setUp() {
90 cache = new ModelCache(MOCK_SERVICES, dispatcher);
91 }
92
Simon Hunt338a3b42016-04-14 09:43:52 -070093 @Test
94 public void basic() {
Simon Hunt642bc452016-05-04 19:34:45 -070095 title("basic");
Simon Hunt338a3b42016-04-14 09:43:52 -070096 print(cache);
97 assertEquals("unex # members", 0, cache.clusterMemberCount());
98 assertEquals("unex # regions", 0, cache.regionCount());
99 }
100
Simon Hunt642bc452016-05-04 19:34:45 -0700101 @Test
102 public void addAndRemoveClusterMember() {
103 title("addAndRemoveClusterMember");
104 print(cache);
105 assertEquals("unex # members", 0, cache.clusterMemberCount());
106 dispatcher.assertEventCount(0);
107
Simon Huntc0f20c12016-05-09 09:30:20 -0700108 cache.addOrUpdateClusterMember(CNODE_1);
Simon Hunt642bc452016-05-04 19:34:45 -0700109 print(cache);
110 assertEquals("unex # members", 1, cache.clusterMemberCount());
111 dispatcher.assertEventCount(1);
112 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
113
Simon Huntc0f20c12016-05-09 09:30:20 -0700114 cache.removeClusterMember(CNODE_1);
Simon Hunt642bc452016-05-04 19:34:45 -0700115 print(cache);
116 assertEquals("unex # members", 0, cache.clusterMemberCount());
117 dispatcher.assertEventCount(2);
118 dispatcher.assertLast(Type.CLUSTER_MEMBER_REMOVED, C1);
119 }
120
121 @Test
Simon Hunt58a0dd02016-05-17 11:54:23 -0700122 public void nonExistentClusterMember() {
123 title("nonExistentClusterMember");
124 cache.addOrUpdateClusterMember(CNODE_1);
125 print(cache);
126 assertEquals("unex # members", 1, cache.clusterMemberCount());
127 dispatcher.assertEventCount(1);
128 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
129
130 cache.removeClusterMember(CNODE_2);
131 assertEquals("unex # members", 1, cache.clusterMemberCount());
132 dispatcher.assertEventCount(1);
133 }
134
135 @Test
Simon Hunt642bc452016-05-04 19:34:45 -0700136 public void createThreeNodeCluster() {
137 title("createThreeNodeCluster");
Simon Huntc0f20c12016-05-09 09:30:20 -0700138 cache.addOrUpdateClusterMember(CNODE_1);
Simon Hunt642bc452016-05-04 19:34:45 -0700139 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
Simon Huntc0f20c12016-05-09 09:30:20 -0700140 cache.addOrUpdateClusterMember(CNODE_2);
Simon Hunt642bc452016-05-04 19:34:45 -0700141 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C2);
Simon Huntc0f20c12016-05-09 09:30:20 -0700142 cache.addOrUpdateClusterMember(CNODE_3);
Simon Hunt642bc452016-05-04 19:34:45 -0700143 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C3);
144 dispatcher.assertEventCount(3);
145 print(cache);
146 }
147
Simon Huntc0f20c12016-05-09 09:30:20 -0700148 @Test
149 public void addNodeThenExamineIt() {
150 title("addNodeThenExamineIt");
151 cache.addOrUpdateClusterMember(CNODE_1);
152 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
153
154 UiClusterMember member = cache.accessClusterMember(nodeId(C1));
155 print(member);
156 // see AbstractUiImplTest Mock Environment for expected values...
157 assertEquals("wrong id str", C1, member.idAsString());
158 assertEquals("wrong id", nodeId(C1), member.id());
Simon Huntc0f20c12016-05-09 09:30:20 -0700159 assertEquals("not online", true, member.isOnline());
160 assertEquals("not ready", true, member.isReady());
Simon Huntc0f20c12016-05-09 09:30:20 -0700161 }
162
163
164 @Test
165 public void addNodeAndDevices() {
166 title("addNodeAndDevices");
167 cache.addOrUpdateClusterMember(CNODE_1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700168 dispatcher.assertLast(Type.CLUSTER_MEMBER_ADDED_OR_UPDATED, C1);
Simon Huntc0f20c12016-05-09 09:30:20 -0700169 cache.addOrUpdateDevice(DEV_1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700170 dispatcher.assertLast(Type.DEVICE_ADDED_OR_UPDATED, D1);
Simon Huntc0f20c12016-05-09 09:30:20 -0700171 cache.addOrUpdateDevice(DEV_2);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700172 dispatcher.assertLast(Type.DEVICE_ADDED_OR_UPDATED, D2);
Simon Huntc0f20c12016-05-09 09:30:20 -0700173 cache.addOrUpdateDevice(DEV_3);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700174 dispatcher.assertLast(Type.DEVICE_ADDED_OR_UPDATED, D3);
175 dispatcher.assertEventCount(4);
Simon Huntc0f20c12016-05-09 09:30:20 -0700176 print(cache);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700177
178 assertEquals("unex # nodes", 1, cache.clusterMemberCount());
179 assertEquals("unex # devices", 3, cache.deviceCount());
180 cache.removeDevice(DEV_4);
181 assertEquals("unex # devices", 3, cache.deviceCount());
182 dispatcher.assertEventCount(4);
183
184 cache.removeDevice(DEV_2);
185 dispatcher.assertLast(Type.DEVICE_REMOVED, D2);
186 dispatcher.assertEventCount(5);
187
188 // check out details of device
189 UiDevice dev = cache.accessDevice(DEVID_1);
190 assertEquals("wrong id", D1, dev.idAsString());
191 assertEquals("wrong region", R1, dev.regionId().toString());
192 Device d = dev.backingDevice();
193 assertEquals("wrong serial", SERIAL, d.serialNumber());
Simon Huntc0f20c12016-05-09 09:30:20 -0700194 }
195
196 @Test
197 public void addRegions() {
198 title("addRegions");
199 cache.addOrUpdateRegion(REGION_1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700200 dispatcher.assertLast(Type.REGION_ADDED_OR_UPDATED, R1);
201 dispatcher.assertEventCount(1);
202 assertEquals("unex # regions", 1, cache.regionCount());
203
204 cache.addOrUpdateRegion(REGION_2);
205 dispatcher.assertLast(Type.REGION_ADDED_OR_UPDATED, R2);
206 dispatcher.assertEventCount(2);
207 assertEquals("unex # regions", 2, cache.regionCount());
208
Simon Huntc0f20c12016-05-09 09:30:20 -0700209 print(cache);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700210
211 cache.removeRegion(REGION_3);
212 dispatcher.assertEventCount(2);
213 assertEquals("unex # regions", 2, cache.regionCount());
214
215 cache.removeRegion(REGION_1);
216 dispatcher.assertLast(Type.REGION_REMOVED, R1);
217 dispatcher.assertEventCount(3);
218 assertEquals("unex # regions", 1, cache.regionCount());
219
220 print(cache);
221
222 UiRegion region = cache.accessRegion(REGION_2.id());
223 assertEquals("wrong id", REGION_2.id(), region.id());
224 assertEquals("unex # device IDs", 3, region.deviceIds().size());
225 assertContains("missing ID", region.deviceIds(), DEVID_4, DEVID_5, DEVID_6);
226 Region r = region.backingRegion();
227 print(r);
228 assertEquals("wrong region name", "Region-R2", r.name());
229 }
230
231 private static final String[] LINKS_2_7 = {D2, "27", D7, "72"};
232
233 @Test
234 public void addLinks() {
235 title("addLinks");
236
237 Iterator<Link> iter = makeLinkPair(LINKS_2_7).iterator();
238 Link link1 = iter.next();
239 Link link2 = iter.next();
240 print(link1);
241 print(link2);
242
243 UiLinkId idA2B = uiLinkId(link1);
244 UiLinkId idB2A = uiLinkId(link2);
245 // remember, link IDs are canonicalized
246 assertEquals("not same link ID", idA2B, idB2A);
247
248 // we've established that the ID is the same for both
249 UiLinkId linkId = idA2B;
250
Simon Huntc13082f2016-08-03 21:20:23 -0700251 cache.addOrUpdateDeviceLink(link1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700252 dispatcher.assertLast(Type.LINK_ADDED_OR_UPDATED, linkId.toString());
253 dispatcher.assertEventCount(1);
Simon Huntc13082f2016-08-03 21:20:23 -0700254 assertEquals("unex # links", 1, cache.deviceLinkCount());
Simon Hunt58a0dd02016-05-17 11:54:23 -0700255
Simon Huntc13082f2016-08-03 21:20:23 -0700256 UiDeviceLink link = cache.accessDeviceLink(linkId);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700257 assertEquals("dev A not d2", DEVID_2, link.deviceA());
258 assertEquals("dev B not d7", DEVID_7, link.deviceB());
259 assertEquals("wrong backing link A-B", link1, link.linkAtoB());
260 assertEquals("backing link B-A?", null, link.linkBtoA());
261
Simon Huntc13082f2016-08-03 21:20:23 -0700262 cache.addOrUpdateDeviceLink(link2);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700263 dispatcher.assertLast(Type.LINK_ADDED_OR_UPDATED, linkId.toString());
264 dispatcher.assertEventCount(2);
265 // NOTE: yes! expect 1 UiLink
Simon Huntc13082f2016-08-03 21:20:23 -0700266 assertEquals("unex # links", 1, cache.deviceLinkCount());
Simon Hunt58a0dd02016-05-17 11:54:23 -0700267
Simon Huntc13082f2016-08-03 21:20:23 -0700268 link = cache.accessDeviceLink(linkId);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700269 assertEquals("dev A not d2", DEVID_2, link.deviceA());
270 assertEquals("dev B not d7", DEVID_7, link.deviceB());
271 assertEquals("wrong backing link A-B", link1, link.linkAtoB());
272 assertEquals("wrong backing link B-A", link2, link.linkBtoA());
273
274 // now remove links one at a time
Simon Huntc13082f2016-08-03 21:20:23 -0700275 cache.removeDeviceLink(link1);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700276 // NOTE: yes! ADD_OR_UPDATE, since the link was updated
277 dispatcher.assertLast(Type.LINK_ADDED_OR_UPDATED, linkId.toString());
278 dispatcher.assertEventCount(3);
279 // NOTE: yes! expect 1 UiLink (still)
Simon Huntc13082f2016-08-03 21:20:23 -0700280 assertEquals("unex # links", 1, cache.deviceLinkCount());
Simon Hunt58a0dd02016-05-17 11:54:23 -0700281
Simon Huntc13082f2016-08-03 21:20:23 -0700282 link = cache.accessDeviceLink(linkId);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700283 assertEquals("dev A not d2", DEVID_2, link.deviceA());
284 assertEquals("dev B not d7", DEVID_7, link.deviceB());
285 assertEquals("backing link A-B?", null, link.linkAtoB());
286 assertEquals("wrong backing link B-A", link2, link.linkBtoA());
287
288 // remove final link
Simon Huntc13082f2016-08-03 21:20:23 -0700289 cache.removeDeviceLink(link2);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700290 dispatcher.assertLast(Type.LINK_REMOVED, linkId.toString());
291 dispatcher.assertEventCount(4);
292 // NOTE: finally link should be removed from cache
Simon Huntc13082f2016-08-03 21:20:23 -0700293 assertEquals("unex # links", 0, cache.deviceLinkCount());
Simon Huntc0f20c12016-05-09 09:30:20 -0700294 }
295
Simon Hunteae81ee2016-05-19 12:33:22 -0700296 private void assertHostLinkCounts(int nHosts, int nLinks) {
297 assertEquals("unex # hosts", nHosts, cache.hostCount());
Simon Huntc13082f2016-08-03 21:20:23 -0700298 assertEquals("unex # links", nLinks, cache.edgeLinkCount());
Simon Hunteae81ee2016-05-19 12:33:22 -0700299 }
300
301 private void assertLocation(HostId hid, DeviceId expDev, int expPort) {
302 UiHost h = cache.accessHost(hid);
303 assertEquals("unex device", expDev, h.locationDevice());
304 assertEquals("unex port", portNumber(expPort), h.locationPort());
305 }
306
307 @Test
308 public void addHosts() {
309 title("addHosts");
310
311 assertHostLinkCounts(0, 0);
312 Host hostA = createHost(DEV_1, 101, "a");
313 Host hostB = createHost(DEV_1, 102, "b");
314
315 // add a host
316 cache.addOrUpdateHost(hostA);
317 dispatcher.assertLast(Type.HOST_ADDED_OR_UPDATED, hostA.id().toString());
318 dispatcher.assertEventCount(1);
319 assertHostLinkCounts(1, 1);
320 assertLocation(hostA.id(), DEVID_1, 101);
321
322 // add a second host
323 cache.addOrUpdateHost(hostB);
324 dispatcher.assertLast(Type.HOST_ADDED_OR_UPDATED, hostB.id().toString());
325 dispatcher.assertEventCount(2);
326 assertHostLinkCounts(2, 2);
327 assertLocation(hostB.id(), DEVID_1, 102);
328
329 // update the first host
330 cache.addOrUpdateHost(hostA);
331 dispatcher.assertLast(Type.HOST_ADDED_OR_UPDATED, hostA.id().toString());
332 dispatcher.assertEventCount(3);
333 assertHostLinkCounts(2, 2);
334 assertLocation(hostA.id(), DEVID_1, 101);
335
336 print(cache.dumpString());
337
338 // remove the second host
339 cache.removeHost(hostB);
340 dispatcher.assertLast(Type.HOST_REMOVED, hostB.id().toString());
341 dispatcher.assertEventCount(4);
342 assertHostLinkCounts(1, 1);
343 assertNull("still host B?", cache.accessHost(hostB.id()));
344
345 print(cache.dumpString());
346
347 // first, verify where host A is currently residing
348 assertLocation(hostA.id(), DEVID_1, 101);
349
350 // now let's move hostA to a different port
351 Host movedHost = createHost(DEV_1, 200, "a");
352 print(hostA);
353 print(movedHost);
354
355 cache.moveHost(movedHost, hostA);
356 dispatcher.assertLast(Type.HOST_MOVED, hostA.id().toString());
357 dispatcher.assertEventCount(5);
358 assertHostLinkCounts(1, 1);
359
360 assertLocation(hostA.id(), DEVID_1, 200);
361
362 print(cache.dumpString());
363
364 // finally, let's move the host to a different device and port
365 Host movedAgain = createHost(DEV_8, 800, "a");
366
367 cache.moveHost(movedAgain, movedHost);
368 dispatcher.assertLast(Type.HOST_MOVED, hostA.id().toString());
369 dispatcher.assertEventCount(6);
370 assertHostLinkCounts(1, 1);
371
372 assertLocation(hostA.id(), DEVID_8, 800);
373
374 print(cache.dumpString());
375 }
376
377
Simon Huntc0f20c12016-05-09 09:30:20 -0700378 @Test
379 public void load() {
380 title("load");
381 cache.load();
Simon Hunt58a0dd02016-05-17 11:54:23 -0700382 print(cache.dumpString());
383
384 // See mock service bundle for expected values (AbstractTopoModelTest)
385 assertEquals("unex # cnodes", 3, cache.clusterMemberCount());
386 assertEquals("unex # regions", 3, cache.regionCount());
387 assertEquals("unex # devices", 9, cache.deviceCount());
388 assertEquals("unex # hosts", 18, cache.hostCount());
Simon Huntc13082f2016-08-03 21:20:23 -0700389 assertEquals("unex # device-links", 8, cache.deviceLinkCount());
390 assertEquals("unex # edge-links", 18, cache.edgeLinkCount());
391 assertEquals("unex # synth-links", 0, cache.synthLinkCount());
Simon Huntc0f20c12016-05-09 09:30:20 -0700392 }
Simon Hunt338a3b42016-04-14 09:43:52 -0700393}