blob: 679a888eebb54168c68b8791f437bbd57f3fe7f6 [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 Hartb4758a92014-09-24 10:46:45 -070022import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080023import org.onlab.packet.ARP;
24import org.onlab.packet.Ethernet;
25import org.onlab.packet.IpAddress;
26import org.onlab.packet.IpPrefix;
27import org.onlab.packet.MacAddress;
Jonathan Hart6cd2f352015-01-13 17:44:45 -080028import org.onlab.packet.VlanId;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.net.ConnectPoint;
30import org.onosproject.net.Device;
31import org.onosproject.net.DeviceId;
32import org.onosproject.net.Host;
33import org.onosproject.net.MastershipRole;
34import org.onosproject.net.Port;
35import org.onosproject.net.PortNumber;
36import org.onosproject.net.device.DeviceListener;
37import org.onosproject.net.device.DeviceServiceAdapter;
38import org.onosproject.net.flow.instructions.Instruction;
39import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
40import org.onosproject.net.host.HostProvider;
41import org.onosproject.net.host.InterfaceIpAddress;
42import org.onosproject.net.host.PortAddresses;
43import org.onosproject.net.packet.OutboundPacket;
Thomas Vachuska27bee092015-06-23 19:03:10 -070044import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080045import org.onosproject.net.provider.ProviderId;
Jonathan Hartb4758a92014-09-24 10:46:45 -070046
Thomas Vachuska27bee092015-06-23 19:03:10 -070047import java.util.ArrayList;
48import java.util.Collections;
49import java.util.List;
50import java.util.Set;
51
52import static org.easymock.EasyMock.*;
53import static org.junit.Assert.*;
Jonathan Hartb4758a92014-09-24 10:46:45 -070054
55public class HostMonitorTest {
56
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070057 private static final IpAddress TARGET_IP_ADDR =
Thomas Vachuska27bee092015-06-23 19:03:10 -070058 IpAddress.valueOf("10.0.0.1");
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -070059 private static final IpAddress SOURCE_ADDR =
Thomas Vachuska27bee092015-06-23 19:03:10 -070060 IpAddress.valueOf("10.0.0.99");
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -070061 private static final InterfaceIpAddress IA1 =
Thomas Vachuska27bee092015-06-23 19:03:10 -070062 new InterfaceIpAddress(SOURCE_ADDR, IpPrefix.valueOf("10.0.0.0/24"));
Jonathan Hartb4758a92014-09-24 10:46:45 -070063 private MacAddress sourceMac = MacAddress.valueOf(1L);
64
65 private HostMonitor hostMonitor;
66
Jonathan Hartdc09a3b2014-10-27 11:34:26 -070067 @After
68 public void shutdown() {
69 hostMonitor.shutdown();
70 }
71
Jonathan Hartb4758a92014-09-24 10:46:45 -070072 @Test
73 public void testMonitorHostExists() throws Exception {
74 ProviderId id = new ProviderId("fake://", "id");
75
76 Host host = createMock(Host.class);
77 expect(host.providerId()).andReturn(id);
78 replay(host);
79
80 HostManager hostManager = createMock(HostManager.class);
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070081 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
Jonathan Hartb4758a92014-09-24 10:46:45 -070082 .andReturn(Collections.singleton(host));
83 replay(hostManager);
84
85 HostProvider hostProvider = createMock(HostProvider.class);
86 expect(hostProvider.id()).andReturn(id).anyTimes();
87 hostProvider.triggerProbe(host);
88 expectLastCall().once();
89 replay(hostProvider);
90
91 hostMonitor = new HostMonitor(null, null, hostManager);
92
93 hostMonitor.registerHostProvider(hostProvider);
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070094 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
Jonathan Hartb4758a92014-09-24 10:46:45 -070095
96 hostMonitor.run(null);
97
98 verify(hostProvider);
99 }
100
101 @Test
Jonathan Hartb4758a92014-09-24 10:46:45 -0700102 public void testMonitorHostDoesNotExist() throws Exception {
Jonathan Hartdc09a3b2014-10-27 11:34:26 -0700103
Jonathan Hartb4758a92014-09-24 10:46:45 -0700104 HostManager hostManager = createMock(HostManager.class);
105
106 DeviceId devId = DeviceId.deviceId("fake");
107
108 Device device = createMock(Device.class);
109 expect(device.id()).andReturn(devId).anyTimes();
110 replay(device);
111
112 PortNumber portNum = PortNumber.portNumber(1L);
113
114 Port port = createMock(Port.class);
115 expect(port.number()).andReturn(portNum).anyTimes();
116 replay(port);
117
118 TestDeviceService deviceService = new TestDeviceService();
119 deviceService.addDevice(device, Collections.singleton(port));
120
121 ConnectPoint cp = new ConnectPoint(devId, portNum);
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700122 PortAddresses pa =
Thomas Vachuska27bee092015-06-23 19:03:10 -0700123 new PortAddresses(cp, Collections.singleton(IA1), sourceMac, VlanId.NONE);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700124
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700125 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
Jonathan Hartb4758a92014-09-24 10:46:45 -0700126 .andReturn(Collections.<Host>emptySet()).anyTimes();
127 expect(hostManager.getAddressBindingsForPort(cp))
Jonathan Harta887ba82014-11-03 15:20:52 -0800128 .andReturn(Collections.singleton(pa)).anyTimes();
Jonathan Hartb4758a92014-09-24 10:46:45 -0700129 replay(hostManager);
130
131 TestPacketService packetService = new TestPacketService();
132
133
134 // Run the test
135 hostMonitor = new HostMonitor(deviceService, packetService, hostManager);
136
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700137 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700138 hostMonitor.run(null);
139
140
141 // Check that a packet was sent to our PacketService and that it has
142 // the properties we expect
Jonathan Hartdc09a3b2014-10-27 11:34:26 -0700143 assertEquals(1, packetService.packets.size());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700144 OutboundPacket packet = packetService.packets.get(0);
145
146 // Check the output port is correct
Ray Milkey42507352015-03-20 15:16:10 -0700147 assertEquals(1, packet.treatment().immediate().size());
148 Instruction instruction = packet.treatment().immediate().get(0);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700149 assertTrue(instruction instanceof OutputInstruction);
150 OutputInstruction oi = (OutputInstruction) instruction;
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800151 assertEquals(portNum, oi.port());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700152
153 // Check the output packet is correct (well the important bits anyway)
154 Ethernet eth = new Ethernet();
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800155 final byte[] pktData = new byte[packet.data().remaining()];
156 packet.data().get(pktData);
157 eth.deserialize(pktData, 0, pktData.length);
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800158 assertEquals(Ethernet.VLAN_UNTAGGED, eth.getVlanID());
159 ARP arp = (ARP) eth.getPayload();
160 assertArrayEquals(SOURCE_ADDR.toOctets(),
161 arp.getSenderProtocolAddress());
162 assertArrayEquals(sourceMac.toBytes(),
163 arp.getSenderHardwareAddress());
164 assertArrayEquals(TARGET_IP_ADDR.toOctets(),
165 arp.getTargetProtocolAddress());
166 }
167
168 @Test
169 public void testMonitorHostDoesNotExistWithVlan() throws Exception {
170
171 HostManager hostManager = createMock(HostManager.class);
172
173 DeviceId devId = DeviceId.deviceId("fake");
174 short vlan = 5;
175
176 Device device = createMock(Device.class);
177 expect(device.id()).andReturn(devId).anyTimes();
178 replay(device);
179
180 PortNumber portNum = PortNumber.portNumber(1L);
181
182 Port port = createMock(Port.class);
183 expect(port.number()).andReturn(portNum).anyTimes();
184 replay(port);
185
186 TestDeviceService deviceService = new TestDeviceService();
187 deviceService.addDevice(device, Collections.singleton(port));
188
189 ConnectPoint cp = new ConnectPoint(devId, portNum);
190 PortAddresses pa =
Thomas Vachuska27bee092015-06-23 19:03:10 -0700191 new PortAddresses(cp, Collections.singleton(IA1), sourceMac,
192 VlanId.vlanId(vlan));
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800193
194 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
195 .andReturn(Collections.<Host>emptySet()).anyTimes();
196 expect(hostManager.getAddressBindingsForPort(cp))
197 .andReturn(Collections.singleton(pa)).anyTimes();
198 replay(hostManager);
199
200 TestPacketService packetService = new TestPacketService();
201
202
203 // Run the test
204 hostMonitor = new HostMonitor(deviceService, packetService, hostManager);
205
206 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
207 hostMonitor.run(null);
208
209
210 // Check that a packet was sent to our PacketService and that it has
211 // the properties we expect
212 assertEquals(1, packetService.packets.size());
213 OutboundPacket packet = packetService.packets.get(0);
214
215 // Check the output port is correct
Ray Milkey42507352015-03-20 15:16:10 -0700216 assertEquals(1, packet.treatment().immediate().size());
217 Instruction instruction = packet.treatment().immediate().get(0);
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800218 assertTrue(instruction instanceof OutputInstruction);
219 OutputInstruction oi = (OutputInstruction) instruction;
220 assertEquals(portNum, oi.port());
221
222 // Check the output packet is correct (well the important bits anyway)
223 Ethernet eth = new Ethernet();
224 final byte[] pktData = new byte[packet.data().remaining()];
225 packet.data().get(pktData);
226 eth.deserialize(pktData, 0, pktData.length);
227 assertEquals(vlan, eth.getVlanID());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700228 ARP arp = (ARP) eth.getPayload();
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800229 assertArrayEquals(SOURCE_ADDR.toOctets(),
230 arp.getSenderProtocolAddress());
231 assertArrayEquals(sourceMac.toBytes(),
232 arp.getSenderHardwareAddress());
233 assertArrayEquals(TARGET_IP_ADDR.toOctets(),
234 arp.getTargetProtocolAddress());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700235 }
236
Thomas Vachuska27bee092015-06-23 19:03:10 -0700237 class TestPacketService extends PacketServiceAdapter {
Jonathan Hartb4758a92014-09-24 10:46:45 -0700238
239 List<OutboundPacket> packets = new ArrayList<>();
240
241 @Override
Jonathan Hartb4758a92014-09-24 10:46:45 -0700242 public void emit(OutboundPacket packet) {
243 packets.add(packet);
244 }
245 }
246
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800247 class TestDeviceService extends DeviceServiceAdapter {
Jonathan Hartb4758a92014-09-24 10:46:45 -0700248
249 List<Device> devices = Lists.newArrayList();
250 Multimap<DeviceId, Port> devicePorts = HashMultimap.create();
251
252 void addDevice(Device device, Set<Port> ports) {
253 devices.add(device);
254 for (Port p : ports) {
255 devicePorts.put(device.id(), p);
256 }
257 }
258
259 @Override
260 public int getDeviceCount() {
261 return 0;
262 }
263
264 @Override
265 public Iterable<Device> getDevices() {
266 return devices;
267 }
268
269 @Override
270 public Device getDevice(DeviceId deviceId) {
271 return null;
272 }
273
274 @Override
275 public MastershipRole getRole(DeviceId deviceId) {
276 return null;
277 }
278
279 @Override
280 public List<Port> getPorts(DeviceId deviceId) {
281 List<Port> ports = Lists.newArrayList();
282 for (Port p : devicePorts.get(deviceId)) {
283 ports.add(p);
284 }
285 return ports;
286 }
287
288 @Override
289 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
290 return null;
291 }
292
293 @Override
294 public boolean isAvailable(DeviceId deviceId) {
295 return false;
296 }
297
298 @Override
299 public void addListener(DeviceListener listener) {
300 }
301
302 @Override
303 public void removeListener(DeviceListener listener) {
304 }
305 }
306}