blob: 2a5f03c776035e963da28efe7c99765c14c84735 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.host.impl;
alshabib4a179dc2014-10-17 17:17:01 -070017
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080018import static org.easymock.EasyMock.createMock;
19import static org.easymock.EasyMock.expect;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080020import static org.easymock.EasyMock.replay;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080021import static org.junit.Assert.assertEquals;
22import static org.junit.Assert.assertNotNull;
23import static org.junit.Assert.assertNull;
24import static org.onlab.packet.VlanId.vlanId;
25import static org.onosproject.net.Device.Type.SWITCH;
26import static org.onosproject.net.DeviceId.deviceId;
27import static org.onosproject.net.HostId.hostId;
28import static org.onosproject.net.PortNumber.portNumber;
29import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
30import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_REMOVED;
31import static org.onosproject.net.device.DeviceEvent.Type.PORT_UPDATED;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080032
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080033import java.nio.ByteBuffer;
34import java.util.Collections;
35import java.util.Dictionary;
36import java.util.Hashtable;
37import java.util.Set;
38
alshabib4a179dc2014-10-17 17:17:01 -070039import org.junit.After;
40import org.junit.Before;
41import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080042import org.onlab.osgi.ComponentContextAdapter;
43import org.onlab.packet.ARP;
44import org.onlab.packet.ChassisId;
45import org.onlab.packet.Ethernet;
46import org.onlab.packet.IpAddress;
47import org.onlab.packet.MacAddress;
48import org.onlab.packet.VlanId;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070049import org.onosproject.cfg.ComponentConfigAdapter;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080050import org.onosproject.core.ApplicationId;
51import org.onosproject.core.CoreService;
52import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080053import org.onosproject.net.ConnectPoint;
54import org.onosproject.net.DefaultDevice;
55import org.onosproject.net.DefaultHost;
56import org.onosproject.net.DefaultPort;
57import org.onosproject.net.Device;
58import org.onosproject.net.DeviceId;
59import org.onosproject.net.Host;
60import org.onosproject.net.HostId;
61import org.onosproject.net.HostLocation;
62import org.onosproject.net.device.DeviceEvent;
63import org.onosproject.net.device.DeviceListener;
64import org.onosproject.net.device.DeviceServiceAdapter;
Saurav Dasc313c402015-02-27 10:09:47 -080065import org.onosproject.net.flow.FlowRule;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080066import org.onosproject.net.flow.TrafficSelector;
Brian O'Connorabafb502014-12-02 22:26:20 -080067import org.onosproject.net.flow.TrafficTreatment;
68import org.onosproject.net.host.HostDescription;
69import org.onosproject.net.host.HostProvider;
70import org.onosproject.net.host.HostProviderRegistry;
71import org.onosproject.net.host.HostProviderService;
72import org.onosproject.net.host.HostServiceAdapter;
73import org.onosproject.net.packet.DefaultInboundPacket;
74import org.onosproject.net.packet.InboundPacket;
75import org.onosproject.net.packet.OutboundPacket;
76import org.onosproject.net.packet.PacketContext;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080077import org.onosproject.net.packet.PacketPriority;
Brian O'Connorabafb502014-12-02 22:26:20 -080078import org.onosproject.net.packet.PacketProcessor;
79import org.onosproject.net.packet.PacketService;
80import org.onosproject.net.provider.AbstractProviderService;
81import org.onosproject.net.provider.ProviderId;
82import org.onosproject.net.topology.Topology;
83import org.onosproject.net.topology.TopologyServiceAdapter;
alshabib4a179dc2014-10-17 17:17:01 -070084
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080085import com.google.common.collect.ImmutableSet;
Thomas Vachuska33601602014-11-19 03:32:15 -080086
alshabib4a179dc2014-10-17 17:17:01 -070087public class HostLocationProviderTest {
88
89 private static final Integer INPORT = 10;
90 private static final String DEV1 = "of:1";
91 private static final String DEV2 = "of:2";
92 private static final String DEV3 = "of:3";
93
Thomas Vachuska33601602014-11-19 03:32:15 -080094 private static final VlanId VLAN = vlanId();
alshabib4a179dc2014-10-17 17:17:01 -070095 private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
96 private static final MacAddress BCMAC = MacAddress.valueOf("ff:ff:ff:ff:ff:ff");
97 private static final byte[] IP = new byte[]{10, 0, 0, 1};
98
Thomas Vachuska33601602014-11-19 03:32:15 -080099 private static final IpAddress IP_ADDRESS =
100 IpAddress.valueOf(IpAddress.Version.INET, IP);
101 private static final HostLocation LOCATION =
102 new HostLocation(deviceId(DEV1), portNumber(INPORT), 0L);
103
104 private static final DefaultHost HOST =
105 new DefaultHost(ProviderId.NONE, hostId(MAC), MAC,
106 vlanId(VlanId.UNTAGGED), LOCATION,
107 ImmutableSet.of(IP_ADDRESS));
108
109 private static final ComponentContextAdapter CTX_FOR_REMOVE =
110 new ComponentContextAdapter() {
111 @Override
112 public Dictionary getProperties() {
113 Hashtable<String, String> props = new Hashtable<>();
114 props.put("hostRemovalEnabled", "true");
115 return props;
116 }
117 };
118
119 public static final ComponentContextAdapter CTX_FOR_NO_REMOVE =
120 new ComponentContextAdapter() {
121 @Override
122 public Dictionary getProperties() {
123 return new Hashtable();
124 }
125 };
126
alshabib4a179dc2014-10-17 17:17:01 -0700127 private final HostLocationProvider provider = new HostLocationProvider();
Thomas Vachuska33601602014-11-19 03:32:15 -0800128 private final TestHostRegistry hostRegistry = new TestHostRegistry();
alshabib4a179dc2014-10-17 17:17:01 -0700129 private final TestTopologyService topoService = new TestTopologyService();
Thomas Vachuska33601602014-11-19 03:32:15 -0800130 private final TestDeviceService deviceService = new TestDeviceService();
131 private final TestHostService hostService = new TestHostService();
alshabib4a179dc2014-10-17 17:17:01 -0700132 private final TestPacketService packetService = new TestPacketService();
133
134 private PacketProcessor testProcessor;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800135 private CoreService coreService;
alshabib4a179dc2014-10-17 17:17:01 -0700136 private TestHostProviderService providerService;
137
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800138 private ApplicationId appId =
139 new DefaultApplicationId(100, "org.onosproject.provider.host");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800140
alshabib4a179dc2014-10-17 17:17:01 -0700141 @Before
142 public void setUp() {
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800143
144 coreService = createMock(CoreService.class);
145 expect(coreService.registerApplication(appId.name()))
146 .andReturn(appId).anyTimes();
147 replay(coreService);
148
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700149 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800150 provider.coreService = coreService;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800151
Thomas Vachuska33601602014-11-19 03:32:15 -0800152 provider.providerRegistry = hostRegistry;
alshabib4a179dc2014-10-17 17:17:01 -0700153 provider.topologyService = topoService;
Pavlin Radoslavovd6612f92015-02-23 13:53:32 -0800154 provider.packetService = packetService;
Thomas Vachuska33601602014-11-19 03:32:15 -0800155 provider.deviceService = deviceService;
156 provider.hostService = hostService;
alshabib4a179dc2014-10-17 17:17:01 -0700157
Thomas Vachuska33601602014-11-19 03:32:15 -0800158 provider.activate(CTX_FOR_NO_REMOVE);
alshabib4a179dc2014-10-17 17:17:01 -0700159 }
160
161 @Test
162 public void basics() {
163 assertNotNull("registration expected", providerService);
164 assertEquals("incorrect provider", provider, providerService.provider());
165 }
166
167 @Test
168 public void events() {
169 // new host
alshabib4a179dc2014-10-17 17:17:01 -0700170 testProcessor.process(new TestPacketContext(DEV1));
171 assertNotNull("new host expected", providerService.added);
172 assertNull("host motion unexpected", providerService.moved);
173
174 // the host moved to new switch
175 testProcessor.process(new TestPacketContext(DEV2));
176 assertNotNull("host motion expected", providerService.moved);
177
178 // the host was misheard on a spine
179 testProcessor.process(new TestPacketContext(DEV3));
180 assertNull("host misheard on spine switch", providerService.spine);
181 }
182
Thomas Vachuska33601602014-11-19 03:32:15 -0800183 @Test
184 public void removeHostByDeviceRemove() {
185 provider.modified(CTX_FOR_REMOVE);
186 testProcessor.process(new TestPacketContext(DEV1));
187 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
188 "m", "h", "s", "n", new ChassisId(0L));
189 deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
190 assertEquals("incorrect remove count", 1, providerService.removeCount);
191 }
192
193 @Test
194 public void removeHostByDeviceOffline() {
195 provider.modified(CTX_FOR_REMOVE);
196 testProcessor.process(new TestPacketContext(DEV1));
197 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
198 "m", "h", "s", "n", new ChassisId(0L));
199 deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
200 assertEquals("incorrect remove count", 1, providerService.removeCount);
201 }
202
203 @Test
204 public void removeHostByDevicePortDown() {
205 provider.modified(CTX_FOR_REMOVE);
206 testProcessor.process(new TestPacketContext(DEV1));
207 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
208 "m", "h", "s", "n", new ChassisId(0L));
209 deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
210 new DefaultPort(device, portNumber(INPORT),
211 false)));
212 assertEquals("incorrect remove count", 1, providerService.removeCount);
213 }
214
215
alshabib4a179dc2014-10-17 17:17:01 -0700216 @After
217 public void tearDown() {
218 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800219 provider.coreService = null;
alshabib4a179dc2014-10-17 17:17:01 -0700220 provider.providerRegistry = null;
alshabib4a179dc2014-10-17 17:17:01 -0700221 }
222
223 private class TestHostRegistry implements HostProviderRegistry {
224
225 @Override
226 public HostProviderService register(HostProvider provider) {
227 providerService = new TestHostProviderService(provider);
228 return providerService;
229 }
230
231 @Override
232 public void unregister(HostProvider provider) {
233 }
234
235 @Override
236 public Set<ProviderId> getProviders() {
237 return null;
238 }
239
240 }
241
242 private class TestHostProviderService
243 extends AbstractProviderService<HostProvider>
244 implements HostProviderService {
245
246 DeviceId added = null;
247 DeviceId moved = null;
248 DeviceId spine = null;
Thomas Vachuska33601602014-11-19 03:32:15 -0800249 public int removeCount;
alshabib4a179dc2014-10-17 17:17:01 -0700250
251 protected TestHostProviderService(HostProvider provider) {
252 super(provider);
253 }
254
255 @Override
256 public void hostDetected(HostId hostId, HostDescription hostDescription) {
257 DeviceId descr = hostDescription.location().deviceId();
258 if (added == null) {
259 added = descr;
260 } else if ((moved == null) && !descr.equals(added)) {
261 moved = descr;
262 } else {
263 spine = descr;
264 }
265 }
266
267 @Override
268 public void hostVanished(HostId hostId) {
Thomas Vachuska33601602014-11-19 03:32:15 -0800269 removeCount++;
alshabib4a179dc2014-10-17 17:17:01 -0700270 }
271
272 }
273
274 private class TestPacketService implements PacketService {
275
276 @Override
277 public void addProcessor(PacketProcessor processor, int priority) {
278 testProcessor = processor;
279 }
280
281 @Override
282 public void removeProcessor(PacketProcessor processor) {
alshabib4a179dc2014-10-17 17:17:01 -0700283 }
284
285 @Override
286 public void emit(OutboundPacket packet) {
alshabib4a179dc2014-10-17 17:17:01 -0700287 }
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800288
289 @Override
290 public void requestPackets(TrafficSelector selector,
291 PacketPriority priority, ApplicationId appId) {
292 }
Saurav Dasc313c402015-02-27 10:09:47 -0800293
294 @Override
295 public void requestPackets(TrafficSelector selector,
296 PacketPriority priority, ApplicationId appId,
297 FlowRule.Type tableType) {
298 }
alshabib4a179dc2014-10-17 17:17:01 -0700299 }
300
301
302 private class TestTopologyService extends TopologyServiceAdapter {
303 @Override
304 public boolean isInfrastructure(Topology topology,
305 ConnectPoint connectPoint) {
306 //simulate DPID3 as an infrastructure switch
Thomas Vachuska33601602014-11-19 03:32:15 -0800307 if ((connectPoint.deviceId()).equals(deviceId(DEV3))) {
alshabib4a179dc2014-10-17 17:17:01 -0700308 return true;
309 }
310 return false;
311 }
312 }
313
314 private class TestPacketContext implements PacketContext {
315
316 private final String deviceId;
317
318 public TestPacketContext(String deviceId) {
319 this.deviceId = deviceId;
320 }
321
322 @Override
323 public long time() {
324 return 0;
325 }
326
327 @Override
328 public InboundPacket inPacket() {
329 ARP arp = new ARP();
330 arp.setSenderProtocolAddress(IP)
331 .setSenderHardwareAddress(MAC.toBytes())
332 .setTargetHardwareAddress(BCMAC.toBytes())
333 .setTargetProtocolAddress(IP);
334
335 Ethernet eth = new Ethernet();
336 eth.setEtherType(Ethernet.TYPE_ARP)
337 .setVlanID(VLAN.toShort())
338 .setSourceMACAddress(MAC.toBytes())
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800339 .setDestinationMACAddress(BCMAC)
alshabib4a179dc2014-10-17 17:17:01 -0700340 .setPayload(arp);
Thomas Vachuska33601602014-11-19 03:32:15 -0800341 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
342 portNumber(INPORT));
alshabib4a179dc2014-10-17 17:17:01 -0700343 return new DefaultInboundPacket(receivedFrom, eth,
344 ByteBuffer.wrap(eth.serialize()));
345 }
346
347 @Override
348 public OutboundPacket outPacket() {
349 return null;
350 }
351
352 @Override
353 public TrafficTreatment.Builder treatmentBuilder() {
354 return null;
355 }
356
357 @Override
358 public void send() {
359
360 }
361
362 @Override
363 public boolean block() {
364 return false;
365 }
366
367 @Override
368 public boolean isHandled() {
369 return false;
370 }
371 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800372
373 private class TestDeviceService extends DeviceServiceAdapter {
374 private DeviceListener listener;
375
376 @Override
377 public void addListener(DeviceListener listener) {
378 this.listener = listener;
379 }
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800380
381 @Override
382 public Iterable<Device> getDevices() {
383 return Collections.emptyList();
384 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800385 }
386
387 private class TestHostService extends HostServiceAdapter {
388 @Override
389 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
390 return ImmutableSet.of(HOST);
391 }
392
393 @Override
394 public Set<Host> getConnectedHosts(DeviceId deviceId) {
395 return ImmutableSet.of(HOST);
396 }
397
398 }
alshabib4a179dc2014-10-17 17:17:01 -0700399}