Ray Milkey
Committed by Gerrit Code Review

Unit tests for the OpenFlow controller class

Change-Id: I14a6e2810ec15edfccb309ab94dabe96670f4026
......@@ -94,7 +94,7 @@ public class Controller {
protected String tsLocation;
protected char[] ksPwd;
protected char[] tsPwd;
private SSLEngine serverSSLEngine;
protected SSLEngine serverSSLEngine;
// Perf. related configuration
protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow;
import java.util.Map;
import java.util.Set;
import org.onosproject.net.driver.Behaviour;
import org.onosproject.net.driver.Driver;
import org.onosproject.net.driver.DriverData;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
/**
* Created by ray on 11/4/15.
*/
public class DriverAdapter implements Driver {
@Override
public String name() {
return null;
}
@Override
public Driver parent() {
return null;
}
@Override
public String manufacturer() {
return null;
}
@Override
public String hwVersion() {
return null;
}
@Override
public String swVersion() {
return null;
}
@Override
public Set<Class<? extends Behaviour>> behaviours() {
return null;
}
@Override
public Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour) {
return null;
}
@Override
public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) {
return true;
}
@Override
public <T extends Behaviour> T createBehaviour(DriverData data, Class<T> behaviourClass) {
return null;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Behaviour> T createBehaviour(DriverHandler handler, Class<T> behaviourClass) {
if (behaviourClass == OpenFlowSwitchDriver.class) {
return (T) new OpenflowSwitchDriverAdapter();
}
return null;
}
@Override
public Map<String, String> properties() {
return null;
}
@Override
public Driver merge(Driver other) {
return null;
}
@Override
public Set<String> keys() {
return null;
}
@Override
public String value(String key) {
return null;
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow;
import java.util.Set;
import org.onosproject.net.DeviceId;
import org.onosproject.net.driver.Behaviour;
import org.onosproject.net.driver.Driver;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.driver.DriverService;
/**
* Created by ray on 11/4/15.
*/
public class DriverServiceAdapter implements DriverService {
@Override
public Set<Driver> getDrivers() {
return null;
}
@Override
public Set<Driver> getDrivers(Class<? extends Behaviour> withBehaviour) {
return null;
}
@Override
public Driver getDriver(String mfr, String hw, String sw) {
return null;
}
@Override
public Driver getDriver(DeviceId deviceId) {
return null;
}
@Override
public DriverHandler createHandler(DeviceId deviceId, String... credentials) {
return null;
}
@Override
public Driver getDriver(String driverName) {
return null;
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow;
import java.util.Set;
import org.jboss.netty.buffer.ChannelBuffer;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
import org.projectfloodlight.openflow.protocol.OFStatsType;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.OFVersion;
import com.google.common.hash.PrimitiveSink;
/**
* Created by ray on 11/4/15.
*/
public class OFDescStatsReplyAdapter implements OFDescStatsReply {
@Override
public OFVersion getVersion() {
return null;
}
@Override
public OFType getType() {
return null;
}
@Override
public long getXid() {
return 0;
}
@Override
public OFStatsType getStatsType() {
return null;
}
@Override
public Set<OFStatsReplyFlags> getFlags() {
return null;
}
@Override
public String getMfrDesc() {
return null;
}
@Override
public String getHwDesc() {
return null;
}
@Override
public String getSwDesc() {
return null;
}
@Override
public String getSerialNum() {
return null;
}
@Override
public String getDpDesc() {
return null;
}
@Override
public void writeTo(ChannelBuffer channelBuffer) {
}
@Override
public Builder createBuilder() {
return null;
}
@Override
public void putTo(PrimitiveSink sink) {
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow;
import java.util.List;
import org.jboss.netty.channel.Channel;
import org.onosproject.net.Device;
import org.onosproject.net.driver.DriverData;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.RoleState;
import org.onosproject.openflow.controller.driver.OpenFlowAgent;
import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
import org.onosproject.openflow.controller.driver.RoleHandler;
import org.onosproject.openflow.controller.driver.SwitchStateException;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFVersion;
/**
* Testing adapter for the OpenFlow switch driver class.
*/
public class OpenflowSwitchDriverAdapter implements OpenFlowSwitchDriver {
@Override
public void setAgent(OpenFlowAgent agent) {
}
@Override
public void setRoleHandler(RoleHandler roleHandler) {
}
@Override
public void reassertRole() {
}
@Override
public boolean handleRoleError(OFErrorMsg error) {
return false;
}
@Override
public void handleNiciraRole(OFMessage m) throws SwitchStateException {
}
@Override
public void handleRole(OFMessage m) throws SwitchStateException {
}
@Override
public boolean connectSwitch() {
return false;
}
@Override
public boolean activateMasterSwitch() {
return false;
}
@Override
public boolean activateEqualSwitch() {
return false;
}
@Override
public void transitionToEqualSwitch() {
}
@Override
public void transitionToMasterSwitch() {
}
@Override
public void removeConnectedSwitch() {
}
@Override
public void setPortDescReply(OFPortDescStatsReply portDescReply) {
}
@Override
public void setPortDescReplies(List<OFPortDescStatsReply> portDescReplies) {
}
@Override
public void setFeaturesReply(OFFeaturesReply featuresReply) {
}
@Override
public void setSwitchDescription(OFDescStatsReply desc) {
}
@Override
public int getNextTransactionId() {
return 0;
}
@Override
public void setOFVersion(OFVersion ofV) {
}
@Override
public void setTableFull(boolean full) {
}
@Override
public void setChannel(Channel channel) {
}
@Override
public void setConnected(boolean connected) {
}
@Override
public void init(Dpid dpid, OFDescStatsReply desc, OFVersion ofv) {
}
@Override
public Boolean supportNxRole() {
return true;
}
@Override
public void startDriverHandshake() {
}
@Override
public boolean isDriverHandshakeComplete() {
return false;
}
@Override
public void processDriverHandshakeMessage(OFMessage m) {
}
@Override
public void sendRoleRequest(OFMessage message) {
}
@Override
public void sendHandshakeMessage(OFMessage message) {
}
@Override
public DriverHandler handler() {
return null;
}
@Override
public void setHandler(DriverHandler handler) {
}
@Override
public DriverData data() {
return null;
}
@Override
public void setData(DriverData data) {
}
@Override
public void sendMsg(OFMessage msg) {
}
@Override
public void sendMsg(List<OFMessage> msgs) {
}
@Override
public void handleMessage(OFMessage fromSwitch) {
}
@Override
public void setRole(RoleState role) {
}
@Override
public RoleState getRole() {
return null;
}
@Override
public List<OFPortDesc> getPorts() {
return null;
}
@Override
public OFFactory factory() {
// return what-ever triggers requestPending = true
return OFFactories.getFactory(OFVersion.OF_10);
}
@Override
public String getStringId() {
return "100";
}
@Override
public long getId() {
return 0;
}
@Override
public String manufacturerDescription() {
return null;
}
@Override
public String datapathDescription() {
return null;
}
@Override
public String hardwareDescription() {
return null;
}
@Override
public String softwareDescription() {
return null;
}
@Override
public String serialNumber() {
return null;
}
@Override
public boolean isConnected() {
return false;
}
@Override
public void disconnectSwitch() {
}
@Override
public void returnRoleReply(RoleState requested, RoleState response) {
}
@Override
public Device.Type deviceType() {
return Device.Type.SWITCH;
}
@Override
public String channelId() {
return null;
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow.controller.impl;
import java.io.File;
import java.io.IOException;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Map;
import java.util.stream.IntStream;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestTools;
import org.onlab.util.ItemNotFoundException;
import org.onosproject.net.DeviceId;
import org.onosproject.net.driver.Driver;
import org.onosproject.openflow.DriverAdapter;
import org.onosproject.openflow.DriverServiceAdapter;
import org.onosproject.openflow.OFDescStatsReplyAdapter;
import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.io.Files;
import static com.google.common.io.ByteStreams.toByteArray;
import static com.google.common.io.Files.write;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
/**
* Unit tests for the OpenFlow controller class.
*/
public class ControllerTest {
Controller controller;
protected static final Logger log = LoggerFactory.getLogger(ControllerTest.class);
static final File TEST_DIR = Files.createTempDir();
/*
* Writes the necessary file for the tests in the temporary directory
*/
static File stageTestResource(String name) throws IOException {
File file = new File(TEST_DIR, name);
byte[] bytes = toByteArray(ControllerTest.class.getResourceAsStream(name));
write(bytes, file);
return file;
}
class MockDriverService extends DriverServiceAdapter {
static final int NO_SUCH_DRIVER_ID = 1;
static final int ITEM_NOT_FOUND_DRIVER_ID = 2;
static final int DRIVER_EXISTS_ID = 3;
static final String BASE_DRIVER_NAME = "of:000000000000000";
static final String NO_SUCH_DRIVER = BASE_DRIVER_NAME
+ NO_SUCH_DRIVER_ID;
static final String ITEM_NOT_FOUND_DRIVER = BASE_DRIVER_NAME
+ ITEM_NOT_FOUND_DRIVER_ID;
static final String DRIVER_EXISTS = BASE_DRIVER_NAME
+ DRIVER_EXISTS_ID;
@Override
public Driver getDriver(DeviceId deviceId) {
switch (deviceId.toString()) {
case NO_SUCH_DRIVER:
return null;
case ITEM_NOT_FOUND_DRIVER:
throw new ItemNotFoundException();
case DRIVER_EXISTS:
return new DriverAdapter();
default:
throw new AssertionError();
}
}
}
/**
* Creates and initializes a new controller.
*/
@Before
public void setUp() {
controller = new Controller();
Dictionary<String, String> properties = new Hashtable<>();
properties.put("openflowPorts",
Integer.toString(TestTools.findAvailablePort(0)));
controller.setConfigParams(properties);
}
/**
* Tests fetching a driver that does not exist.
*/
@Test
public void switchInstanceNotFoundTest() {
controller.start(null, new MockDriverService());
OpenFlowSwitchDriver driver =
controller.getOFSwitchInstance(MockDriverService.NO_SUCH_DRIVER_ID,
null,
null);
assertThat(driver, nullValue());
controller.stop();
}
/**
* Tests fetching a driver that throws an ItemNotFoundException.
*/
@Test
public void switchItemNotFoundTest() {
controller.start(null, new MockDriverService());
OFDescStatsReply stats =
new OFDescStatsReplyAdapter();
OpenFlowSwitchDriver driver =
controller.getOFSwitchInstance(MockDriverService.ITEM_NOT_FOUND_DRIVER_ID,
stats,
null);
assertThat(driver, nullValue());
controller.stop();
}
/**
* Tests fetching a driver that throws an ItemNotFoundException.
*/
@Test
public void driverExistsTest() {
controller.start(null, new MockDriverService());
OFDescStatsReply stats =
new OFDescStatsReplyAdapter();
OpenFlowSwitchDriver driver =
controller.getOFSwitchInstance(MockDriverService.DRIVER_EXISTS_ID,
stats,
null);
assertThat(driver, notNullValue());
controller.stop();
}
/**
* Tests configuring the controller.
*/
@Test
public void testConfiguration() {
Dictionary<String, String> properties = new Hashtable<>();
properties.put("openflowPorts", "1,2,3,4,5");
properties.put("workerThreads", "5");
controller.setConfigParams(properties);
IntStream.rangeClosed(1, 5)
.forEach(i -> assertThat(controller.openFlowPorts, hasItem(i)));
assertThat(controller.workerThreads, is(5));
}
/**
* Tests the SSL/TLS methods in the controller.
*/
@Test
public void testSsl() throws IOException {
File keystore = stageTestResource("ControllerTestKeystore.jks");
String keystoreName = keystore.getAbsolutePath();
System.setProperty("enableOFTLS", Boolean.toString(Boolean.TRUE));
System.setProperty("javax.net.ssl.keyStore", keystoreName);
System.setProperty("javax.net.ssl.trustStore", keystoreName);
System.setProperty("javax.net.ssl.keyStorePassword", "password");
System.setProperty("javax.net.ssl.trustStorePassword", "password");
Dictionary<String, String> properties = new Hashtable<>();
properties.put("openflowPorts",
Integer.toString(TestTools.findAvailablePort(0)));
properties.put("workerThreads", "0");
controller.setConfigParams(properties);
controller.start(null, new MockDriverService());
assertThat(controller.serverSSLEngine, notNullValue());
controller.stop();
boolean removed = keystore.delete();
if (!removed) {
log.warn("Could not remove temporary file");
}
}
/**
* Tests controll utility health methods.
*/
@Test
public void testHealth() {
Map<String, Long> memory = controller.getMemory();
assertThat(memory.size(), is(2));
assertThat(memory.get("total"), is(not(0)));
assertThat(memory.get("free"), is(not(0)));
long startTime = controller.getSystemStartTime();
assertThat(startTime, lessThan(System.currentTimeMillis()));
long upTime = controller.getSystemUptime();
assertThat(upTime, lessThan(30L * 1000));
}
}
......@@ -15,35 +15,21 @@
*/
package org.onosproject.openflow.controller.impl;
import org.jboss.netty.channel.Channel;
import java.io.IOException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.net.Device;
import org.onosproject.net.driver.DriverData;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.OpenflowSwitchDriverAdapter;
import org.onosproject.openflow.controller.RoleState;
import org.onosproject.openflow.controller.driver.OpenFlowAgent;
import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
import org.onosproject.openflow.controller.driver.RoleHandler;
import org.onosproject.openflow.controller.driver.RoleRecvStatus;
import org.onosproject.openflow.controller.driver.RoleReplyInfo;
import org.onosproject.openflow.controller.driver.SwitchStateException;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.types.U64;
import java.io.IOException;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.onosproject.openflow.controller.RoleState.MASTER;
import static org.onosproject.openflow.controller.RoleState.SLAVE;
......@@ -103,25 +89,12 @@ public class RoleManagerTest {
}
}
private class TestSwitchDriver implements OpenFlowSwitchDriver {
private class TestSwitchDriver extends OpenflowSwitchDriverAdapter {
RoleState failed = null;
RoleState current = null;
@Override
public void sendMsg(OFMessage msg) {
}
@Override
public void sendMsg(List<OFMessage> msgs) {
}
@Override
public void handleMessage(OFMessage fromSwitch) {
}
@Override
public void setRole(RoleState role) {
current = role;
}
......@@ -132,143 +105,6 @@ public class RoleManagerTest {
}
@Override
public List<OFPortDesc> getPorts() {
return null;
}
@Override
public OFFactory factory() {
// return what-ever triggers requestPending = true
return OFFactories.getFactory(OFVersion.OF_10);
}
@Override
public String getStringId() {
return "100";
}
@Override
public long getId() {
return 0;
}
@Override
public String manufacturerDescription() {
return null;
}
@Override
public String datapathDescription() {
return null;
}
@Override
public String hardwareDescription() {
return null;
}
@Override
public String softwareDescription() {
return null;
}
@Override
public String serialNumber() {
return null;
}
@Override
public void disconnectSwitch() {
}
@Override
public Device.Type deviceType() {
return Device.Type.SWITCH;
}
@Override
public void setAgent(OpenFlowAgent agent) {
}
@Override
public void setRoleHandler(RoleHandler roleHandler) {
}
@Override
public void reassertRole() {
}
@Override
public boolean handleRoleError(OFErrorMsg error) {
return false;
}
@Override
public void handleNiciraRole(OFMessage m) throws SwitchStateException {
}
@Override
public void handleRole(OFMessage m) throws SwitchStateException {
}
@Override
public void startDriverHandshake() {
}
@Override
public boolean isDriverHandshakeComplete() {
return false;
}
@Override
public void processDriverHandshakeMessage(OFMessage m) {
}
@Override
public void sendRoleRequest(OFMessage message) {
}
@Override
public void sendHandshakeMessage(OFMessage message) {
}
@Override
public boolean connectSwitch() {
return false;
}
@Override
public boolean activateMasterSwitch() {
return false;
}
@Override
public boolean activateEqualSwitch() {
return false;
}
@Override
public void transitionToEqualSwitch() {
}
@Override
public void transitionToMasterSwitch() {
}
@Override
public void removeConnectedSwitch() {
}
@Override
public void setPortDescReply(OFPortDescStatsReply portDescReply) {
}
@Override
public void setPortDescReplies(List<OFPortDescStatsReply> portDescReplies) {
}
@Override
public void setFeaturesReply(OFFeaturesReply featuresReply) {
}
......@@ -282,37 +118,6 @@ public class RoleManagerTest {
}
@Override
public Boolean supportNxRole() {
return true;
}
@Override
public void setOFVersion(OFVersion ofV) {
}
@Override
public void setTableFull(boolean full) {
}
@Override
public void setChannel(Channel channel) {
}
@Override
public void setConnected(boolean connected) {
}
@Override
public void init(Dpid dpid, OFDescStatsReply desc, OFVersion ofv) {
}
@Override
public boolean isConnected() {
return false;
}
@Override
public void returnRoleReply(RoleState requested, RoleState response) {
failed = requested;
}
......@@ -321,25 +126,5 @@ public class RoleManagerTest {
public String channelId() {
return "1.2.3.4:1";
}
@Override
public DriverHandler handler() {
return null;
}
@Override
public void setHandler(DriverHandler handler) {
}
@Override
public DriverData data() {
return null;
}
@Override
public void setData(DriverData data) {
}
}
}
......
......@@ -20,6 +20,7 @@ import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.List;
import java.util.Random;
......@@ -207,4 +208,20 @@ public final class TestTools {
}
}
/*
* Finds an available port that a test can bind to.
*/
public static int findAvailablePort(int defaultPort) {
try {
ServerSocket socket = new ServerSocket(0);
socket.setReuseAddress(true);
int port = socket.getLocalPort();
socket.close();
return port;
} catch (IOException ex) {
return defaultPort;
}
}
}
......