Unit tests for the OpenFlow controller class

Change-Id: I14a6e2810ec15edfccb309ab94dabe96670f4026
diff --git a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/ControllerTest.java b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/ControllerTest.java
new file mode 100644
index 0000000..3ff3bde
--- /dev/null
+++ b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/ControllerTest.java
@@ -0,0 +1,219 @@
+/*
+ * 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));
+    }
+}
diff --git a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
index 0a71a40..4b59438 100644
--- a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
+++ b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
@@ -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 @@
         }
     }
 
-    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 @@
         }
 
         @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 @@
         }
 
         @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 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) {
-
-        }
     }
 }