blob: 4385ac23e767c7a6061ef1dddf0a651a8d3ae97b [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.host.impl;
Jonathan Hartb4758a92014-09-24 10:46:45 -070017
Thomas Vachuska27bee092015-06-23 19:03:10 -070018import com.google.common.collect.HashMultimap;
19import com.google.common.collect.Lists;
20import com.google.common.collect.Multimap;
Jonathan Hartdc09a3b2014-10-27 11:34:26 -070021import org.junit.After;
Jonathan Hartfb32a6e2015-09-01 12:12:14 +020022import org.junit.Before;
Jonathan Hartb4758a92014-09-24 10:46:45 -070023import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080024import org.onlab.packet.ARP;
25import org.onlab.packet.Ethernet;
26import org.onlab.packet.IpAddress;
27import org.onlab.packet.IpPrefix;
28import org.onlab.packet.MacAddress;
Jonathan Hart6cd2f352015-01-13 17:44:45 -080029import org.onlab.packet.VlanId;
Jonathan Hart4cb39882015-08-12 23:50:55 -040030import org.onosproject.incubator.net.intf.Interface;
31import org.onosproject.incubator.net.intf.InterfaceService;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.net.ConnectPoint;
33import org.onosproject.net.Device;
34import org.onosproject.net.DeviceId;
35import org.onosproject.net.Host;
36import org.onosproject.net.MastershipRole;
37import org.onosproject.net.Port;
38import org.onosproject.net.PortNumber;
39import org.onosproject.net.device.DeviceListener;
40import org.onosproject.net.device.DeviceServiceAdapter;
Jonathan Hartfb32a6e2015-09-01 12:12:14 +020041import org.onosproject.net.edge.EdgePortService;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.flow.instructions.Instruction;
43import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
44import org.onosproject.net.host.HostProvider;
45import org.onosproject.net.host.InterfaceIpAddress;
46import org.onosproject.net.host.PortAddresses;
47import org.onosproject.net.packet.OutboundPacket;
Thomas Vachuska27bee092015-06-23 19:03:10 -070048import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080049import org.onosproject.net.provider.ProviderId;
Jonathan Hartb4758a92014-09-24 10:46:45 -070050
Thomas Vachuska27bee092015-06-23 19:03:10 -070051import java.util.ArrayList;
52import java.util.Collections;
53import java.util.List;
54import java.util.Set;
55
Jonathan Hartfb32a6e2015-09-01 12:12:14 +020056import static org.easymock.EasyMock.anyObject;
Jonathan Hart2a655752015-04-07 16:46:33 -070057import static org.easymock.EasyMock.createMock;
58import static org.easymock.EasyMock.expect;
59import static org.easymock.EasyMock.expectLastCall;
60import static org.easymock.EasyMock.replay;
61import static org.easymock.EasyMock.verify;
62import static org.junit.Assert.assertArrayEquals;
63import static org.junit.Assert.assertEquals;
64import static org.junit.Assert.assertTrue;
Jonathan Hartb4758a92014-09-24 10:46:45 -070065
66public class HostMonitorTest {
67
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070068 private static final IpAddress TARGET_IP_ADDR =
Thomas Vachuska27bee092015-06-23 19:03:10 -070069 IpAddress.valueOf("10.0.0.1");
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -070070 private static final IpAddress SOURCE_ADDR =
Thomas Vachuska27bee092015-06-23 19:03:10 -070071 IpAddress.valueOf("10.0.0.99");
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -070072 private static final InterfaceIpAddress IA1 =
Thomas Vachuska27bee092015-06-23 19:03:10 -070073 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
Jonathan Hartfb32a6e2015-09-01 12:12:14 +020076 private EdgePortService edgePortService;
77
Jonathan Hartb4758a92014-09-24 10:46:45 -070078 private HostMonitor hostMonitor;
79
Jonathan Hartfb32a6e2015-09-01 12:12:14 +020080 @Before
81 public void setUp() {
82 edgePortService = createMock(EdgePortService.class);
83 expect(edgePortService.isEdgePoint(anyObject(ConnectPoint.class)))
84 .andReturn(true).anyTimes();
85 replay(edgePortService);
86 }
87
Jonathan Hartdc09a3b2014-10-27 11:34:26 -070088 @After
89 public void shutdown() {
90 hostMonitor.shutdown();
91 }
92
Jonathan Hartb4758a92014-09-24 10:46:45 -070093 @Test
94 public void testMonitorHostExists() throws Exception {
95 ProviderId id = new ProviderId("fake://", "id");
96
97 Host host = createMock(Host.class);
98 expect(host.providerId()).andReturn(id);
99 replay(host);
100
101 HostManager hostManager = createMock(HostManager.class);
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700102 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
Jonathan Hartb4758a92014-09-24 10:46:45 -0700103 .andReturn(Collections.singleton(host));
104 replay(hostManager);
105
106 HostProvider hostProvider = createMock(HostProvider.class);
107 expect(hostProvider.id()).andReturn(id).anyTimes();
108 hostProvider.triggerProbe(host);
109 expectLastCall().once();
110 replay(hostProvider);
111
Jonathan Hartfb32a6e2015-09-01 12:12:14 +0200112 hostMonitor = new HostMonitor(null, hostManager, null, edgePortService);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700113
114 hostMonitor.registerHostProvider(hostProvider);
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700115 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700116
117 hostMonitor.run(null);
118
119 verify(hostProvider);
120 }
121
122 @Test
Jonathan Hartb4758a92014-09-24 10:46:45 -0700123 public void testMonitorHostDoesNotExist() throws Exception {
Jonathan Hartdc09a3b2014-10-27 11:34:26 -0700124
Jonathan Hartb4758a92014-09-24 10:46:45 -0700125 HostManager hostManager = createMock(HostManager.class);
126
127 DeviceId devId = DeviceId.deviceId("fake");
128
129 Device device = createMock(Device.class);
130 expect(device.id()).andReturn(devId).anyTimes();
131 replay(device);
132
133 PortNumber portNum = PortNumber.portNumber(1L);
134
135 Port port = createMock(Port.class);
136 expect(port.number()).andReturn(portNum).anyTimes();
137 replay(port);
138
139 TestDeviceService deviceService = new TestDeviceService();
140 deviceService.addDevice(device, Collections.singleton(port));
141
142 ConnectPoint cp = new ConnectPoint(devId, portNum);
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700143 PortAddresses pa =
Thomas Vachuska27bee092015-06-23 19:03:10 -0700144 new PortAddresses(cp, Collections.singleton(IA1), sourceMac, VlanId.NONE);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700145
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700146 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
Jonathan Hart4cb39882015-08-12 23:50:55 -0400147 .andReturn(Collections.emptySet()).anyTimes();
Jonathan Hartb4758a92014-09-24 10:46:45 -0700148 replay(hostManager);
149
Jonathan Hart4cb39882015-08-12 23:50:55 -0400150 InterfaceService interfaceService = createMock(InterfaceService.class);
151 expect(interfaceService.getMatchingInterface(TARGET_IP_ADDR))
152 .andReturn(new Interface(cp, Collections.singleton(IA1), sourceMac, VlanId.NONE))
153 .anyTimes();
154 replay(interfaceService);
155
Jonathan Hartb4758a92014-09-24 10:46:45 -0700156 TestPacketService packetService = new TestPacketService();
157
158
159 // Run the test
Jonathan Hartfb32a6e2015-09-01 12:12:14 +0200160 hostMonitor = new HostMonitor(packetService, hostManager, interfaceService, edgePortService);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700161
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700162 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700163 hostMonitor.run(null);
164
165
166 // Check that a packet was sent to our PacketService and that it has
167 // the properties we expect
Jonathan Hartdc09a3b2014-10-27 11:34:26 -0700168 assertEquals(1, packetService.packets.size());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700169 OutboundPacket packet = packetService.packets.get(0);
170
171 // Check the output port is correct
Ray Milkey42507352015-03-20 15:16:10 -0700172 assertEquals(1, packet.treatment().immediate().size());
173 Instruction instruction = packet.treatment().immediate().get(0);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700174 assertTrue(instruction instanceof OutputInstruction);
175 OutputInstruction oi = (OutputInstruction) instruction;
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800176 assertEquals(portNum, oi.port());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700177
178 // Check the output packet is correct (well the important bits anyway)
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800179 final byte[] pktData = new byte[packet.data().remaining()];
180 packet.data().get(pktData);
Jonathan Hart2a655752015-04-07 16:46:33 -0700181 Ethernet eth = Ethernet.deserializer().deserialize(pktData, 0, pktData.length);
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800182 assertEquals(Ethernet.VLAN_UNTAGGED, eth.getVlanID());
183 ARP arp = (ARP) eth.getPayload();
184 assertArrayEquals(SOURCE_ADDR.toOctets(),
185 arp.getSenderProtocolAddress());
186 assertArrayEquals(sourceMac.toBytes(),
187 arp.getSenderHardwareAddress());
188 assertArrayEquals(TARGET_IP_ADDR.toOctets(),
189 arp.getTargetProtocolAddress());
190 }
191
192 @Test
193 public void testMonitorHostDoesNotExistWithVlan() throws Exception {
194
195 HostManager hostManager = createMock(HostManager.class);
196
197 DeviceId devId = DeviceId.deviceId("fake");
198 short vlan = 5;
199
200 Device device = createMock(Device.class);
201 expect(device.id()).andReturn(devId).anyTimes();
202 replay(device);
203
204 PortNumber portNum = PortNumber.portNumber(1L);
205
206 Port port = createMock(Port.class);
207 expect(port.number()).andReturn(portNum).anyTimes();
208 replay(port);
209
210 TestDeviceService deviceService = new TestDeviceService();
211 deviceService.addDevice(device, Collections.singleton(port));
212
213 ConnectPoint cp = new ConnectPoint(devId, portNum);
214 PortAddresses pa =
Thomas Vachuska27bee092015-06-23 19:03:10 -0700215 new PortAddresses(cp, Collections.singleton(IA1), sourceMac,
216 VlanId.vlanId(vlan));
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800217
218 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
Jonathan Hart4cb39882015-08-12 23:50:55 -0400219 .andReturn(Collections.emptySet()).anyTimes();
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800220 replay(hostManager);
221
Jonathan Hart4cb39882015-08-12 23:50:55 -0400222 InterfaceService interfaceService = createMock(InterfaceService.class);
223 expect(interfaceService.getMatchingInterface(TARGET_IP_ADDR))
224 .andReturn(new Interface(cp, Collections.singleton(IA1), sourceMac, VlanId.vlanId(vlan)))
225 .anyTimes();
226 replay(interfaceService);
227
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800228 TestPacketService packetService = new TestPacketService();
229
230
231 // Run the test
Jonathan Hartfb32a6e2015-09-01 12:12:14 +0200232 hostMonitor = new HostMonitor(packetService, hostManager, interfaceService, edgePortService);
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800233
234 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
235 hostMonitor.run(null);
236
237
238 // Check that a packet was sent to our PacketService and that it has
239 // the properties we expect
240 assertEquals(1, packetService.packets.size());
241 OutboundPacket packet = packetService.packets.get(0);
242
243 // Check the output port is correct
Ray Milkey42507352015-03-20 15:16:10 -0700244 assertEquals(1, packet.treatment().immediate().size());
245 Instruction instruction = packet.treatment().immediate().get(0);
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800246 assertTrue(instruction instanceof OutputInstruction);
247 OutputInstruction oi = (OutputInstruction) instruction;
248 assertEquals(portNum, oi.port());
249
250 // Check the output packet is correct (well the important bits anyway)
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800251 final byte[] pktData = new byte[packet.data().remaining()];
252 packet.data().get(pktData);
Jonathan Hart2a655752015-04-07 16:46:33 -0700253 Ethernet eth = Ethernet.deserializer().deserialize(pktData, 0, pktData.length);
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800254 assertEquals(vlan, eth.getVlanID());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700255 ARP arp = (ARP) eth.getPayload();
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800256 assertArrayEquals(SOURCE_ADDR.toOctets(),
257 arp.getSenderProtocolAddress());
258 assertArrayEquals(sourceMac.toBytes(),
259 arp.getSenderHardwareAddress());
260 assertArrayEquals(TARGET_IP_ADDR.toOctets(),
261 arp.getTargetProtocolAddress());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700262 }
263
Thomas Vachuska27bee092015-06-23 19:03:10 -0700264 class TestPacketService extends PacketServiceAdapter {
Jonathan Hartb4758a92014-09-24 10:46:45 -0700265
266 List<OutboundPacket> packets = new ArrayList<>();
267
268 @Override
Jonathan Hartb4758a92014-09-24 10:46:45 -0700269 public void emit(OutboundPacket packet) {
270 packets.add(packet);
271 }
272 }
273
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800274 class TestDeviceService extends DeviceServiceAdapter {
Jonathan Hartb4758a92014-09-24 10:46:45 -0700275
276 List<Device> devices = Lists.newArrayList();
277 Multimap<DeviceId, Port> devicePorts = HashMultimap.create();
278
279 void addDevice(Device device, Set<Port> ports) {
280 devices.add(device);
281 for (Port p : ports) {
282 devicePorts.put(device.id(), p);
283 }
284 }
285
286 @Override
287 public int getDeviceCount() {
288 return 0;
289 }
290
291 @Override
292 public Iterable<Device> getDevices() {
293 return devices;
294 }
295
296 @Override
297 public Device getDevice(DeviceId deviceId) {
298 return null;
299 }
300
301 @Override
302 public MastershipRole getRole(DeviceId deviceId) {
303 return null;
304 }
305
306 @Override
307 public List<Port> getPorts(DeviceId deviceId) {
308 List<Port> ports = Lists.newArrayList();
309 for (Port p : devicePorts.get(deviceId)) {
310 ports.add(p);
311 }
312 return ports;
313 }
314
315 @Override
316 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
317 return null;
318 }
319
320 @Override
321 public boolean isAvailable(DeviceId deviceId) {
322 return false;
323 }
324
325 @Override
326 public void addListener(DeviceListener listener) {
327 }
328
329 @Override
330 public void removeListener(DeviceListener listener) {
331 }
332 }
333}