blob: 654cab1949bd917bfb30d0eb07f024a8d503d0db [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 */
Jonathan Hartb4758a92014-09-24 10:46:45 -070016package org.onlab.onos.net.host.impl;
17
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;
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -080023import static org.junit.Assert.*;
Jonathan Hartb4758a92014-09-24 10:46:45 -070024
25import java.util.ArrayList;
Jonathan Hartb4758a92014-09-24 10:46:45 -070026import java.util.Collections;
27import java.util.List;
28import java.util.Set;
29
Jonathan Hartdc09a3b2014-10-27 11:34:26 -070030import org.junit.After;
Jonathan Hartb4758a92014-09-24 10:46:45 -070031import org.junit.Test;
32import org.onlab.onos.net.ConnectPoint;
33import org.onlab.onos.net.Device;
34import org.onlab.onos.net.DeviceId;
35import org.onlab.onos.net.Host;
36import org.onlab.onos.net.MastershipRole;
37import org.onlab.onos.net.Port;
38import org.onlab.onos.net.PortNumber;
39import org.onlab.onos.net.device.DeviceListener;
40import org.onlab.onos.net.device.DeviceService;
41import org.onlab.onos.net.flow.instructions.Instruction;
42import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
43import org.onlab.onos.net.host.HostProvider;
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -070044import org.onlab.onos.net.host.InterfaceIpAddress;
Jonathan Hartb4758a92014-09-24 10:46:45 -070045import org.onlab.onos.net.host.PortAddresses;
46import org.onlab.onos.net.packet.OutboundPacket;
47import org.onlab.onos.net.packet.PacketProcessor;
48import org.onlab.onos.net.packet.PacketService;
49import org.onlab.onos.net.provider.ProviderId;
50import org.onlab.packet.ARP;
51import org.onlab.packet.Ethernet;
52import org.onlab.packet.IpAddress;
53import org.onlab.packet.IpPrefix;
54import org.onlab.packet.MacAddress;
55
56import com.google.common.collect.HashMultimap;
57import com.google.common.collect.Lists;
58import com.google.common.collect.Multimap;
59
60public class HostMonitorTest {
61
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070062 private static final IpAddress TARGET_IP_ADDR =
63 IpAddress.valueOf("10.0.0.1");
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -070064 private static final IpAddress SOURCE_ADDR =
65 IpAddress.valueOf("10.0.0.99");
66 private static final InterfaceIpAddress IA1 =
67 new InterfaceIpAddress(SOURCE_ADDR, IpPrefix.valueOf("10.0.0.0/24"));
Jonathan Hartb4758a92014-09-24 10:46:45 -070068 private MacAddress sourceMac = MacAddress.valueOf(1L);
69
70 private HostMonitor hostMonitor;
71
Jonathan Hartdc09a3b2014-10-27 11:34:26 -070072 @After
73 public void shutdown() {
74 hostMonitor.shutdown();
75 }
76
Jonathan Hartb4758a92014-09-24 10:46:45 -070077 @Test
78 public void testMonitorHostExists() throws Exception {
79 ProviderId id = new ProviderId("fake://", "id");
80
81 Host host = createMock(Host.class);
82 expect(host.providerId()).andReturn(id);
83 replay(host);
84
85 HostManager hostManager = createMock(HostManager.class);
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070086 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
Jonathan Hartb4758a92014-09-24 10:46:45 -070087 .andReturn(Collections.singleton(host));
88 replay(hostManager);
89
90 HostProvider hostProvider = createMock(HostProvider.class);
91 expect(hostProvider.id()).andReturn(id).anyTimes();
92 hostProvider.triggerProbe(host);
93 expectLastCall().once();
94 replay(hostProvider);
95
96 hostMonitor = new HostMonitor(null, null, hostManager);
97
98 hostMonitor.registerHostProvider(hostProvider);
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070099 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700100
101 hostMonitor.run(null);
102
103 verify(hostProvider);
104 }
105
106 @Test
Jonathan Hartb4758a92014-09-24 10:46:45 -0700107 public void testMonitorHostDoesNotExist() throws Exception {
Jonathan Hartdc09a3b2014-10-27 11:34:26 -0700108
Jonathan Hartb4758a92014-09-24 10:46:45 -0700109 HostManager hostManager = createMock(HostManager.class);
110
111 DeviceId devId = DeviceId.deviceId("fake");
112
113 Device device = createMock(Device.class);
114 expect(device.id()).andReturn(devId).anyTimes();
115 replay(device);
116
117 PortNumber portNum = PortNumber.portNumber(1L);
118
119 Port port = createMock(Port.class);
120 expect(port.number()).andReturn(portNum).anyTimes();
121 replay(port);
122
123 TestDeviceService deviceService = new TestDeviceService();
124 deviceService.addDevice(device, Collections.singleton(port));
125
126 ConnectPoint cp = new ConnectPoint(devId, portNum);
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700127 PortAddresses pa =
128 new PortAddresses(cp, Collections.singleton(IA1), sourceMac);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700129
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700130 expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
Jonathan Hartb4758a92014-09-24 10:46:45 -0700131 .andReturn(Collections.<Host>emptySet()).anyTimes();
132 expect(hostManager.getAddressBindingsForPort(cp))
133 .andReturn(pa).anyTimes();
134 replay(hostManager);
135
136 TestPacketService packetService = new TestPacketService();
137
138
139 // Run the test
140 hostMonitor = new HostMonitor(deviceService, packetService, hostManager);
141
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700142 hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700143 hostMonitor.run(null);
144
145
146 // Check that a packet was sent to our PacketService and that it has
147 // the properties we expect
Jonathan Hartdc09a3b2014-10-27 11:34:26 -0700148 assertEquals(1, packetService.packets.size());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700149 OutboundPacket packet = packetService.packets.get(0);
150
151 // Check the output port is correct
Jonathan Hartdc09a3b2014-10-27 11:34:26 -0700152 assertEquals(1, packet.treatment().instructions().size());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700153 Instruction instruction = packet.treatment().instructions().get(0);
154 assertTrue(instruction instanceof OutputInstruction);
155 OutputInstruction oi = (OutputInstruction) instruction;
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800156 assertEquals(portNum, oi.port());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700157
158 // Check the output packet is correct (well the important bits anyway)
159 Ethernet eth = new Ethernet();
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800160 final byte[] pktData = new byte[packet.data().remaining()];
161 packet.data().get(pktData);
162 eth.deserialize(pktData, 0, pktData.length);
Jonathan Hartb4758a92014-09-24 10:46:45 -0700163 ARP arp = (ARP) eth.getPayload();
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800164 assertArrayEquals(SOURCE_ADDR.toOctets(),
165 arp.getSenderProtocolAddress());
166 assertArrayEquals(sourceMac.toBytes(),
167 arp.getSenderHardwareAddress());
168 assertArrayEquals(TARGET_IP_ADDR.toOctets(),
169 arp.getTargetProtocolAddress());
Jonathan Hartb4758a92014-09-24 10:46:45 -0700170 }
171
172 class TestPacketService implements PacketService {
173
174 List<OutboundPacket> packets = new ArrayList<>();
175
176 @Override
177 public void addProcessor(PacketProcessor processor, int priority) {
178 }
179
180 @Override
181 public void removeProcessor(PacketProcessor processor) {
182 }
183
184 @Override
185 public void emit(OutboundPacket packet) {
186 packets.add(packet);
187 }
188 }
189
190 class TestDeviceService implements DeviceService {
191
192 List<Device> devices = Lists.newArrayList();
193 Multimap<DeviceId, Port> devicePorts = HashMultimap.create();
194
195 void addDevice(Device device, Set<Port> ports) {
196 devices.add(device);
197 for (Port p : ports) {
198 devicePorts.put(device.id(), p);
199 }
200 }
201
202 @Override
203 public int getDeviceCount() {
204 return 0;
205 }
206
207 @Override
208 public Iterable<Device> getDevices() {
209 return devices;
210 }
211
212 @Override
213 public Device getDevice(DeviceId deviceId) {
214 return null;
215 }
216
217 @Override
218 public MastershipRole getRole(DeviceId deviceId) {
219 return null;
220 }
221
222 @Override
223 public List<Port> getPorts(DeviceId deviceId) {
224 List<Port> ports = Lists.newArrayList();
225 for (Port p : devicePorts.get(deviceId)) {
226 ports.add(p);
227 }
228 return ports;
229 }
230
231 @Override
232 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
233 return null;
234 }
235
236 @Override
237 public boolean isAvailable(DeviceId deviceId) {
238 return false;
239 }
240
241 @Override
242 public void addListener(DeviceListener listener) {
243 }
244
245 @Override
246 public void removeListener(DeviceListener listener) {
247 }
248 }
249}