blob: c20da19392204eeafee76fa6c80284eb7d2c0c05 [file] [log] [blame]
tombe988312014-09-19 18:38:47 -07001package org.onlab.onos.net.host.impl;
Ayaka Koshibeac8e7292014-09-16 16:08:31 -07002
3import static org.junit.Assert.assertEquals;
4import static org.junit.Assert.assertFalse;
Ayaka Koshibeac8e7292014-09-16 16:08:31 -07005import static org.junit.Assert.assertNotNull;
Jonathan Hartc884f1b2014-09-24 11:53:33 -07006import static org.junit.Assert.assertNull;
Ayaka Koshibeac8e7292014-09-16 16:08:31 -07007import static org.junit.Assert.assertTrue;
Jonathan Hartc884f1b2014-09-24 11:53:33 -07008import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED;
9import static org.onlab.onos.net.host.HostEvent.Type.HOST_MOVED;
10import static org.onlab.onos.net.host.HostEvent.Type.HOST_REMOVED;
11import static org.onlab.onos.net.host.HostEvent.Type.HOST_UPDATED;
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070012
13import java.util.List;
14import java.util.Set;
15
16import org.junit.After;
17import org.junit.Before;
18import org.junit.Test;
19import org.onlab.onos.event.Event;
20import org.onlab.onos.event.impl.TestEventDispatcher;
Jonathan Hartc884f1b2014-09-24 11:53:33 -070021import org.onlab.onos.net.ConnectPoint;
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070022import org.onlab.onos.net.DeviceId;
23import org.onlab.onos.net.Host;
24import org.onlab.onos.net.HostId;
25import org.onlab.onos.net.HostLocation;
26import org.onlab.onos.net.PortNumber;
27import org.onlab.onos.net.host.DefaultHostDescription;
28import org.onlab.onos.net.host.HostDescription;
29import org.onlab.onos.net.host.HostEvent;
30import org.onlab.onos.net.host.HostListener;
31import org.onlab.onos.net.host.HostProvider;
32import org.onlab.onos.net.host.HostProviderRegistry;
33import org.onlab.onos.net.host.HostProviderService;
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -070034import org.onlab.onos.net.host.InterfaceIpAddress;
Jonathan Hartc884f1b2014-09-24 11:53:33 -070035import org.onlab.onos.net.host.PortAddresses;
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070036import org.onlab.onos.net.provider.AbstractProvider;
37import org.onlab.onos.net.provider.ProviderId;
tomea961ff2014-10-01 12:45:15 -070038import org.onlab.onos.store.trivial.impl.SimpleHostStore;
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -070039import org.onlab.packet.IpAddress;
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -070040import org.onlab.packet.IpPrefix;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070041import org.onlab.packet.MacAddress;
42import org.onlab.packet.VlanId;
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070043
44import com.google.common.collect.Lists;
45import com.google.common.collect.Sets;
46
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070047/**
48 * Test codifying the host service & host provider service contracts.
49 */
tom202175a2014-09-19 19:00:11 -070050public class HostManagerTest {
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070051
tom7e02cda2014-09-18 12:05:46 -070052 private static final ProviderId PID = new ProviderId("of", "foo");
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070053
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070054 private static final VlanId VLAN1 = VlanId.vlanId((short) 1);
55 private static final VlanId VLAN2 = VlanId.vlanId((short) 2);
56 private static final MacAddress MAC1 = MacAddress.valueOf("00:00:11:00:00:01");
57 private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02");
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070058 private static final HostId HID1 = HostId.hostId(MAC1, VLAN1);
59 private static final HostId HID2 = HostId.hostId(MAC2, VLAN1);
60
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -070061 private static final IpPrefix IP1 = IpPrefix.valueOf("10.0.0.1");
62 private static final IpPrefix IP2 = IpPrefix.valueOf("10.0.0.2");
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070063
64 private static final DeviceId DID1 = DeviceId.deviceId("of:001");
65 private static final DeviceId DID2 = DeviceId.deviceId("of:002");
66 private static final PortNumber P1 = PortNumber.portNumber(100);
67 private static final PortNumber P2 = PortNumber.portNumber(200);
68 private static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L);
69 private static final HostLocation LOC2 = new HostLocation(DID1, P2, 123L);
Jonathan Hartc884f1b2014-09-24 11:53:33 -070070 private static final ConnectPoint CP1 = new ConnectPoint(DID1, P1);
71 private static final ConnectPoint CP2 = new ConnectPoint(DID2, P2);
72
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -070073 private static final InterfaceIpAddress IA1 =
74 new InterfaceIpAddress(IpAddress.valueOf("10.1.1.1"),
75 IpPrefix.valueOf("10.1.1.0/24"));
76 private static final InterfaceIpAddress IA2 =
77 new InterfaceIpAddress(IpAddress.valueOf("10.2.2.2"),
78 IpPrefix.valueOf("10.2.0.0/16"));
79 private static final InterfaceIpAddress IA3 =
80 new InterfaceIpAddress(IpAddress.valueOf("10.3.3.3"),
81 IpPrefix.valueOf("10.3.3.0/24"));
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070082
tom202175a2014-09-19 19:00:11 -070083 private HostManager mgr;
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070084
85 protected TestListener listener = new TestListener();
86 protected HostProviderRegistry registry;
87 protected TestHostProvider provider;
88 protected HostProviderService providerService;
89
90 @Before
91 public void setUp() {
tom202175a2014-09-19 19:00:11 -070092 mgr = new HostManager();
tom5bcc9462014-09-19 10:11:31 -070093 mgr.store = new SimpleHostStore();
Ayaka Koshibeac8e7292014-09-16 16:08:31 -070094 mgr.eventDispatcher = new TestEventDispatcher();
95 registry = mgr;
96 mgr.activate();
97
98 mgr.addListener(listener);
99
100 provider = new TestHostProvider();
101 providerService = registry.register(provider);
102 assertTrue("provider should be registered",
tom093340b2014-10-10 00:15:36 -0700103 registry.getProviders().contains(provider.id()));
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700104 }
105
106 @After
107 public void tearDown() {
108 registry.unregister(provider);
109 assertFalse("provider should not be registered",
tom093340b2014-10-10 00:15:36 -0700110 registry.getProviders().contains(provider.id()));
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700111
112 mgr.removeListener(listener);
113 mgr.deactivate();
114 mgr.eventDispatcher = null;
115 }
116
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700117 private void detect(HostId hid, MacAddress mac, VlanId vlan,
tom093340b2014-10-10 00:15:36 -0700118 HostLocation loc, IpPrefix ip) {
119 HostDescription descr = new DefaultHostDescription(mac, vlan, loc, ip);
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700120 providerService.hostDetected(hid, descr);
121 assertNotNull("host should be found", mgr.getHost(hid));
122 }
123
124 private void validateEvents(Enum... types) {
125 int i = 0;
126 assertEquals("wrong events received", types.length, listener.events.size());
127 for (Event event : listener.events) {
128 assertEquals("incorrect event type", types[i], event.type());
129 i++;
130 }
131 listener.events.clear();
132 }
133
134 @Test
135 public void hostDetected() {
136 assertNull("host shouldn't be found", mgr.getHost(HID1));
137
138 // host addition
tom093340b2014-10-10 00:15:36 -0700139 detect(HID1, MAC1, VLAN1, LOC1, IP1);
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700140 assertEquals("exactly one should be found", 1, mgr.getHostCount());
tom093340b2014-10-10 00:15:36 -0700141 detect(HID2, MAC2, VLAN2, LOC2, IP1);
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700142 assertEquals("two hosts should be found", 2, mgr.getHostCount());
143 validateEvents(HOST_ADDED, HOST_ADDED);
144
145 // host motion
tom093340b2014-10-10 00:15:36 -0700146 detect(HID1, MAC1, VLAN1, LOC2, IP1);
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700147 validateEvents(HOST_MOVED);
148 assertEquals("only two hosts should be found", 2, mgr.getHostCount());
149
150 // host update
tom093340b2014-10-10 00:15:36 -0700151 detect(HID1, MAC1, VLAN1, LOC2, IP2);
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700152 validateEvents(HOST_UPDATED);
153 assertEquals("only two hosts should be found", 2, mgr.getHostCount());
154 }
155
156 @Test
157 public void hostVanished() {
tom093340b2014-10-10 00:15:36 -0700158 detect(HID1, MAC1, VLAN1, LOC1, IP1);
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700159 providerService.hostVanished(HID1);
160 validateEvents(HOST_ADDED, HOST_REMOVED);
161
162 assertNull("host should have been removed", mgr.getHost(HID1));
163 }
164
165 private void validateHosts(
tom093340b2014-10-10 00:15:36 -0700166 String msg, Iterable<Host> hosts, HostId... ids) {
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700167 Set<HostId> hids = Sets.newHashSet(ids);
168 for (Host h : hosts) {
169 assertTrue(msg, hids.remove(h.id()));
170 }
171 assertTrue("expected hosts not fetched from store", hids.isEmpty());
172 }
173
174 @Test
175 public void getHosts() {
tom093340b2014-10-10 00:15:36 -0700176 detect(HID1, MAC1, VLAN1, LOC1, IP1);
177 detect(HID2, MAC2, VLAN1, LOC2, IP2);
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700178
179 validateHosts("host not properly stored", mgr.getHosts(), HID1, HID2);
180 validateHosts("can't get hosts by VLAN", mgr.getHostsByVlan(VLAN1), HID1, HID2);
181 validateHosts("can't get hosts by MAC", mgr.getHostsByMac(MAC1), HID1);
182 validateHosts("can't get hosts by IP", mgr.getHostsByIp(IP1), HID1);
183 validateHosts("can't get hosts by location", mgr.getConnectedHosts(LOC1), HID1);
184 assertTrue("incorrect host location", mgr.getConnectedHosts(DID2).isEmpty());
185 }
186
187 private static class TestHostProvider extends AbstractProvider
188 implements HostProvider {
189
190 protected TestHostProvider() {
191 super(PID);
192 }
193
194 @Override
195 public ProviderId id() {
196 return PID;
197 }
198
199 @Override
200 public void triggerProbe(Host host) {
201 }
202
203 }
204
205 private static class TestListener implements HostListener {
206
207 protected List<HostEvent> events = Lists.newArrayList();
208
209 @Override
210 public void event(HostEvent event) {
211 events.add(event);
212 }
213
214 }
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700215
216 @Test
217 public void bindAddressesToPort() {
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700218 PortAddresses add1 =
219 new PortAddresses(CP1, Sets.newHashSet(IA1, IA2), MAC1);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700220
221 mgr.bindAddressesToPort(add1);
222 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
223
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700224 assertTrue(add1.ipAddresses().equals(storedAddresses.ipAddresses()));
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700225 assertTrue(add1.mac().equals(storedAddresses.mac()));
226
227 // Add some more addresses and check that they're added correctly
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700228 PortAddresses add2 =
229 new PortAddresses(CP1, Sets.newHashSet(IA3), null);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700230
231 mgr.bindAddressesToPort(add2);
232 storedAddresses = mgr.getAddressBindingsForPort(CP1);
233
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700234 assertTrue(storedAddresses.ipAddresses().equals(
235 Sets.newHashSet(IA1, IA2, IA3)));
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700236 assertTrue(storedAddresses.mac().equals(MAC1));
237
238 PortAddresses add3 = new PortAddresses(CP1, null, MAC2);
239
240 mgr.bindAddressesToPort(add3);
241 storedAddresses = mgr.getAddressBindingsForPort(CP1);
242
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700243 assertTrue(storedAddresses.ipAddresses().equals(
244 Sets.newHashSet(IA1, IA2, IA3)));
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700245 assertTrue(storedAddresses.mac().equals(MAC2));
246 }
247
248 @Test
249 public void unbindAddressesFromPort() {
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700250 PortAddresses add1 =
251 new PortAddresses(CP1, Sets.newHashSet(IA1, IA2), MAC1);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700252
253 mgr.bindAddressesToPort(add1);
254 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
255
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700256 assertTrue(storedAddresses.ipAddresses().size() == 2);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700257 assertNotNull(storedAddresses.mac());
258
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700259 PortAddresses rem1 =
260 new PortAddresses(CP1, Sets.newHashSet(IA1), null);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700261
262 mgr.unbindAddressesFromPort(rem1);
263 storedAddresses = mgr.getAddressBindingsForPort(CP1);
264
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700265 assertTrue(storedAddresses.ipAddresses().equals(Sets.newHashSet(IA2)));
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700266 assertTrue(storedAddresses.mac().equals(MAC1));
267
268 PortAddresses rem2 = new PortAddresses(CP1, null, MAC1);
269
270 mgr.unbindAddressesFromPort(rem2);
271 storedAddresses = mgr.getAddressBindingsForPort(CP1);
272
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700273 assertTrue(storedAddresses.ipAddresses().equals(Sets.newHashSet(IA2)));
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700274 assertNull(storedAddresses.mac());
275
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700276 PortAddresses rem3 =
277 new PortAddresses(CP1, Sets.newHashSet(IA2), MAC1);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700278
279 mgr.unbindAddressesFromPort(rem3);
280 storedAddresses = mgr.getAddressBindingsForPort(CP1);
281
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700282 assertTrue(storedAddresses.ipAddresses().isEmpty());
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700283 assertNull(storedAddresses.mac());
284 }
285
286 @Test
287 public void clearAddresses() {
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700288 PortAddresses add1 =
289 new PortAddresses(CP1, Sets.newHashSet(IA1, IA2), MAC1);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700290
291 mgr.bindAddressesToPort(add1);
292 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
293
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700294 assertTrue(storedAddresses.ipAddresses().size() == 2);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700295 assertNotNull(storedAddresses.mac());
296
297 mgr.clearAddresses(CP1);
298 storedAddresses = mgr.getAddressBindingsForPort(CP1);
299
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700300 assertTrue(storedAddresses.ipAddresses().isEmpty());
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700301 assertNull(storedAddresses.mac());
302 }
303
304 @Test
305 public void getAddressBindingsForPort() {
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700306 PortAddresses add1 =
307 new PortAddresses(CP1, Sets.newHashSet(IA1, IA2), MAC1);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700308
309 mgr.bindAddressesToPort(add1);
310 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
311
312 assertTrue(storedAddresses.connectPoint().equals(CP1));
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700313 assertTrue(storedAddresses.ipAddresses().equals(
314 Sets.newHashSet(IA1, IA2)));
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700315 assertTrue(storedAddresses.mac().equals(MAC1));
316 }
317
318 @Test
319 public void getAddressBindings() {
320 Set<PortAddresses> storedAddresses = mgr.getAddressBindings();
321
322 assertTrue(storedAddresses.isEmpty());
323
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700324 PortAddresses add1 =
325 new PortAddresses(CP1, Sets.newHashSet(IA1, IA2), MAC1);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700326
327 mgr.bindAddressesToPort(add1);
328
329 storedAddresses = mgr.getAddressBindings();
330
331 assertTrue(storedAddresses.size() == 1);
332
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700333 PortAddresses add2 =
334 new PortAddresses(CP2, Sets.newHashSet(IA3), MAC2);
Jonathan Hartc884f1b2014-09-24 11:53:33 -0700335
336 mgr.bindAddressesToPort(add2);
337
338 storedAddresses = mgr.getAddressBindings();
339
340 assertTrue(storedAddresses.size() == 2);
341 assertTrue(storedAddresses.equals(Sets.newHashSet(add1, add2)));
342 }
Ayaka Koshibeac8e7292014-09-16 16:08:31 -0700343}