blob: 280a5eaa0bf39509e2cf7201b0a03ff2d011350c [file] [log] [blame]
samanwita palf28207b2015-09-04 10:41:56 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
samanwita palf28207b2015-09-04 10:41:56 -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 */
16package org.onosproject.dhcp.impl;
17
18import com.google.common.collect.ImmutableSet;
19import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
22import org.onlab.packet.DHCP;
23import org.onlab.packet.DHCPOption;
samanwita pal8969cbe2015-09-04 13:31:30 -070024import org.onlab.packet.DHCPPacketType;
samanwita palf28207b2015-09-04 10:41:56 -070025import org.onlab.packet.Ethernet;
26import org.onlab.packet.IPv4;
27import org.onlab.packet.Ip4Address;
samanwita palc40e5ed2015-09-24 11:01:51 -070028import org.onlab.packet.IpAddress;
samanwita palf28207b2015-09-04 10:41:56 -070029import org.onlab.packet.MacAddress;
30import org.onlab.packet.UDP;
31import org.onosproject.core.CoreServiceAdapter;
Thomas Vachuskaa1da42e2015-09-09 00:45:22 -070032import org.onosproject.dhcp.DhcpStore;
33import org.onosproject.dhcp.IpAssignment;
samanwita palf28207b2015-09-04 10:41:56 -070034import org.onosproject.net.Host;
35import org.onosproject.net.HostId;
Thomas Vachuska54dc3522015-09-09 00:11:45 -070036import org.onosproject.net.config.NetworkConfigRegistryAdapter;
samanwita palf28207b2015-09-04 10:41:56 -070037import org.onosproject.net.host.HostDescription;
38import org.onosproject.net.host.HostProvider;
39import org.onosproject.net.host.HostProviderRegistry;
40import org.onosproject.net.host.HostProviderService;
41import org.onosproject.net.packet.DefaultInboundPacket;
42import org.onosproject.net.packet.DefaultPacketContext;
43import org.onosproject.net.packet.InboundPacket;
44import org.onosproject.net.packet.OutboundPacket;
45import org.onosproject.net.packet.PacketContext;
46import org.onosproject.net.packet.PacketProcessor;
47import org.onosproject.net.packet.PacketServiceAdapter;
48import org.onosproject.net.provider.AbstractProvider;
49import org.onosproject.net.provider.AbstractProviderService;
50import org.onosproject.net.provider.ProviderId;
51
52import java.nio.ByteBuffer;
53import java.util.ArrayList;
Thomas Vachuska54dc3522015-09-09 00:11:45 -070054import java.util.Date;
samanwita palf28207b2015-09-04 10:41:56 -070055import java.util.HashMap;
56import java.util.List;
57import java.util.Map;
58import java.util.Set;
59
60import static org.junit.Assert.assertEquals;
61import static org.junit.Assert.fail;
62import static org.onosproject.net.NetTestTools.connectPoint;
63
64/**
65 * Set of tests of the ONOS application component.
66 */
67
Thomas Vachuskaa1da42e2015-09-09 00:45:22 -070068public class DhcpManagerTest {
samanwita palf28207b2015-09-04 10:41:56 -070069
Thomas Vachuskaa1da42e2015-09-09 00:45:22 -070070 private DhcpManager dhcpXManager;
samanwita palf28207b2015-09-04 10:41:56 -070071
72 protected PacketProcessor packetProcessor;
73
74 protected HostProviderService hostProviderService;
75
samanwita pal2a313402015-09-14 16:03:22 -070076 private static final HostId CLIENT1_HOST = HostId.hostId(MacAddress.valueOf("1a:1a:1a:1a:1a:1a"));
samanwita palf28207b2015-09-04 10:41:56 -070077
78 private static final String EXPECTED_IP = "10.2.0.2";
79
80 private static final Ip4Address BROADCAST = Ip4Address.valueOf("255.255.255.255");
81
82 private static final int TRANSACTION_ID = 1000;
83
84 private static final ProviderId PID = new ProviderId("of", "foo");
85
86 @Before
87 public void setUp() {
Thomas Vachuskaa1da42e2015-09-09 00:45:22 -070088 dhcpXManager = new DhcpManager();
89 dhcpXManager.cfgService = new TestNetworkConfigRegistry();
90 dhcpXManager.packetService = new TestPacketService();
91 dhcpXManager.coreService = new TestCoreService();
92 dhcpXManager.dhcpStore = new TestDhcpStore();
samanwita palf28207b2015-09-04 10:41:56 -070093 hostProviderService = new TestHostProviderService(new TestHostProvider());
Thomas Vachuskaa1da42e2015-09-09 00:45:22 -070094 dhcpXManager.hostProviderService = hostProviderService;
95 dhcpXManager.hostProviderRegistry = new TestHostRegistry();
96 dhcpXManager.activate();
samanwita palf28207b2015-09-04 10:41:56 -070097 }
98
99 @After
100 public void tearDown() {
Thomas Vachuskaa1da42e2015-09-09 00:45:22 -0700101 dhcpXManager.deactivate();
samanwita palf28207b2015-09-04 10:41:56 -0700102 }
103
104 /**
105 * Tests the response to a DHCP Discover Packet.
106 */
107 @Test
108 public void testDiscover() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800109 Ethernet reply = constructDhcpPacket(DHCPPacketType.DHCPDISCOVER);
samanwita palf28207b2015-09-04 10:41:56 -0700110 sendPacket(reply);
111 }
112
113 /**
114 * Tests the response to a DHCP Request Packet.
115 */
116 @Test
117 public void testRequest() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800118 Ethernet reply = constructDhcpPacket(DHCPPacketType.DHCPREQUEST);
samanwita palf28207b2015-09-04 10:41:56 -0700119 sendPacket(reply);
120 }
121
122 /**
123 * Sends an Ethernet packet to the process method of the Packet Processor.
124 * @param reply Ethernet packet
125 */
126 private void sendPacket(Ethernet reply) {
127 final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
128 InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
129 reply,
130 byteBuffer);
131
132 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
133 packetProcessor.process(context);
134 }
135
136 /**
137 * Constructs an Ethernet packet containing a DHCP Payload.
samanwita pal8969cbe2015-09-04 13:31:30 -0700138 * @param packetType DHCP Message Type
samanwita palf28207b2015-09-04 10:41:56 -0700139 * @return Ethernet packet
140 */
Jonathan Hartb35540a2015-11-17 09:30:56 -0800141 private Ethernet constructDhcpPacket(DHCPPacketType packetType) {
samanwita palf28207b2015-09-04 10:41:56 -0700142
143 // Ethernet Frame.
144 Ethernet ethReply = new Ethernet();
samanwita pal2a313402015-09-14 16:03:22 -0700145 ethReply.setSourceMACAddress(CLIENT1_HOST.mac());
samanwita palf28207b2015-09-04 10:41:56 -0700146 ethReply.setDestinationMACAddress(MacAddress.BROADCAST);
147 ethReply.setEtherType(Ethernet.TYPE_IPV4);
148 ethReply.setVlanID((short) 2);
149
150 // IP Packet
151 IPv4 ipv4Reply = new IPv4();
152 ipv4Reply.setSourceAddress(0);
153 ipv4Reply.setDestinationAddress(BROADCAST.toInt());
154 ipv4Reply.setTtl((byte) 127);
155
156 // UDP Datagram.
157 UDP udpReply = new UDP();
158 udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
159 udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
160
161 // DHCP Payload.
162 DHCP dhcpReply = new DHCP();
163 dhcpReply.setOpCode(DHCP.OPCODE_REQUEST);
164
165 dhcpReply.setYourIPAddress(0);
166 dhcpReply.setServerIPAddress(0);
167
168 dhcpReply.setTransactionId(TRANSACTION_ID);
samanwita pal2a313402015-09-14 16:03:22 -0700169 dhcpReply.setClientHardwareAddress(CLIENT1_HOST.mac().toBytes());
samanwita palf28207b2015-09-04 10:41:56 -0700170 dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
171 dhcpReply.setHardwareAddressLength((byte) 6);
172
173 // DHCP Options.
174 DHCPOption option = new DHCPOption();
175 List<DHCPOption> optionList = new ArrayList<>();
176
177 // DHCP Message Type.
178 option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
179 option.setLength((byte) 1);
samanwita pal8969cbe2015-09-04 13:31:30 -0700180 byte[] optionData = {(byte) packetType.getValue()};
samanwita palf28207b2015-09-04 10:41:56 -0700181 option.setData(optionData);
182 optionList.add(option);
183
184 // DHCP Requested IP.
185 option = new DHCPOption();
186 option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue());
187 option.setLength((byte) 4);
188 optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
189 option.setData(optionData);
190 optionList.add(option);
191
192 // End Option.
193 option = new DHCPOption();
194 option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
195 option.setLength((byte) 1);
196 optionList.add(option);
197
198 dhcpReply.setOptions(optionList);
199
200 udpReply.setPayload(dhcpReply);
201 ipv4Reply.setPayload(udpReply);
202 ethReply.setPayload(ipv4Reply);
203
204 return ethReply;
205 }
206
207 /**
208 * Validates the contents of the packet sent by the DHCP Manager.
209 * @param packet Ethernet packet received
210 */
211 private void validatePacket(Ethernet packet) {
212 DHCP dhcpPacket = (DHCP) packet.getPayload().getPayload().getPayload();
samanwita pal2a313402015-09-14 16:03:22 -0700213 assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT1_HOST.mac());
samanwita palf28207b2015-09-04 10:41:56 -0700214 assertEquals(Ip4Address.valueOf(dhcpPacket.getYourIPAddress()), Ip4Address.valueOf(EXPECTED_IP));
215 assertEquals(dhcpPacket.getTransactionId(), TRANSACTION_ID);
216 }
217
218 /**
219 * Mocks the DHCPStore.
220 */
Thomas Vachuskaa1da42e2015-09-09 00:45:22 -0700221 private final class TestDhcpStore implements DhcpStore {
samanwita palf28207b2015-09-04 10:41:56 -0700222
223
224 public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) {
225 }
226
samanwita pal2a313402015-09-14 16:03:22 -0700227 public Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP) {
samanwita palf28207b2015-09-04 10:41:56 -0700228 return Ip4Address.valueOf(EXPECTED_IP);
229 }
230
danielcd9deed2015-10-30 17:16:16 +0900231 public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack,
232 List<Ip4Address> addressList) {
samanwita palf28207b2015-09-04 10:41:56 -0700233 return true;
234 }
235
236 public void setDefaultTimeoutForPurge(int timeInSeconds) {
237 }
238
samanwita palc40e5ed2015-09-24 11:01:51 -0700239 public Ip4Address releaseIP(HostId hostId) {
240 return null;
samanwita palf28207b2015-09-04 10:41:56 -0700241 }
242
samanwita pal0bff4302015-09-15 13:37:00 -0700243 public Map<HostId, IpAssignment> listAssignedMapping() {
244 return listAllMapping();
245 }
246
247 public Map<HostId, IpAssignment> listAllMapping() {
samanwita pal2a313402015-09-14 16:03:22 -0700248 Map<HostId, IpAssignment> map = new HashMap<>();
Thomas Vachuskaa1da42e2015-09-09 00:45:22 -0700249 IpAssignment assignment = IpAssignment.builder()
Thomas Vachuska54dc3522015-09-09 00:11:45 -0700250 .ipAddress(Ip4Address.valueOf(EXPECTED_IP))
Thomas Vachuskaa1da42e2015-09-09 00:45:22 -0700251 .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned)
Thomas Vachuska54dc3522015-09-09 00:11:45 -0700252 .leasePeriod(300)
253 .timestamp(new Date())
254 .build();
samanwita pal2a313402015-09-14 16:03:22 -0700255 map.put(CLIENT1_HOST, assignment);
samanwita palf28207b2015-09-04 10:41:56 -0700256 return map;
257 }
258
danielcd9deed2015-10-30 17:16:16 +0900259 public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack,
260 List<Ip4Address> addressList) {
samanwita palf28207b2015-09-04 10:41:56 -0700261 return true;
262 }
263
264 public boolean removeStaticIP(MacAddress macID) {
265 return true;
266 }
267
268 public Iterable<Ip4Address> getAvailableIPs() {
269 List<Ip4Address> ipList = new ArrayList<>();
270 ipList.add(Ip4Address.valueOf(EXPECTED_IP));
271 return ImmutableSet.copyOf(ipList);
272 }
danielcd9deed2015-10-30 17:16:16 +0900273 public IpAssignment getIpAssignmentFromAllocationMap(HostId hostId) {
274 return null;
275 }
samanwita palf28207b2015-09-04 10:41:56 -0700276 }
277
278 /**
279 * Mocks the DefaultPacket context.
280 */
281 private final class TestPacketContext extends DefaultPacketContext {
282 private TestPacketContext(long time, InboundPacket inPkt,
283 OutboundPacket outPkt, boolean block) {
284 super(time, inPkt, outPkt, block);
285 }
286
287 @Override
288 public void send() {
289 // We don't send anything out.
290 }
291 }
292
293 /**
294 * Keeps a reference to the PacketProcessor and verifies the OutboundPackets.
295 */
296 private class TestPacketService extends PacketServiceAdapter {
297
298 @Override
299 public void addProcessor(PacketProcessor processor, int priority) {
300 packetProcessor = processor;
301 }
302
303 @Override
304 public void emit(OutboundPacket packet) {
305 try {
306 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
307 0, packet.data().array().length);
308 validatePacket(eth);
309 } catch (Exception e) {
310 fail(e.getMessage());
311 }
312 }
313 }
314
315 /**
316 * Mocks the CoreService.
317 */
318 private class TestCoreService extends CoreServiceAdapter {
319
320 }
321
322 /**
323 * Mocks the NetworkConfigRegistry.
324 */
325 private class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
326
327 }
328
329 /**
330 * Mocks the HostProviderService.
331 */
332 private class TestHostProviderService extends AbstractProviderService<HostProvider>
333 implements HostProviderService {
334
335 protected TestHostProviderService(HostProvider provider) {
336 super(provider);
337 }
338
339 @Override
Brian O'Connorf107bd72015-09-21 15:31:03 -0700340 public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
alshabibeff00542015-09-23 13:22:33 -0700341
samanwita palf28207b2015-09-04 10:41:56 -0700342 }
343
344 @Override
345 public void hostVanished(HostId hostId) {
346 }
347
samanwita palc40e5ed2015-09-24 11:01:51 -0700348 @Override
349 public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
350
351 }
352
samanwita palf28207b2015-09-04 10:41:56 -0700353 }
354
355 /**
356 * Mocks the HostProvider.
357 */
358 private static class TestHostProvider extends AbstractProvider
359 implements HostProvider {
360
361 protected TestHostProvider() {
362 super(PID);
363 }
364
365 @Override
366 public ProviderId id() {
367 return PID;
368 }
369
370 @Override
371 public void triggerProbe(Host host) {
372 }
373
374 }
375
376 /**
377 * Mocks the HostProviderRegistry.
378 */
379 private class TestHostRegistry implements HostProviderRegistry {
380
381 @Override
382 public HostProviderService register(HostProvider provider) {
383 return hostProviderService;
384 }
385
386 @Override
387 public void unregister(HostProvider provider) {
388 }
389
390 @Override
391 public Set<ProviderId> getProviders() {
392 return null;
393 }
394
395 }
396
397}