From 2b284d65090454410856e70298305a779495f031 Mon Sep 17 00:00:00 2001
From: Alex Reimers <alex@bigswitch.com>
Date: Wed, 8 Aug 2012 20:11:51 -0700
Subject: [PATCH] More FloodlightTestModuleLoader stuff.

---
 build.xml                                     |   1 +
 .../core/module/FloodlightModuleLoader.java   |  75 +++++++-
 .../learningswitch/LearningSwitch.java        |   2 +
 ...htcontroller.core.module.IFloodlightModule |   3 +
 .../resources/floodlightdefault.properties    |   3 +
 .../module/FloodlightTestModuleLoader.java    | 182 ++++++++++++++++++
 .../core/test/MockFloodlightProvider.java     |  22 ++-
 .../forwarding/ForwardingTest.java            |  28 ++-
 .../learningswitch/LearningSwitchTest.java    |  36 ++--
 .../test/FloodlightTestCase.java              |   6 +-
 10 files changed, 310 insertions(+), 48 deletions(-)
 create mode 100644 src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java

diff --git a/build.xml b/build.xml
index e985d6fbd..b810a7f7e 100644
--- a/build.xml
+++ b/build.xml
@@ -181,6 +181,7 @@
                     <exclude name="**/storage/tests/StorageTest.java"/>
                     <exclude name="**/test/Mock*"/>
                     <exclude name="**/core/test/**"/>
+                    <exclude name="**/core/module/**"/>
                 </fileset>
             </batchtest>
         </junit>
diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
index ec443e207..46a9b0e98 100644
--- a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
+++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
@@ -11,11 +11,13 @@ import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.Queue;
+import java.util.ServiceConfigurationError;
 import java.util.ServiceLoader;
 import java.util.Set;
 
@@ -75,9 +77,20 @@ public class FloodlightModuleLoader {
 	        ServiceLoader<IFloodlightModule> moduleLoader
 	            = ServiceLoader.load(IFloodlightModule.class, cl);
 	        // Iterate for each module, iterate through and add it's services
-	        for (IFloodlightModule m : moduleLoader) {
-	            if (logger.isTraceEnabled()) {
-	                logger.trace("Found module " + m.getClass().getName());
+	        Iterator<IFloodlightModule> moduleIter = moduleLoader.iterator();
+	        while (moduleIter.hasNext()) {
+	        	IFloodlightModule m = null;
+	        	try {
+	        		m = moduleIter.next();
+	        	} catch (ServiceConfigurationError sce) {
+	        		logger.debug("Could not find module");
+	        		//moduleIter.remove();
+	        		continue;
+	        	}
+	        //}
+	        //for (IFloodlightModule m : moduleLoader) {
+	            if (logger.isDebugEnabled()) {
+	                logger.debug("Found module " + m.getClass().getName());
 	            }
 
 	            // Set up moduleNameMap
@@ -100,7 +113,7 @@ public class FloodlightModuleLoader {
 	                    int dupInConf = 0;
 	                    for (IFloodlightModule cMod : mods) {
 	                        if (mList.contains(cMod.getClass().getCanonicalName()))
-	                            dupInConf++;
+	                            dupInConf += 1;
 	                    }
 	                    
 	                    if (dupInConf > 1) {
@@ -108,7 +121,7 @@ public class FloodlightModuleLoader {
                             for (IFloodlightModule mod : mods) {
                                 duplicateMods += mod.getClass().getCanonicalName() + ", ";
                             }
-	                        throw new FloodlightModuleException("ERROR! The configuraiton " +
+	                        throw new FloodlightModuleException("ERROR! The configuraiton" +
 	                                " file specifies more than one module that provides the service " +
 	                                s.getCanonicalName() +". Please specify only ONE of the " +
 	                                "following modules in the config file: " + duplicateMods);
@@ -164,12 +177,17 @@ public class FloodlightModuleLoader {
 	/**
 	 * Loads modules (and their dependencies) specified in the list
 	 * @param mList The array of fully qualified module names
+	 * @param ignoreList The list of Floodlight services NOT to 
+	 * load modules for. Used for unit testing.
 	 * @return The ModuleContext containing all the loaded modules
 	 * @throws FloodlightModuleException
 	 */
-	public IFloodlightModuleContext loadModulesFromList(Collection<String> configMods, Properties prop) 
-            throws FloodlightModuleException {
-        logger.trace("Starting module loader");
+	protected IFloodlightModuleContext loadModulesFromList(Collection<String> configMods, Properties prop, 
+			Collection<IFloodlightService> ignoreList) throws FloodlightModuleException {
+		logger.debug("Starting module loader");
+		if (logger.isDebugEnabled() && ignoreList != null)
+			logger.debug("Not loading module services " + ignoreList.toString());
+
         findAllModules(configMods);
         
         Collection<IFloodlightModule> moduleSet = new ArrayList<IFloodlightModule>();
@@ -192,6 +210,30 @@ public class FloodlightModuleLoader {
                 throw new FloodlightModuleException("Module " + 
                         moduleName + " not found");
             }
+            // If the module provies a service that is in the
+            // services ignorelist don't load it.
+            if ((ignoreList != null) && (module.getModuleServices() != null)) {
+            	for (IFloodlightService ifs : ignoreList) {
+            		for (Class<?> intsIgnore : ifs.getClass().getInterfaces()) {
+            			//System.out.println(intsIgnore.getName());
+        				// Check that the interface extends IFloodlightService
+        				//if (intsIgnore.isAssignableFrom(IFloodlightService.class)) {
+            			//System.out.println(module.getClass().getName());
+    					if (intsIgnore.isAssignableFrom(module.getClass())) {
+    						// We now ignore loading this module.
+    						logger.debug("Not loading module " + 
+    									 module.getClass().getCanonicalName() +
+    									 " because interface " +
+    									 intsIgnore.getCanonicalName() +
+    									 " is in the ignore list.");
+    						
+    						continue;
+    					}
+        				//}
+            		}
+            	}
+            }
+            
             // Add the module to be loaded
             addModule(moduleMap, moduleSet, module);
             // Add it's dep's to the queue
@@ -243,6 +285,18 @@ public class FloodlightModuleLoader {
         startupModules(moduleSet);
         
         return floodlightModuleContext;
+	}
+	
+	/**
+	 * Loads modules (and their dependencies) specified in the list.
+	 * @param configMods The collection of fully qualified module names to load.
+	 * @param prop The list of properties that are configuration options.
+	 * @return The ModuleContext containing all the loaded modules.
+	 * @throws FloodlightModuleException
+	 */
+	public IFloodlightModuleContext loadModulesFromList(Collection<String> configMods, Properties prop) 
+            throws FloodlightModuleException {
+		return loadModulesFromList(configMods, prop, null);
     }
 	
 	/**
@@ -320,8 +374,7 @@ public class FloodlightModuleLoader {
     protected void startupModules(Collection<IFloodlightModule> moduleSet) {
         for (IFloodlightModule m : moduleSet) {
             if (logger.isDebugEnabled()) {
-                logger.debug("Starting " + 
-                             m.getClass().getCanonicalName());
+                logger.debug("Starting " + m.getClass().getCanonicalName());
             }
             m.startUp(floodlightModuleContext);
         }
@@ -332,6 +385,8 @@ public class FloodlightModuleLoader {
      * @param prop The properties file to use
      */
     protected void parseConfigParameters(Properties prop) {
+    	if (prop == null) return;
+    	
         Enumeration<?> e = prop.propertyNames();
         while (e.hasMoreElements()) {
             String key = (String) e.nextElement();
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
index 08fe99305..005708d13 100644
--- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
+++ b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
@@ -436,6 +436,8 @@ public class LearningSwitch
             case ERROR:
                 log.info("received an error {} from switch {}", (OFError) msg, sw);
                 return Command.CONTINUE;
+            default:
+            	break;
         }
         log.error("received an unexpected message {} from switch {}", msg, sw);
         return Command.CONTINUE;
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index 20b677aef..21436e568 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -19,3 +19,6 @@ net.floodlightcontroller.threadpool.ThreadPool
 net.floodlightcontroller.ui.web.StaticWebRoutable
 net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter
 net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier
+net.floodlightcontroller.devicemanager.test.MockDeviceManager
+net.floodlightcontroller.core.test.MockFloodlightProvider
+net.floodlightcontroller.core.test.MockThreadPoolService
diff --git a/src/main/resources/floodlightdefault.properties b/src/main/resources/floodlightdefault.properties
index 27b2795b3..9bcf7fd2a 100644
--- a/src/main/resources/floodlightdefault.properties
+++ b/src/main/resources/floodlightdefault.properties
@@ -1,4 +1,7 @@
 floodlight.modules = net.floodlightcontroller.storage.memory.MemoryStorageSource,\
+net.floodlightcontroller.core.FloodlightProvider,\
+net.floodlightcontroller.threadpool.ThreadPool,\
+net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl,\
 net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher,\
 net.floodlightcontroller.forwarding.Forwarding,\
 net.floodlightcontroller.jython.JythonDebugInterface,\
diff --git a/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java b/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java
new file mode 100644
index 000000000..2ba838e51
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/core/module/FloodlightTestModuleLoader.java
@@ -0,0 +1,182 @@
+package net.floodlightcontroller.core.module;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.floodlightcontroller.core.module.FloodlightModuleLoader;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.test.MockFloodlightProvider;
+import net.floodlightcontroller.core.test.MockThreadPoolService;
+import net.floodlightcontroller.counter.NullCounterStore;
+import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
+import net.floodlightcontroller.devicemanager.test.MockDeviceManager;
+import net.floodlightcontroller.perfmon.NullPktInProcessingTime;
+import net.floodlightcontroller.storage.memory.MemoryStorageSource;
+import net.floodlightcontroller.topology.TopologyManager;
+
+public class FloodlightTestModuleLoader extends FloodlightModuleLoader {
+	protected static Logger log = LoggerFactory.getLogger(FloodlightTestModuleLoader.class);
+	
+	// List of default modules to use unless specified otherwise
+	public static final Class<? extends IFloodlightModule> DEFAULT_STORAGE_SOURCE =
+			MemoryStorageSource.class;
+	public static final Class<? extends IFloodlightModule> DEFAULT_FLOODLIGHT_PRPOVIDER =
+			MockFloodlightProvider.class;
+	public static final Class<? extends IFloodlightModule> DEFAULT_TOPOLOGY_PROVIDER =
+			TopologyManager.class;
+	public static final Class<? extends IFloodlightModule> DEFAULT_DEVICE_SERVICE =
+			MockDeviceManager.class;
+	public static final Class<? extends IFloodlightModule> DEFAULT_COUNTER_STORE =
+			NullCounterStore.class;
+	public static final Class<? extends IFloodlightModule> DEFAULT_THREADPOOL =
+			MockThreadPoolService.class;
+	public static final Class<? extends IFloodlightModule> DEFAULT_ENTITY_CLASSIFIER =
+			DefaultEntityClassifier.class;
+	public static final Class<? extends IFloodlightModule> DEFAULT_PERFMON =
+			NullPktInProcessingTime.class;
+	
+	protected static final Collection<Class<? extends IFloodlightModule>> DEFAULT_MODULE_LIST;
+	
+	static {
+		DEFAULT_MODULE_LIST = new ArrayList<Class<? extends IFloodlightModule>>();
+		DEFAULT_MODULE_LIST.add(DEFAULT_DEVICE_SERVICE);
+		DEFAULT_MODULE_LIST.add(DEFAULT_FLOODLIGHT_PRPOVIDER);
+		DEFAULT_MODULE_LIST.add(DEFAULT_STORAGE_SOURCE);
+		DEFAULT_MODULE_LIST.add(DEFAULT_TOPOLOGY_PROVIDER);
+		DEFAULT_MODULE_LIST.add(DEFAULT_COUNTER_STORE);
+		DEFAULT_MODULE_LIST.add(DEFAULT_THREADPOOL);
+		DEFAULT_MODULE_LIST.add(DEFAULT_ENTITY_CLASSIFIER);
+		DEFAULT_MODULE_LIST.add(DEFAULT_PERFMON);
+	}
+	
+	protected IFloodlightModuleContext fmc;
+	
+	/**
+	 * Adds default modules to the list of modules to load. This is done
+	 * in order to avoid the module loader throwing errors about duplicate
+	 * modules and neither one is specified by the user.
+	 * @param userModules The list of user specified modules to add to.
+	 */
+	protected void addDefaultModules(Collection<Class<? extends IFloodlightModule>> userModules) {
+		Collection<Class<? extends IFloodlightModule>> defaultModules =
+				new ArrayList<Class<? extends IFloodlightModule>>(DEFAULT_MODULE_LIST.size());
+		defaultModules.addAll(DEFAULT_MODULE_LIST);
+		
+		Iterator<Class<? extends IFloodlightModule>> modIter = userModules.iterator();
+		while (modIter.hasNext()) {
+			Class<? extends IFloodlightModule> userMod = modIter.next();
+			Iterator<Class<? extends IFloodlightModule>> dmIter = defaultModules.iterator();
+			while (dmIter.hasNext()) {
+				Class<? extends IFloodlightModule> dmMod = dmIter.next();
+				Collection<Class<? extends IFloodlightService>> userModServs;
+				Collection<Class<? extends IFloodlightService>> dmModServs;
+				try {
+					dmModServs = dmMod.newInstance().getModuleServices();
+					userModServs = userMod.newInstance().getModuleServices();
+				} catch (InstantiationException e) {
+					log.error(e.getMessage());
+					break;
+				} catch (IllegalAccessException e) {
+					log.error(e.getMessage());
+					break;
+				}
+				
+				// If either of these are null continue as they have no services
+				if (dmModServs == null || userModServs == null) continue;
+				
+				// If the user supplied modules has a service
+				// that is in the default module list we remove
+				// the default module from the list.
+				boolean shouldBreak = false;
+				Iterator<Class<? extends IFloodlightService>> userModServsIter 
+					= userModServs.iterator();
+				while (userModServsIter.hasNext()) {
+					Class<? extends IFloodlightService> userModServIntf = userModServsIter.next();
+					Iterator<Class<? extends IFloodlightService>> dmModsServsIter 
+						= dmModServs.iterator();
+					while (dmModsServsIter.hasNext()) {
+						Class<? extends IFloodlightService> dmModServIntf 
+							= dmModsServsIter.next();
+						
+						if (dmModServIntf.getCanonicalName().equals(
+								userModServIntf.getCanonicalName())) {
+							logger.debug("Removing default module {} because it was " +
+									"overriden by an explicitly specified module",
+									dmModServIntf.getCanonicalName());
+							dmIter.remove();
+							shouldBreak = true;
+							break;
+						}
+					}
+					if (shouldBreak) break;
+				}
+				if (shouldBreak) break;
+			}
+		}
+		
+		// Append the remaining default modules to the user specified ones.
+		// This avoids the module loader throwing duplicate module errors.
+		userModules.addAll(defaultModules);
+		log.debug("Using module set " + userModules.toString());
+	}
+	
+	/**
+	 * Sets up all modules and their dependencies.
+	 * @param modules The list of modules that the user wants to load.
+	 * @param mockedServices The list of services that will be mocked. Any
+	 * module that provides this service will not be loaded.
+	 */
+	public void setupModules(Collection<Class<? extends IFloodlightModule>> modules,
+			Collection<IFloodlightService> mockedServices) {
+		addDefaultModules(modules);
+		Collection<String> modulesAsString = new ArrayList<String>();
+		for (Class<? extends IFloodlightModule> m : modules) {
+			modulesAsString.add(m.getCanonicalName());
+		}
+		
+		try {
+			fmc = loadModulesFromList(modulesAsString, null, mockedServices);
+		} catch (FloodlightModuleException e) {
+			log.error(e.getMessage());
+		}
+	}
+	
+	/**
+	 * Gets the inited/started instance of a module from the context.
+	 * @param ifl The name if the module to get, i.e. "LearningSwitch.class".
+	 * @return The inited/started instance of the module.
+	 */
+	public IFloodlightModule getModuleByName(Class<? extends IFloodlightModule> ifl) {
+		Collection<IFloodlightModule> modules = fmc.getAllModules();
+		for (IFloodlightModule m : modules) {
+			if (ifl.getCanonicalName().equals(m.getClass().getCanonicalName())) {
+				return m;
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * Gets an inited/started instance of a service from the context.
+	 * @param ifs The name of the service to get, i.e. "ITopologyService.class".
+	 * @return The inited/started instance of the service from teh context.
+	 */
+	public IFloodlightService getModuleByService(Class<? extends IFloodlightService> ifs) {
+		Collection<IFloodlightModule> modules = fmc.getAllModules();
+		for (IFloodlightModule m : modules) {
+			Collection<Class<? extends IFloodlightService>> mServs = m.getModuleServices();
+			if (mServs == null) continue;
+			for (Class<? extends IFloodlightService> mServClass : mServs) {
+				if (mServClass.getCanonicalName().equals(ifs.getCanonicalName())) {
+					assert(m instanceof IFloodlightService);
+					return (IFloodlightService)m;
+				}
+			}
+		}
+		return null;
+	}
+}
diff --git a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
index 577e5ded5..3daa04f52 100644
--- a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
+++ b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
@@ -19,6 +19,7 @@ package net.floodlightcontroller.core.test;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -199,28 +200,31 @@ public class MockFloodlightProvider implements IFloodlightModule, IFloodlightPro
 
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        // TODO Auto-generated method stub
-        return null;
+    	Collection<Class<? extends IFloodlightService>> services =
+                new ArrayList<Class<? extends IFloodlightService>>(1);
+        services.add(IFloodlightProviderService.class);
+        return services;
     }
 
     @Override
     public Map<Class<? extends IFloodlightService>, IFloodlightService>
             getServiceImpls() {
-        // TODO Auto-generated method stub
-        return null;
+    	Map<Class<? extends IFloodlightService>,
+        	IFloodlightService> m = 
+            	new HashMap<Class<? extends IFloodlightService>,
+                        IFloodlightService>();
+    	m.put(IFloodlightProviderService.class, this);
+    	return m;
     }
 
     @Override
     public Collection<Class<? extends IFloodlightService>>
             getModuleDependencies() {
-        // TODO Auto-generated method stub
-        return null;
+    	return null;
     }
     
     @Override
-    public
-            void
-            init(FloodlightModuleContext context)
+    public void init(FloodlightModuleContext context)
                                                  throws FloodlightModuleException {
         // TODO Auto-generated method stub
         
diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
index 2f952254c..9da4359cf 100644
--- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
+++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
@@ -97,10 +97,30 @@ public class ForwardingTest extends FloodlightTestCase {
     public void setUp() throws Exception {
         super.setUp();
 
-        // Mock context
         cntx = new FloodlightContext();
+        
+        // Module loader setup
+        /*
+        Collection<Class<? extends IFloodlightModule>> mods = new ArrayList<Class<? extends IFloodlightModule>>();
+        Collection<IFloodlightService> mockedServices = new ArrayList<IFloodlightService>();
+        mods.add(Forwarding.class);
+        routingEngine = createMock(IRoutingService.class);
+        topology = createMock(ITopologyService.class);
+        mockedServices.add(routingEngine);
+        mockedServices.add(topology);
+        FloodlightTestModuleLoader fml = new FloodlightTestModuleLoader();
+        fml.setupModules(mods, mockedServices);
+        mockFloodlightProvider =
+        		(MockFloodlightProvider) fml.getModuleByName(MockFloodlightProvider.class);
+        deviceManager =
+        		(MockDeviceManager) fml.getModuleByName(MockDeviceManager.class);
+        threadPool =
+        		(MockThreadPoolService) fml.getModuleByName(MockThreadPoolService.class);
+        forwarding =
+        		(Forwarding) fml.getModuleByName(Forwarding.class);
+        */
         mockFloodlightProvider = getMockFloodlightProvider();
-        forwarding = getForwarding();
+        forwarding = new Forwarding();
         threadPool = new MockThreadPoolService();
         deviceManager = new MockDeviceManager();
         flowReconcileMgr = new FlowReconcileManager();
@@ -251,10 +271,6 @@ public class ForwardingTest extends FloodlightTestCase {
                 srcDevice);
     }
 
-    private Forwarding getForwarding() {
-        return new Forwarding();
-    }
-
     @Test
     public void testForwardMultiSwitchPath() throws Exception {
         
diff --git a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
index 0272de2da..a68a1b873 100644
--- a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
+++ b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
@@ -22,21 +22,20 @@ import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 
-import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.counter.CounterStore;
-import net.floodlightcontroller.counter.ICounterStoreService;
+import net.floodlightcontroller.core.module.FloodlightTestModuleLoader;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.test.MockFloodlightProvider;
 import net.floodlightcontroller.packet.Data;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPacket;
 import net.floodlightcontroller.packet.IPv4;
 import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.restserver.RestApiServer;
 import net.floodlightcontroller.test.FloodlightTestCase;
 
 import org.junit.Before;
@@ -69,18 +68,15 @@ public class LearningSwitchTest extends FloodlightTestCase {
     @Before
     public void setUp() throws Exception {
         super.setUp();
-
-        FloodlightModuleContext fmc = new FloodlightModuleContext();
-        fmc.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
-        fmc.addService(ICounterStoreService.class, new CounterStore());
-        RestApiServer restApi = new RestApiServer();
-        fmc.addService(IRestApiService.class, restApi);
-        restApi.init(fmc);
-        restApi.startUp(fmc);
-        learningSwitch = new LearningSwitch();
-        learningSwitch.init(fmc);
-        learningSwitch.startUp(fmc);
-        
+        FloodlightTestModuleLoader fml = new FloodlightTestModuleLoader();
+        Collection<Class<? extends IFloodlightModule>> mods 
+        	= new ArrayList<Class<? extends IFloodlightModule>>();
+        mods.add(LearningSwitch.class);
+        fml.setupModules(mods, null);
+        learningSwitch = (LearningSwitch) fml.getModuleByName(LearningSwitch.class);
+        mockFloodlightProvider = 
+        		(MockFloodlightProvider) fml.getModuleByName(MockFloodlightProvider.class);
+       
         // Build our test packet
         this.testPacket = new Ethernet()
             .setDestinationMACAddress("00:11:22:33:44:55")
@@ -153,7 +149,7 @@ public class LearningSwitchTest extends FloodlightTestCase {
 
         // Mock up our expected behavior
         IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        expect(mockSwitch.getStringId()).andReturn("00:11:22:33:44:55:66:77");
+        expect(mockSwitch.getStringId()).andReturn("00:11:22:33:44:55:66:77").anyTimes();
         mockSwitch.write(po, null);
 
         // Start recording the replay on the mocks
@@ -161,6 +157,7 @@ public class LearningSwitchTest extends FloodlightTestCase {
         // Get the listener and trigger the packet in
         IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
                 OFType.PACKET_IN).get(0);
+        // Make sure it's the right listener
         listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn));
 
         // Verify the replay matched our expectations      
@@ -214,7 +211,6 @@ public class LearningSwitchTest extends FloodlightTestCase {
         expect(mockSwitch.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((Integer) (OFMatch.OFPFW_IN_PORT | OFMatch.OFPFW_NW_PROTO
                 | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST | OFMatch.OFPFW_NW_SRC_ALL
                 | OFMatch.OFPFW_NW_DST_ALL | OFMatch.OFPFW_NW_TOS));
-        expect(mockSwitch.getStringId()).andReturn("00:11:22:33:44:55:66:77").anyTimes();
         mockSwitch.write(fm1, null);
         mockSwitch.write(fm2, null);
 
diff --git a/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java b/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java
index 550cd1f52..b0e83cc11 100644
--- a/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java
+++ b/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java
@@ -87,9 +87,9 @@ public class FloodlightTestCase extends TestCase {
     public void setUp() throws Exception {
         mockFloodlightProvider = new MockFloodlightProvider();
     }
-
+    
     @Test
-    public void testSanity() {
-        assertTrue(true);
+    public void testSanity() throws Exception {
+    	assertTrue(true);
     }
 }
-- 
GitLab