blob: 7152ad9d1d343b1ad85f12c5a10fce3de8dc609d [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.host.impl;
Jonathan Hartb4758a92014-09-24 10:46:45 -070017
18import static org.easymock.EasyMock.createMock;
19import static org.easymock.EasyMock.expect;
20import static org.easymock.EasyMock.expectLastCall;
21import static org.easymock.EasyMock.replay;
22import static org.easymock.EasyMock.verify;
Jonathan Harta887ba82014-11-03 15:20:52 -080023import static org.junit.Assert.assertArrayEquals;
24import static org.junit.Assert.assertEquals;
25import static org.junit.Assert.assertTrue;
Jonathan Hartb4758a92014-09-24 10:46:45 -070026
27import java.util.ArrayList;
Jonathan Hartb4758a92014-09-24 10:46:45 -070028import java.util.Collections;
29import java.util.List;
30import java.util.Set;
31
Jonathan Hartdc09a3b2014-10-27 11:34:26 -070032import org.junit.After;
Jonathan Hartb4758a92014-09-24 10:46:45 -070033import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080034import org.onlab.packet.ARP;
35import org.onlab.packet.Ethernet;
36import org.onlab.packet.IpAddress;
37import org.onlab.packet.IpPrefix;
38import org.onlab.packet.MacAddress;
39import org.onosproject.core.ApplicationId;
Jonathan Hart6cd2f352015-01-13 17:44:45 -080040import org.onlab.packet.VlanId;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.net.ConnectPoint;
42import org.onosproject.net.Device;
43import org.onosproject.net.DeviceId;
44import org.onosproject.net.Host;
45import org.onosproject.net.MastershipRole;
46import org.onosproject.net.Port;
47import org.onosproject.net.PortNumber;
48import org.onosproject.net.device.DeviceListener;
49import org.onosproject.net.device.DeviceServiceAdapter;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080050import org.onosproject.net.flow.TrafficSelector;
Brian O'Connorabafb502014-12-02 22:26:20 -080051import org.onosproject.net.flow.instructions.Instruction;
52import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
53import org.onosproject.net.host.HostProvider;
54import org.onosproject.net.host.InterfaceIpAddress;
55import org.onosproject.net.host.PortAddresses;
56import org.onosproject.net.packet.OutboundPacket;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080057import org.onosproject.net.packet.PacketPriority;
Brian O'Connorabafb502014-12-02 22:26:20 -080058import org.onosproject.net.packet.PacketProcessor;
59import org.onosproject.net.packet.PacketService;
60import org.onosproject.net.provider.ProviderId;
Jonathan Hartb4758a92014-09-24 10:46:45 -070061
62import com.google.common.collect.HashMultimap;
63import com.google.common.collect.Lists;
64import com.google.common.collect.Multimap;
65
66public class HostMonitorTest {
67
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070068 private static final IpAddress TARGET_IP_ADDR =
69 IpAddress.valueOf("10.0.0.1");
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -070070 private static final IpAddress SOURCE_ADDR =
71 IpAddress.valueOf("10.0.0.99");
72 private static final InterfaceIpAddress IA1 =
73 new InterfaceIpAddress(SOURCE_ADDR, IpPrefix.valueOf("10.0.0.0/24"));
Jonathan Hartb4758a92014-09-24 10:46:45 -070074 private MacAddress sourceMac = MacAddress.valueOf(1L);
75
76 private HostMonitor hostMonitor;
77
Jonathan Hartdc09a3b2014-10-27 11:34:26 -070078 @After
79 public void shutdown() {
80 hostMonitor.shutdown();
81 }
82
Jonathan Hartb4758a92014-09-24 10:46:45 -070083 @Test
84 public void testMonitorHostExists() throws Exception {
85 ProviderId id = new ProviderId("fake://", "id");
86
87 Host host = createMock(Host.class);
88 expect(host.providerId()).andReturn(id);
89 replay(host);
90
91 HostManager hostManager = createMock(HostManager.class);
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070092 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
Jonathan Hartb4758a92014-09-24 10:46:45 -070093 .andReturn(Collections.singleton(host));
94 replay(hostManager);
95
96 HostProvider hostProvider = createMock(HostProvider.class);
97 expect(hostProvider.id()).andReturn(id).anyTimes();
98 hostProvider.triggerProbe(host);
99 expectLastCall().once();
100 replay(hostProvider);
101
102 hostMonitor = new HostMonitor(null, null, hostManager);
103
104 hostMonitor.registerHostProvider(hostProvider);
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700105 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700106
107 hostMonitor.run(null);
108
109 verify(hostProvider);
110 }
111
112 @Test
Jonathan Hartb4758a92014-09-24 10:46:45 -0700113 public void testMonitorHostDoesNotExist() throws Exception {
Jonathan Hartdc09a3b2014-10-27 11:34:26 -0700114
Jonathan Hartb4758a92014-09-24 10:46:45 -0700115 HostManager hostManager = createMock(HostManager.class);
116
117 DeviceId devId = DeviceId.deviceId("fake");
118
119 Device device = createMock(Device.class);
120 expect(device.id()).andReturn(devId).anyTimes();
121 replay(device);
122
123 PortNumber portNum = PortNumber.portNumber(1L);
124
125 Port port = createMock(Port.class);
126 expect(port.number()).andReturn(portNum).anyTimes();
127 replay(port);
128
129 TestDeviceService deviceService = new TestDeviceService();
130 deviceService.addDevice(device, Collections.singleton(port));
131
132 ConnectPoint cp = new ConnectPoint(devId, portNum);
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700133 PortAddresses pa =
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800134 new PortAddresses(cp, Collections.singleton(IA1), sourceMac, VlanId.NONE);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700135
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700136 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
Jonathan Hartb4758a92014-09-24 10:46:45 -0700137 .andReturn(Collections.<Host>emptySet()).anyTimes();
138 expect(hostManager.getAddressBindingsForPort(cp))
Jonathan Harta887ba82014-11-03 15:20:52 -0800139 .andReturn(Collections.singleton(pa)).anyTimes();
Jonathan Hartb4758a92014-09-24 10:46:45 -0700140 replay(hostManager);
141
142 TestPacketService packetService = new TestPacketService();
143
144
145 // Run the test
146 hostMonitor = new HostMonitor(deviceService, packetService, hostManager);
147
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700148 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700149 hostMonitor.run(null);
150
151
152 // Check that a packet was sent to our PacketService and that it has
153 // the properties we expect
Jonathan Hartdc09a3b2014-10-27 11:34:26 -0700154 assertEquals(1, packetService.packets.size());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700155 OutboundPacket packet = packetService.packets.get(0);
156
157 // Check the output port is correct
Jonathan Hartdc09a3b2014-10-27 11:34:26 -0700158 assertEquals(1, packet.treatment().instructions().size());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700159 Instruction instruction = packet.treatment().instructions().get(0);
160 assertTrue(instruction instanceof OutputInstruction);
161 OutputInstruction oi = (OutputInstruction) instruction;
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800162 assertEquals(portNum, oi.port());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700163
164 // Check the output packet is correct (well the important bits anyway)
165 Ethernet eth = new Ethernet();
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800166 final byte[] pktData = new byte[packet.data().remaining()];
167 packet.data().get(pktData);
168 eth.deserialize(pktData, 0, pktData.length);
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800169 assertEquals(Ethernet.VLAN_UNTAGGED, eth.getVlanID());
170 ARP arp = (ARP) eth.getPayload();
171 assertArrayEquals(SOURCE_ADDR.toOctets(),
172 arp.getSenderProtocolAddress());
173 assertArrayEquals(sourceMac.toBytes(),
174 arp.getSenderHardwareAddress());
175 assertArrayEquals(TARGET_IP_ADDR.toOctets(),
176 arp.getTargetProtocolAddress());
177 }
178
179 @Test
180 public void testMonitorHostDoesNotExistWithVlan() throws Exception {
181
182 HostManager hostManager = createMock(HostManager.class);
183
184 DeviceId devId = DeviceId.deviceId("fake");
185 short vlan = 5;
186
187 Device device = createMock(Device.class);
188 expect(device.id()).andReturn(devId).anyTimes();
189 replay(device);
190
191 PortNumber portNum = PortNumber.portNumber(1L);
192
193 Port port = createMock(Port.class);
194 expect(port.number()).andReturn(portNum).anyTimes();
195 replay(port);
196
197 TestDeviceService deviceService = new TestDeviceService();
198 deviceService.addDevice(device, Collections.singleton(port));
199
200 ConnectPoint cp = new ConnectPoint(devId, portNum);
201 PortAddresses pa =
202 new PortAddresses(cp, Collections.singleton(IA1), sourceMac,
203 VlanId.vlanId(vlan));
204
205 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
206 .andReturn(Collections.<Host>emptySet()).anyTimes();
207 expect(hostManager.getAddressBindingsForPort(cp))
208 .andReturn(Collections.singleton(pa)).anyTimes();
209 replay(hostManager);
210
211 TestPacketService packetService = new TestPacketService();
212
213
214 // Run the test
215 hostMonitor = new HostMonitor(deviceService, packetService, hostManager);
216
217 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
218 hostMonitor.run(null);
219
220
221 // Check that a packet was sent to our PacketService and that it has
222 // the properties we expect
223 assertEquals(1, packetService.packets.size());
224 OutboundPacket packet = packetService.packets.get(0);
225
226 // Check the output port is correct
227 assertEquals(1, packet.treatment().instructions().size());
228 Instruction instruction = packet.treatment().instructions().get(0);
229 assertTrue(instruction instanceof OutputInstruction);
230 OutputInstruction oi = (OutputInstruction) instruction;
231 assertEquals(portNum, oi.port());
232
233 // Check the output packet is correct (well the important bits anyway)
234 Ethernet eth = new Ethernet();
235 final byte[] pktData = new byte[packet.data().remaining()];
236 packet.data().get(pktData);
237 eth.deserialize(pktData, 0, pktData.length);
238 assertEquals(vlan, eth.getVlanID());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700239 ARP arp = (ARP) eth.getPayload();
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800240 assertArrayEquals(SOURCE_ADDR.toOctets(),
241 arp.getSenderProtocolAddress());
242 assertArrayEquals(sourceMac.toBytes(),
243 arp.getSenderHardwareAddress());
244 assertArrayEquals(TARGET_IP_ADDR.toOctets(),
245 arp.getTargetProtocolAddress());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700246 }
247
248 class TestPacketService implements PacketService {
249
250 List<OutboundPacket> packets = new ArrayList<>();
251
252 @Override
253 public void addProcessor(PacketProcessor processor, int priority) {
254 }
255
256 @Override
257 public void removeProcessor(PacketProcessor processor) {
258 }
259
260 @Override
261 public void emit(OutboundPacket packet) {
262 packets.add(packet);
263 }
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800264
265 @Override
266 public void requestPackets(TrafficSelector selector,
267 PacketPriority priority, ApplicationId appId) {
268 }
Jonathan Hartb4758a92014-09-24 10:46:45 -0700269 }
270
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800271 class TestDeviceService extends DeviceServiceAdapter {
Jonathan Hartb4758a92014-09-24 10:46:45 -0700272
273 List<Device> devices = Lists.newArrayList();
274 Multimap<DeviceId, Port> devicePorts = HashMultimap.create();
275
276 void addDevice(Device device, Set<Port> ports) {
277 devices.add(device);
278 for (Port p : ports) {
279 devicePorts.put(device.id(), p);
280 }
281 }
282
283 @Override
284 public int getDeviceCount() {
285 return 0;
286 }
287
288 @Override
289 public Iterable<Device> getDevices() {
290 return devices;
291 }
292
293 @Override
294 public Device getDevice(DeviceId deviceId) {
295 return null;
296 }
297
298 @Override
299 public MastershipRole getRole(DeviceId deviceId) {
300 return null;
301 }
302
303 @Override
304 public List<Port> getPorts(DeviceId deviceId) {
305 List<Port> ports = Lists.newArrayList();
306 for (Port p : devicePorts.get(deviceId)) {
307 ports.add(p);
308 }
309 return ports;
310 }
311
312 @Override
313 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
314 return null;
315 }
316
317 @Override
318 public boolean isAvailable(DeviceId deviceId) {
319 return false;
320 }
321
322 @Override
323 public void addListener(DeviceListener listener) {
324 }
325
326 @Override
327 public void removeListener(DeviceListener listener) {
328 }
329 }
330}