blob: b9d90976e9af51b3fe1f64dd7600b2f91ca0c067 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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
Thomas Vachuska27bee092015-06-23 19:03:10 -070018import com.google.common.collect.ImmutableSet;
alshabib4a179dc2014-10-17 17:17:01 -070019import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080022import org.onlab.osgi.ComponentContextAdapter;
23import org.onlab.packet.ARP;
24import org.onlab.packet.ChassisId;
25import org.onlab.packet.Ethernet;
26import org.onlab.packet.IpAddress;
27import org.onlab.packet.MacAddress;
28import org.onlab.packet.VlanId;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070029import org.onosproject.cfg.ComponentConfigAdapter;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080030import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
32import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.net.ConnectPoint;
34import org.onosproject.net.DefaultDevice;
35import org.onosproject.net.DefaultHost;
36import org.onosproject.net.DefaultPort;
37import org.onosproject.net.Device;
38import org.onosproject.net.DeviceId;
39import org.onosproject.net.Host;
40import org.onosproject.net.HostId;
41import org.onosproject.net.HostLocation;
42import org.onosproject.net.device.DeviceEvent;
43import org.onosproject.net.device.DeviceListener;
44import org.onosproject.net.device.DeviceServiceAdapter;
45import org.onosproject.net.flow.TrafficTreatment;
46import org.onosproject.net.host.HostDescription;
47import org.onosproject.net.host.HostProvider;
48import org.onosproject.net.host.HostProviderRegistry;
49import org.onosproject.net.host.HostProviderService;
50import org.onosproject.net.host.HostServiceAdapter;
51import org.onosproject.net.packet.DefaultInboundPacket;
52import org.onosproject.net.packet.InboundPacket;
53import org.onosproject.net.packet.OutboundPacket;
54import org.onosproject.net.packet.PacketContext;
55import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070056import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080057import org.onosproject.net.provider.AbstractProviderService;
58import org.onosproject.net.provider.ProviderId;
59import org.onosproject.net.topology.Topology;
60import org.onosproject.net.topology.TopologyServiceAdapter;
alshabib4a179dc2014-10-17 17:17:01 -070061
Thomas Vachuska27bee092015-06-23 19:03:10 -070062import java.nio.ByteBuffer;
63import java.util.Collections;
64import java.util.Dictionary;
65import java.util.Hashtable;
66import java.util.Set;
67
68import static org.easymock.EasyMock.*;
69import static org.junit.Assert.*;
70import static org.onlab.packet.VlanId.vlanId;
71import static org.onosproject.net.Device.Type.SWITCH;
72import static org.onosproject.net.DeviceId.deviceId;
73import static org.onosproject.net.HostId.hostId;
74import static org.onosproject.net.PortNumber.portNumber;
75import static org.onosproject.net.device.DeviceEvent.Type.*;
Thomas Vachuska33601602014-11-19 03:32:15 -080076
alshabib4a179dc2014-10-17 17:17:01 -070077public class HostLocationProviderTest {
78
79 private static final Integer INPORT = 10;
80 private static final String DEV1 = "of:1";
81 private static final String DEV2 = "of:2";
82 private static final String DEV3 = "of:3";
83
Thomas Vachuska33601602014-11-19 03:32:15 -080084 private static final VlanId VLAN = vlanId();
alshabib4a179dc2014-10-17 17:17:01 -070085 private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
86 private static final MacAddress BCMAC = MacAddress.valueOf("ff:ff:ff:ff:ff:ff");
87 private static final byte[] IP = new byte[]{10, 0, 0, 1};
88
Thomas Vachuska33601602014-11-19 03:32:15 -080089 private static final IpAddress IP_ADDRESS =
90 IpAddress.valueOf(IpAddress.Version.INET, IP);
91 private static final HostLocation LOCATION =
92 new HostLocation(deviceId(DEV1), portNumber(INPORT), 0L);
93
94 private static final DefaultHost HOST =
95 new DefaultHost(ProviderId.NONE, hostId(MAC), MAC,
96 vlanId(VlanId.UNTAGGED), LOCATION,
97 ImmutableSet.of(IP_ADDRESS));
98
99 private static final ComponentContextAdapter CTX_FOR_REMOVE =
100 new ComponentContextAdapter() {
101 @Override
102 public Dictionary getProperties() {
103 Hashtable<String, String> props = new Hashtable<>();
104 props.put("hostRemovalEnabled", "true");
105 return props;
106 }
107 };
108
109 public static final ComponentContextAdapter CTX_FOR_NO_REMOVE =
110 new ComponentContextAdapter() {
111 @Override
112 public Dictionary getProperties() {
113 return new Hashtable();
114 }
115 };
116
alshabib4a179dc2014-10-17 17:17:01 -0700117 private final HostLocationProvider provider = new HostLocationProvider();
Thomas Vachuska33601602014-11-19 03:32:15 -0800118 private final TestHostRegistry hostRegistry = new TestHostRegistry();
alshabib4a179dc2014-10-17 17:17:01 -0700119 private final TestTopologyService topoService = new TestTopologyService();
Thomas Vachuska33601602014-11-19 03:32:15 -0800120 private final TestDeviceService deviceService = new TestDeviceService();
121 private final TestHostService hostService = new TestHostService();
alshabib4a179dc2014-10-17 17:17:01 -0700122 private final TestPacketService packetService = new TestPacketService();
123
124 private PacketProcessor testProcessor;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800125 private CoreService coreService;
alshabib4a179dc2014-10-17 17:17:01 -0700126 private TestHostProviderService providerService;
127
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800128 private ApplicationId appId =
129 new DefaultApplicationId(100, "org.onosproject.provider.host");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800130
alshabib4a179dc2014-10-17 17:17:01 -0700131 @Before
132 public void setUp() {
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800133
134 coreService = createMock(CoreService.class);
135 expect(coreService.registerApplication(appId.name()))
Thomas Vachuska27bee092015-06-23 19:03:10 -0700136 .andReturn(appId).anyTimes();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800137 replay(coreService);
138
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700139 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800140 provider.coreService = coreService;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800141
Thomas Vachuska33601602014-11-19 03:32:15 -0800142 provider.providerRegistry = hostRegistry;
alshabib4a179dc2014-10-17 17:17:01 -0700143 provider.topologyService = topoService;
Pavlin Radoslavovd6612f92015-02-23 13:53:32 -0800144 provider.packetService = packetService;
Thomas Vachuska33601602014-11-19 03:32:15 -0800145 provider.deviceService = deviceService;
146 provider.hostService = hostService;
alshabib4a179dc2014-10-17 17:17:01 -0700147
Thomas Vachuska33601602014-11-19 03:32:15 -0800148 provider.activate(CTX_FOR_NO_REMOVE);
alshabib4a179dc2014-10-17 17:17:01 -0700149 }
150
151 @Test
152 public void basics() {
153 assertNotNull("registration expected", providerService);
154 assertEquals("incorrect provider", provider, providerService.provider());
155 }
156
157 @Test
158 public void events() {
159 // new host
alshabib4a179dc2014-10-17 17:17:01 -0700160 testProcessor.process(new TestPacketContext(DEV1));
161 assertNotNull("new host expected", providerService.added);
162 assertNull("host motion unexpected", providerService.moved);
163
164 // the host moved to new switch
165 testProcessor.process(new TestPacketContext(DEV2));
166 assertNotNull("host motion expected", providerService.moved);
167
168 // the host was misheard on a spine
169 testProcessor.process(new TestPacketContext(DEV3));
170 assertNull("host misheard on spine switch", providerService.spine);
171 }
172
Thomas Vachuska33601602014-11-19 03:32:15 -0800173 @Test
174 public void removeHostByDeviceRemove() {
175 provider.modified(CTX_FOR_REMOVE);
176 testProcessor.process(new TestPacketContext(DEV1));
177 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
178 "m", "h", "s", "n", new ChassisId(0L));
179 deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
180 assertEquals("incorrect remove count", 1, providerService.removeCount);
181 }
182
183 @Test
184 public void removeHostByDeviceOffline() {
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_AVAILABILITY_CHANGED, device));
190 assertEquals("incorrect remove count", 1, providerService.removeCount);
191 }
192
193 @Test
194 public void removeHostByDevicePortDown() {
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(PORT_UPDATED, device,
200 new DefaultPort(device, portNumber(INPORT),
201 false)));
202 assertEquals("incorrect remove count", 1, providerService.removeCount);
203 }
204
205
alshabib4a179dc2014-10-17 17:17:01 -0700206 @After
207 public void tearDown() {
208 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800209 provider.coreService = null;
alshabib4a179dc2014-10-17 17:17:01 -0700210 provider.providerRegistry = null;
alshabib4a179dc2014-10-17 17:17:01 -0700211 }
212
213 private class TestHostRegistry implements HostProviderRegistry {
214
215 @Override
216 public HostProviderService register(HostProvider provider) {
217 providerService = new TestHostProviderService(provider);
218 return providerService;
219 }
220
221 @Override
222 public void unregister(HostProvider provider) {
223 }
224
225 @Override
226 public Set<ProviderId> getProviders() {
227 return null;
228 }
229
230 }
231
232 private class TestHostProviderService
233 extends AbstractProviderService<HostProvider>
234 implements HostProviderService {
235
236 DeviceId added = null;
237 DeviceId moved = null;
238 DeviceId spine = null;
Thomas Vachuska33601602014-11-19 03:32:15 -0800239 public int removeCount;
alshabib4a179dc2014-10-17 17:17:01 -0700240
241 protected TestHostProviderService(HostProvider provider) {
242 super(provider);
243 }
244
245 @Override
246 public void hostDetected(HostId hostId, HostDescription hostDescription) {
247 DeviceId descr = hostDescription.location().deviceId();
248 if (added == null) {
249 added = descr;
250 } else if ((moved == null) && !descr.equals(added)) {
251 moved = descr;
252 } else {
253 spine = descr;
254 }
255 }
256
257 @Override
258 public void hostVanished(HostId hostId) {
Thomas Vachuska33601602014-11-19 03:32:15 -0800259 removeCount++;
alshabib4a179dc2014-10-17 17:17:01 -0700260 }
261
262 }
263
Thomas Vachuska27bee092015-06-23 19:03:10 -0700264 private class TestPacketService extends PacketServiceAdapter {
alshabib4a179dc2014-10-17 17:17:01 -0700265 @Override
266 public void addProcessor(PacketProcessor processor, int priority) {
267 testProcessor = processor;
268 }
alshabib4a179dc2014-10-17 17:17:01 -0700269 }
270
271
272 private class TestTopologyService extends TopologyServiceAdapter {
273 @Override
274 public boolean isInfrastructure(Topology topology,
275 ConnectPoint connectPoint) {
276 //simulate DPID3 as an infrastructure switch
Thomas Vachuska33601602014-11-19 03:32:15 -0800277 if ((connectPoint.deviceId()).equals(deviceId(DEV3))) {
alshabib4a179dc2014-10-17 17:17:01 -0700278 return true;
279 }
280 return false;
281 }
282 }
283
284 private class TestPacketContext implements PacketContext {
285
286 private final String deviceId;
287
288 public TestPacketContext(String deviceId) {
289 this.deviceId = deviceId;
290 }
291
292 @Override
293 public long time() {
294 return 0;
295 }
296
297 @Override
298 public InboundPacket inPacket() {
299 ARP arp = new ARP();
300 arp.setSenderProtocolAddress(IP)
301 .setSenderHardwareAddress(MAC.toBytes())
302 .setTargetHardwareAddress(BCMAC.toBytes())
303 .setTargetProtocolAddress(IP);
304
305 Ethernet eth = new Ethernet();
306 eth.setEtherType(Ethernet.TYPE_ARP)
307 .setVlanID(VLAN.toShort())
308 .setSourceMACAddress(MAC.toBytes())
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800309 .setDestinationMACAddress(BCMAC)
alshabib4a179dc2014-10-17 17:17:01 -0700310 .setPayload(arp);
Thomas Vachuska33601602014-11-19 03:32:15 -0800311 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
312 portNumber(INPORT));
alshabib4a179dc2014-10-17 17:17:01 -0700313 return new DefaultInboundPacket(receivedFrom, eth,
314 ByteBuffer.wrap(eth.serialize()));
315 }
316
317 @Override
318 public OutboundPacket outPacket() {
319 return null;
320 }
321
322 @Override
323 public TrafficTreatment.Builder treatmentBuilder() {
324 return null;
325 }
326
327 @Override
328 public void send() {
329
330 }
331
332 @Override
333 public boolean block() {
334 return false;
335 }
336
337 @Override
338 public boolean isHandled() {
339 return false;
340 }
341 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800342
343 private class TestDeviceService extends DeviceServiceAdapter {
344 private DeviceListener listener;
345
346 @Override
347 public void addListener(DeviceListener listener) {
348 this.listener = listener;
349 }
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800350
351 @Override
352 public Iterable<Device> getDevices() {
353 return Collections.emptyList();
354 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800355 }
356
357 private class TestHostService extends HostServiceAdapter {
358 @Override
359 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
360 return ImmutableSet.of(HOST);
361 }
362
363 @Override
364 public Set<Host> getConnectedHosts(DeviceId deviceId) {
365 return ImmutableSet.of(HOST);
366 }
367
368 }
alshabib4a179dc2014-10-17 17:17:01 -0700369}