blob: 18e8a26be636c9b08c1802824465b433b8cc14be [file] [log] [blame]
samanwita pale7c08de2015-09-24 21:59:49 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
samanwita pale7c08de2015-09-24 21:59:49 -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 */
16package org.onosproject.store.host.impl;
17
Harshada Chaundkarc9712222019-07-02 15:13:24 +000018import com.google.common.collect.ImmutableSet;
samanwita pale7c08de2015-09-24 21:59:49 -070019import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
Charles Chan2a9492da2019-12-06 19:19:30 -080022import org.onlab.packet.EthType;
samanwita pale7c08de2015-09-24 21:59:49 -070023import org.onlab.packet.IpAddress;
24import org.onlab.packet.MacAddress;
Charles Chan2a9492da2019-12-06 19:19:30 -080025import org.onlab.packet.VlanId;
Harshada Chaundkarc9712222019-07-02 15:13:24 +000026import org.onosproject.net.ConnectPoint;
27import org.onosproject.net.DefaultHost;
28import org.onosproject.net.DeviceId;
samanwita pale7c08de2015-09-24 21:59:49 -070029import org.onosproject.net.Host;
30import org.onosproject.net.HostId;
31import org.onosproject.net.HostLocation;
Harshada Chaundkarc9712222019-07-02 15:13:24 +000032import org.onosproject.net.PortNumber;
samanwita pale7c08de2015-09-24 21:59:49 -070033import org.onosproject.net.host.DefaultHostDescription;
34import org.onosproject.net.host.HostDescription;
Charles Chan2a9492da2019-12-06 19:19:30 -080035import org.onosproject.net.host.HostEvent;
36import org.onosproject.net.host.HostStoreDelegate;
samanwita pale7c08de2015-09-24 21:59:49 -070037import org.onosproject.net.provider.ProviderId;
Harshada Chaundkarc9712222019-07-02 15:13:24 +000038import org.onosproject.store.service.MapEvent;
samanwita pale7c08de2015-09-24 21:59:49 -070039import org.onosproject.store.service.TestStorageService;
40
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +053041import com.google.common.collect.Sets;
Harshada Chaundkarc9712222019-07-02 15:13:24 +000042import org.onosproject.store.service.Versioned;
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +053043
Harshada Chaundkarc9712222019-07-02 15:13:24 +000044import java.util.Collections;
samanwita pale7c08de2015-09-24 21:59:49 -070045import java.util.HashSet;
46import java.util.Set;
47
Sho SHIMIZU53bcc242016-08-15 11:19:24 -070048import static junit.framework.TestCase.assertTrue;
Harshada Chaundkarc9712222019-07-02 15:13:24 +000049import static org.junit.Assert.*;
Sho SHIMIZU53bcc242016-08-15 11:19:24 -070050
samanwita pale7c08de2015-09-24 21:59:49 -070051/**
52 * Tests for the ECHostStore.
53 */
Sho SHIMIZU53bcc242016-08-15 11:19:24 -070054public class DistributedHostStoreTest {
samanwita pale7c08de2015-09-24 21:59:49 -070055
alshabib8a4a6002015-11-25 14:31:16 -080056 private DistributedHostStore ecXHostStore;
Charles Chan2a9492da2019-12-06 19:19:30 -080057 private TestStoreDelegate delegate;
samanwita pale7c08de2015-09-24 21:59:49 -070058
59 private static final HostId HOSTID = HostId.hostId(MacAddress.valueOf("1a:1a:1a:1a:1a:1a"));
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +053060 private static final HostId HOSTID1 = HostId.hostId(MacAddress.valueOf("1a:1a:1a:1a:1a:1b"));
samanwita pale7c08de2015-09-24 21:59:49 -070061
62 private static final IpAddress IP1 = IpAddress.valueOf("10.2.0.2");
63 private static final IpAddress IP2 = IpAddress.valueOf("10.2.0.3");
64
65 private static final ProviderId PID = new ProviderId("of", "foo");
Charles Chanb1e99242017-07-07 14:11:09 -070066 private static final ProviderId PID2 = new ProviderId("of", "foo2");
67
68 private static final HostDescription HOST_LEARNT =
Harshada Chaundkarc9712222019-07-02 15:13:24 +000069 createHostDesc(HOSTID, Sets.newHashSet(IP1), false, Collections.emptySet());
Charles Chanb1e99242017-07-07 14:11:09 -070070 private static final HostDescription HOST_CONFIGURED =
Harshada Chaundkarc9712222019-07-02 15:13:24 +000071 createHostDesc(HOSTID, Sets.newHashSet(IP1), true, Collections.emptySet());
72 // Host with locations
73 private static final DeviceId DEV1 = DeviceId.deviceId("of:0000000000000001");
74 private static final PortNumber P1 = PortNumber.portNumber(1);
75 private static final PortNumber P2 = PortNumber.portNumber(2);
76 private static final ConnectPoint CP11 = new ConnectPoint(DEV1, P1);
77 private static final HostLocation HOST_LOC11 = new HostLocation(CP11, 0);
78 private static final ConnectPoint CP12 = new ConnectPoint(DEV1, P2);
79 private static final HostLocation HOST_LOC12 = new HostLocation(CP12, 0);
80 private static final Set<HostLocation> HOST_LOCATIONS = ImmutableSet.of(HOST_LOC11, HOST_LOC12);
81 private static final Set<HostLocation> HOST_LOCATION = ImmutableSet.of(HOST_LOC11);
82 private static final Set<HostLocation> NONE_LOCATION = ImmutableSet.of(HostLocation.NONE);
83 private static final Set<IpAddress> HOST_ADDRESS = ImmutableSet.of(IP1);
84 private static final Set<IpAddress> HOST_ADDRESSES = ImmutableSet.of(IP1, IP2);
85 private static final HostDescription HOST_LEARNT_WITH_LOCATIONS =
86 createHostDesc(HOSTID, HOST_ADDRESS, false, HOST_LOCATIONS);
87 private static final HostDescription HOST_LEARNT_WITH_ADDRESSES =
88 createHostDesc(HOSTID, Sets.newHashSet(IP1, IP2), false, Collections.emptySet());
89 private static final DefaultHost OLD_HOST = new DefaultHost(PID, HOSTID,
90 HOST_LEARNT_WITH_ADDRESSES.hwAddress(),
91 HOST_LEARNT_WITH_ADDRESSES.vlan(),
92 HOST_LEARNT_WITH_ADDRESSES.locations(),
93 HOST_LEARNT_WITH_ADDRESSES.ipAddress(),
94 HOST_LEARNT_WITH_ADDRESSES.configured(),
95 HOST_LEARNT_WITH_ADDRESSES.annotations());
96 private static final DefaultHost NEW_HOST = new DefaultHost(PID, HOSTID,
97 HOST_LEARNT_WITH_ADDRESSES.hwAddress(),
98 HOST_LEARNT_WITH_ADDRESSES.vlan(),
99 HOST_LEARNT_WITH_ADDRESSES.locations(),
100 HOST_ADDRESS,
101 HOST_LEARNT_WITH_ADDRESSES.configured(),
102 HOST_LEARNT_WITH_ADDRESSES.annotations());
103 private static final MapEvent<HostId, DefaultHost> HOST_EVENT =
104 new MapEvent<>("foobar", HOSTID, new Versioned<>(NEW_HOST, 0), new Versioned<>(OLD_HOST, 0));
Charles Chan2a9492da2019-12-06 19:19:30 -0800105 private static final DefaultHost HOST1 = new DefaultHost(PID, HOSTID, HOSTID.mac(), HOSTID.vlanId(),
106 Set.<HostLocation>of(HOST_LOC11), null,
107 Set.<IpAddress>of(), VlanId.NONE,
108 EthType.EtherType.UNKNOWN.ethType(), false, false);
109 private static final DefaultHost HOST2 = new DefaultHost(PID, HOSTID, HOSTID.mac(), HOSTID.vlanId(),
110 Set.<HostLocation>of(HOST_LOC11), null,
111 Set.<IpAddress>of(IP1), VlanId.NONE,
112 EthType.EtherType.UNKNOWN.ethType(), false, false);
113 private static final DefaultHost HOST3 = new DefaultHost(PID, HOSTID, HOSTID.mac(), HOSTID.vlanId(),
114 Set.<HostLocation>of(HOST_LOC11, HOST_LOC12), null,
115 Set.<IpAddress>of(IP1), VlanId.NONE,
116 EthType.EtherType.UNKNOWN.ethType(), false, false);
117 private static final DefaultHost HOST4 = new DefaultHost(PID, HOSTID, HOSTID.mac(), HOSTID.vlanId(),
118 Set.<HostLocation>of(HOST_LOC11), Set.<HostLocation>of(HOST_LOC12),
119 Set.<IpAddress>of(IP1), VlanId.NONE,
120 EthType.EtherType.UNKNOWN.ethType(), false, false);
samanwita pale7c08de2015-09-24 21:59:49 -0700121
122 @Before
123 public void setUp() {
alshabib8a4a6002015-11-25 14:31:16 -0800124 ecXHostStore = new DistributedHostStore();
samanwita pale7c08de2015-09-24 21:59:49 -0700125
Charles Chan2a9492da2019-12-06 19:19:30 -0800126 delegate = new TestStoreDelegate();
127 ecXHostStore.setDelegate(delegate);
128
samanwita pale7c08de2015-09-24 21:59:49 -0700129 ecXHostStore.storageService = new TestStorageService();
samanwita pale7c08de2015-09-24 21:59:49 -0700130 ecXHostStore.activate();
131 }
132
133 @After
134 public void tearDown() {
135 ecXHostStore.deactivate();
136 }
137
138 /**
139 * Tests the removeIp method call.
140 */
141 @Test
142 public void testRemoveIp() {
143 Set<IpAddress> ips = new HashSet<>();
144 ips.add(IP1);
145 ips.add(IP2);
146
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530147 HostDescription description = createHostDesc(HOSTID, ips);
samanwita pale7c08de2015-09-24 21:59:49 -0700148 ecXHostStore.createOrUpdateHost(PID, HOSTID, description, false);
149 ecXHostStore.removeIp(HOSTID, IP1);
150 Host host = ecXHostStore.getHost(HOSTID);
151
152 assertFalse(host.ipAddresses().contains(IP1));
153 assertTrue(host.ipAddresses().contains(IP2));
154 }
155
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530156 @Test
157 public void testAddHostByIp() {
158 Set<IpAddress> ips = new HashSet<>();
159 ips.add(IP1);
160 ips.add(IP2);
161
162 HostDescription description = createHostDesc(HOSTID, ips);
163 ecXHostStore.createOrUpdateHost(PID, HOSTID, description, false);
164
165 Set<Host> hosts = ecXHostStore.getHosts(IP1);
166
167 assertFalse(hosts.size() > 1);
168 assertTrue(hosts.size() == 1);
169
170 HostDescription description1 = createHostDesc(HOSTID1, Sets.newHashSet(IP2));
171 ecXHostStore.createOrUpdateHost(PID, HOSTID1, description1, false);
172
173 Set<Host> hosts1 = ecXHostStore.getHosts(IP2);
174
175 assertFalse(hosts1.size() < 1);
176 assertTrue(hosts1.size() == 2);
177 }
178
179 @Test
180 public void testRemoveHostByIp() {
181 Set<IpAddress> ips = new HashSet<>();
182 ips.add(IP1);
183 ips.add(IP2);
184
185 HostDescription description = createHostDesc(HOSTID, ips);
186 ecXHostStore.createOrUpdateHost(PID, HOSTID, description, false);
187 ecXHostStore.removeIp(HOSTID, IP1);
188 Set<Host> hosts = ecXHostStore.getHosts(IP1);
189 assertTrue(hosts.size() == 0);
190 }
191
Charles Chanb1e99242017-07-07 14:11:09 -0700192 @Test
193 public void testHostOverride() {
194 Host hostInStore;
195 ecXHostStore.createOrUpdateHost(PID, HOSTID, HOST_LEARNT, false);
196 hostInStore = ecXHostStore.getHost(HOSTID);
197 assertFalse(hostInStore.configured());
198 assertEquals(PID, hostInStore.providerId());
199
200 // Expect: configured host should override learnt host
201 ecXHostStore.createOrUpdateHost(PID2, HOSTID, HOST_CONFIGURED, true);
202 hostInStore = ecXHostStore.getHost(HOSTID);
203 assertTrue(hostInStore.configured());
204 assertEquals(PID2, hostInStore.providerId());
205
206 // Expect: learnt host should not override configured host
207 ecXHostStore.createOrUpdateHost(PID, HOSTID, HOST_LEARNT, false);
208 hostInStore = ecXHostStore.getHost(HOSTID);
209 assertTrue(hostInStore.configured());
210 assertEquals(PID2, hostInStore.providerId());
211 }
212
Harshada Chaundkarc9712222019-07-02 15:13:24 +0000213 @Test
214 public void testRemoteUpdateHostsByIp() {
215 // Add host in the store
216 ecXHostStore.createOrUpdateHost(PID, HOSTID, HOST_LEARNT_WITH_ADDRESSES, false);
217
218 // Expected a learnt host with an IP
219 Host hostInHostsByIp = ecXHostStore.getHosts(IP1).stream()
220 .findFirst().orElse(null);
221 assertNotNull(hostInHostsByIp);
222 assertFalse(hostInHostsByIp.configured());
223 assertEquals(HOSTID, hostInHostsByIp.id());
224 assertEquals(PID, hostInHostsByIp.providerId());
225 assertEquals(NONE_LOCATION, hostInHostsByIp.locations());
226 assertEquals(HOST_ADDRESSES, hostInHostsByIp.ipAddresses());
227
228 // Remove one ip - simulating the update in other instances
229 ecXHostStore.hostLocationTracker.event(HOST_EVENT);
230
231 // Expected null
232 hostInHostsByIp = ecXHostStore.getHosts(IP2).stream()
233 .findFirst().orElse(null);
234 assertNull(hostInHostsByIp);
235
236 // Expected an host with an ip address
237 hostInHostsByIp = ecXHostStore.getHosts(IP1).stream()
238 .findFirst().orElse(null);
239 assertNotNull(hostInHostsByIp);
240 assertFalse(hostInHostsByIp.configured());
241 assertEquals(HOSTID, hostInHostsByIp.id());
242 assertEquals(PID, hostInHostsByIp.providerId());
243 assertEquals(NONE_LOCATION, hostInHostsByIp.locations());
244 assertEquals(HOST_ADDRESS, hostInHostsByIp.ipAddresses());
245
246 }
247
248 @Test
249 public void testLocalUpdateHostsByIp() {
250 // Add host in the store
251 ecXHostStore.createOrUpdateHost(PID, HOSTID, HOST_LEARNT_WITH_ADDRESSES, false);
252
253 // Expected a learnt host with an IP
254 Host hostInHostsByIp = ecXHostStore.getHosts(IP1).stream()
255 .findFirst().orElse(null);
256 assertNotNull(hostInHostsByIp);
257 assertFalse(hostInHostsByIp.configured());
258 assertEquals(HOSTID, hostInHostsByIp.id());
259 assertEquals(PID, hostInHostsByIp.providerId());
260 assertEquals(NONE_LOCATION, hostInHostsByIp.locations());
261 assertEquals(HOST_ADDRESSES, hostInHostsByIp.ipAddresses());
262
263 // Remove one ip
264 ecXHostStore.removeIp(HOSTID, IP2);
265
266 // Expected null
267 hostInHostsByIp = ecXHostStore.getHosts(IP2).stream()
268 .findFirst().orElse(null);
269 assertNull(hostInHostsByIp);
270
271 // Expected an host with an ip address
272 hostInHostsByIp = ecXHostStore.getHosts(IP1).stream()
273 .findFirst().orElse(null);
274 assertNotNull(hostInHostsByIp);
275 assertFalse(hostInHostsByIp.configured());
276 assertEquals(HOSTID, hostInHostsByIp.id());
277 assertEquals(PID, hostInHostsByIp.providerId());
278 assertEquals(NONE_LOCATION, hostInHostsByIp.locations());
279 assertEquals(HOST_ADDRESS, hostInHostsByIp.ipAddresses());
280
281 }
282
283 @Test
284 public void testUpdateLocationInHostsByIp() {
285 // Add host in the store
286 ecXHostStore.createOrUpdateHost(PID, HOSTID, HOST_LEARNT_WITH_LOCATIONS, false);
287 Host hostInHosts = ecXHostStore.getHost(HOSTID);
288
289 // Expected a learnt host with an IP
290 assertFalse(hostInHosts.configured());
291 assertEquals(HOSTID, hostInHosts.id());
292 assertEquals(PID, hostInHosts.providerId());
293 assertEquals(HOST_LOCATIONS, hostInHosts.locations());
294 assertEquals(HOST_ADDRESS, hostInHosts.ipAddresses());
295 Host hostInHostsByIp = ecXHostStore.getHosts(IP1).stream()
296 .findFirst().orElse(null);
297 assertNotNull(hostInHostsByIp);
298 assertFalse(hostInHostsByIp.configured());
299 assertEquals(HOSTID, hostInHostsByIp.id());
300 assertEquals(PID, hostInHostsByIp.providerId());
301 assertEquals(HOST_LOCATIONS, hostInHostsByIp.locations());
302 assertEquals(HOST_ADDRESS, hostInHostsByIp.ipAddresses());
303
304 // Remove one location
305 ecXHostStore.removeLocation(HOSTID, HOST_LOC12);
306
307 // Verify hosts is updated
308 hostInHosts = ecXHostStore.getHost(HOSTID);
309 assertFalse(hostInHosts.configured());
310 assertEquals(HOSTID, hostInHosts.id());
311 assertEquals(PID, hostInHosts.providerId());
312 assertEquals(HOST_LOCATION, hostInHosts.locations());
313 assertEquals(HOST_ADDRESS, hostInHosts.ipAddresses());
314
315 // Verify hostsByIp is updated
316 hostInHostsByIp = ecXHostStore.getHosts(IP1).stream()
317 .findFirst().orElse(null);
318 assertNotNull(hostInHostsByIp);
319 assertFalse(hostInHostsByIp.configured());
320 assertEquals(HOSTID, hostInHostsByIp.id());
321 assertEquals(PID, hostInHostsByIp.providerId());
322 assertEquals(HOST_LOCATION, hostInHostsByIp.locations());
323 assertEquals(HOST_ADDRESS, hostInHostsByIp.ipAddresses());
324 }
325
Charles Chan2a9492da2019-12-06 19:19:30 -0800326 @Test
327 public void testHostAdded() {
328 // Host is first discovered at only one location
329 MapEvent<HostId, DefaultHost> event = new MapEvent<>("event", HOSTID,
330 new Versioned<>(HOST1, 0), null);
331 // Expect: HOST_ADDED
332 ecXHostStore.hostLocationTracker.event(event);
333 assertEquals(HostEvent.Type.HOST_ADDED, delegate.lastEvent.type());
334 assertEquals(HOST1, delegate.lastEvent.subject());
335 assertNull(delegate.lastEvent.prevSubject());
336 }
337
338 @Test
339 public void testHostUpdated() {
340 // Host is updated with an IP
341 MapEvent<HostId, DefaultHost> event = new MapEvent<>("event", HOSTID,
342 new Versioned<>(HOST2, 1), new Versioned<>(HOST1, 0));
343 // Expect: HOST_UPDATED
344 ecXHostStore.hostLocationTracker.event(event);
345 assertEquals(HostEvent.Type.HOST_UPDATED, delegate.lastEvent.type());
346 assertEquals(HOST2, delegate.lastEvent.subject());
347 assertEquals(HOST1, delegate.lastEvent.prevSubject());
348 }
349
350 @Test
351 public void testHostMoved() {
352 // Host is updated with a second location
353 MapEvent<HostId, DefaultHost> event = new MapEvent<>("event", HOSTID,
354 new Versioned<>(HOST3, 1), new Versioned<>(HOST2, 0));
355 // Expect: HOST_MOVED
356 ecXHostStore.hostLocationTracker.event(event);
357 assertEquals(HostEvent.Type.HOST_MOVED, delegate.lastEvent.type());
358 assertEquals(HOST3, delegate.lastEvent.subject());
359 assertEquals(HOST2, delegate.lastEvent.prevSubject());
360 }
361
362 @Test
363 public void testHostAuxMoved() {
364 // Host aux location changed
365 MapEvent<HostId, DefaultHost> event = new MapEvent<>("event", HOSTID,
366 new Versioned<>(HOST4, 1), new Versioned<>(HOST1, 0));
367 // Expect: HOST_AUX_MOVED
368 ecXHostStore.hostLocationTracker.event(event);
369 assertEquals(HostEvent.Type.HOST_AUX_MOVED, delegate.lastEvent.type());
370 assertEquals(HOST4, delegate.lastEvent.subject());
371 assertEquals(HOST1, delegate.lastEvent.prevSubject());
372 }
373
374 @Test
375 public void testHostRemoved() {
376 // Host is removed
377 MapEvent<HostId, DefaultHost> event = new MapEvent<>("event", HOSTID,
378 null, new Versioned<>(HOST3, 0));
379 // Expect: HOST_REMOVED
380 ecXHostStore.hostLocationTracker.event(event);
381 assertEquals(HostEvent.Type.HOST_REMOVED, delegate.lastEvent.type());
382 assertEquals(HOST3, delegate.lastEvent.subject());
383 assertNull(delegate.lastEvent.prevSubject());
384 }
385
386 private class TestStoreDelegate implements HostStoreDelegate {
387 public HostEvent lastEvent;
388
389 @Override
390 public void notify(HostEvent event) {
391 lastEvent = event;
392 }
393 }
Harshada Chaundkarc9712222019-07-02 15:13:24 +0000394
Charles Chanb1e99242017-07-07 14:11:09 -0700395 private static HostDescription createHostDesc(HostId hostId, Set<IpAddress> ips) {
Harshada Chaundkarc9712222019-07-02 15:13:24 +0000396 return createHostDesc(hostId, ips, false, Collections.emptySet());
Charles Chanb1e99242017-07-07 14:11:09 -0700397 }
398
399 private static HostDescription createHostDesc(HostId hostId, Set<IpAddress> ips,
Harshada Chaundkarc9712222019-07-02 15:13:24 +0000400 boolean configured, Set<HostLocation> locations) {
401 return locations.isEmpty() ?
402 new DefaultHostDescription(hostId.mac(), hostId.vlanId(), HostLocation.NONE, ips, configured) :
403 new DefaultHostDescription(hostId.mac(), hostId.vlanId(), locations, ips, configured);
404
Deepa Vaddireddy0a71c8b2017-01-19 21:20:45 +0530405 }
Harshada Chaundkarc9712222019-07-02 15:13:24 +0000406
Sho SHIMIZU53bcc242016-08-15 11:19:24 -0700407}