more unittest support

This commit is contained in:
Alex Huang 2011-02-25 11:57:52 -08:00
parent c06444c079
commit 378a0da0df
8 changed files with 225 additions and 84 deletions

View File

@ -589,6 +589,8 @@
<delete dir="${dist.dir}" />
<delete dir="${unittest.dir}"/>
</target>
<target name="compile-all" description="Compile all of the jars" depends="compile-utils, compile-api, compile-core, compile-server"/>
<target name="clean-all" depends="clean" description="Clean all of the generated files, including dependency cache and javadoc">
<delete dir="${target.dir}" />

View File

@ -214,7 +214,7 @@
<dirset dir="${base.dir}/setup/db"/>
</path>
<target name="compile-tests" depends="build-all">
<target name="compile-tests" depends="compile-all">
<mkdir dir="${unittest.dir}"/>
<mkdir dir="${unittest.target.dir}"/>
<mkdir dir="${unittest.jar.dir}"/>
@ -224,13 +224,17 @@
</target>
<target name="unittest" description="Execute unit tests" depends="compile-tests">
<junit fork="yes" printsummary="true" failureproperty="junit.failure">
<junit fork="true" printsummary="true" showoutput="true" failureproperty="junit.failure">
<!-- N.b. use failureproperty instead of haltonfailure, because if we use
the former, we will get no detailed report about the failure.
If the test fails, the fail element below will still assure that
the Ant run will exit with error status.
-->
<!--bootclasspath refid="test.classpath"/-->
<classpath refid="test.classpath"/>
<permissions>
<grant class="java.security.AllPermission"/>
</permissions>
<jvmarg value="${debug.jvmarg}"/>
<batchtest todir="${unittest.dir}">
<formatter type="plain"/>
@ -250,12 +254,13 @@
</target>
<target name="test" description="Execute one unit test" depends="compile-tests">
<junit fork="true" printsummary="true" failureproperty="junit.failure">
<junit fork="true" printsummary="true" clonevm="true" failureproperty="junit.failure">
<!-- N.b. use failureproperty instead of haltonfailure, because if we use
the former, we will get no detailed report about the failure.
If the test fails, the fail element below will still assure that
the Ant run will exit with error status.
-->
<bootclasspath refid="test.classpath"/>
<classpath refid="test.classpath"/>
<batchtest todir="${unittest.dir}">
<formatter type="plain"/>

View File

@ -18,9 +18,7 @@
package com.cloud.configuration;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -128,9 +126,9 @@ import com.cloud.user.dao.SSHKeyPairDaoImpl;
import com.cloud.user.dao.UserAccountDaoImpl;
import com.cloud.user.dao.UserDaoImpl;
import com.cloud.user.dao.UserStatisticsDaoImpl;
import com.cloud.utils.Pair;
import com.cloud.utils.component.Adapter;
import com.cloud.utils.component.ComponentLibrary;
import com.cloud.utils.component.ComponentLibraryBase;
import com.cloud.utils.component.ComponentLocator.ComponentInfo;
import com.cloud.utils.component.Manager;
import com.cloud.utils.db.GenericDao;
@ -148,21 +146,7 @@ import com.cloud.vm.dao.UserVmDaoImpl;
import com.cloud.vm.dao.UserVmDetailsDaoImpl;
import com.cloud.vm.dao.VMInstanceDaoImpl;
public class DefaultComponentLibrary implements ComponentLibrary {
protected final Map<String, ComponentInfo<GenericDao<?, ? extends Serializable>>> _daos = new LinkedHashMap<String, ComponentInfo<GenericDao<?, ? extends Serializable>>>();
protected ComponentInfo<? extends GenericDao<?, ? extends Serializable>> addDao(String name, Class<? extends GenericDao<?, ? extends Serializable>> clazz) {
return addDao(name, clazz, new ArrayList<Pair<String, Object>>(), true);
}
protected ComponentInfo<? extends GenericDao<?, ? extends Serializable>> addDao(String name, Class<? extends GenericDao<?, ? extends Serializable>> clazz, List<Pair<String, Object>> params, boolean singleton) {
ComponentInfo<GenericDao<?, ? extends Serializable>> componentInfo = new ComponentInfo<GenericDao<?, ? extends Serializable>>(name, clazz, params, singleton);
for (String key : componentInfo.getKeys()) {
_daos.put(key, componentInfo);
}
return componentInfo;
}
public class DefaultComponentLibrary extends ComponentLibraryBase implements ComponentLibrary {
protected void populateDaos() {
addDao("StackMaidDao", StackMaidDaoImpl.class);
@ -263,10 +247,7 @@ public class DefaultComponentLibrary implements ComponentLibrary {
addDao("OvsTunnelAccountDao", OvsTunnelAccountDaoImpl.class);
addDao("StoragePoolWorkDao", StoragePoolWorkDaoImpl.class);
}
Map<String, ComponentInfo<Manager>> _managers = new HashMap<String, ComponentInfo<Manager>>();
Map<String, List<ComponentInfo<Adapter>>> _adapters = new HashMap<String, List<ComponentInfo<Adapter>>>();
@Override
public synchronized Map<String, ComponentInfo<GenericDao<?, ?>>> getDaos() {
if (_daos.size() == 0) {
@ -275,18 +256,6 @@ public class DefaultComponentLibrary implements ComponentLibrary {
return _daos;
}
protected ComponentInfo<Manager> addManager(String name, Class<? extends Manager> clazz, List<Pair<String, Object>> params, boolean singleton) {
ComponentInfo<Manager> info = new ComponentInfo<Manager>(name, clazz, params, singleton);
for (String key : info.getKeys()) {
_managers.put(key, info);
}
return info;
}
protected ComponentInfo<Manager> addManager(String name, Class<? extends Manager> clazz) {
return addManager(name, clazz, new ArrayList<Pair<String, Object>>(), true);
}
protected void populateManagers() {
addManager("StackMaidManager", StackMaidManagerImpl.class);
addManager("agent manager", AgentManagerImpl.class);
@ -328,23 +297,6 @@ public class DefaultComponentLibrary implements ComponentLibrary {
info.addParameter("consoleproxy.sslEnabled", "true");
}
protected <T> List<ComponentInfo<Adapter>> addAdapterChain(Class<T> interphace, List<Pair<String, Class<? extends T>>> adapters) {
ArrayList<ComponentInfo<Adapter>> lst = new ArrayList<ComponentInfo<Adapter>>(adapters.size());
for (Pair<String, Class<? extends T>> adapter : adapters) {
@SuppressWarnings("unchecked")
Class<? extends Adapter> clazz = (Class<? extends Adapter>)adapter.second();
lst.add(new ComponentInfo<Adapter>(adapter.first(), clazz));
}
_adapters.put(interphace.getName(), lst);
return lst;
}
protected <T> void addOneAdapter(Class<T> interphace, String name, Class<? extends T> adapterClass) {
List<Pair<String, Class<? extends T>>> adapters = new ArrayList<Pair<String, Class<? extends T>>>();
adapters.add(new Pair<String, Class<? extends T>>(name, adapterClass));
addAdapterChain(interphace, adapters);
}
@Override
public synchronized Map<String, ComponentInfo<Manager>> getManagers() {
if (_managers.size() == 0) {
@ -370,5 +322,4 @@ public class DefaultComponentLibrary implements ComponentLibrary {
factories.put(EntityManager.class, EntityManagerImpl.class);
return factories;
}
}

View File

@ -42,9 +42,6 @@ import com.cloud.utils.db.Transaction;
public class VersionDaoImplTest extends TestCase {
private static final Logger s_logger = Logger.getLogger(VersionDaoImplTest.class);
/**
* @throws java.lang.Exception
*/
@Override
@Before
public void setUp() throws Exception {
@ -82,12 +79,7 @@ public class VersionDaoImplTest extends TestCase {
throw new RuntimeException("Unable to close DB connection", e);
}
}
/**
* @throws java.lang.Exception
*/
@Override
@After
public void tearDown() throws Exception {
@ -96,7 +88,7 @@ public class VersionDaoImplTest extends TestCase {
public void test217to22Upgrade() {
s_logger.debug("Finding sample data from 2.1.7");
executeScript("VersionDaoImplTest/2.1.7/2.1.7.sample.sql");
VersionDaoImpl dao = ComponentLocator.inject(VersionDaoImpl.class);
String version = dao.getCurrentVersion();

View File

@ -0,0 +1,77 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.utils.component;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentLocator.ComponentInfo;
import com.cloud.utils.db.GenericDao;
public abstract class ComponentLibraryBase implements ComponentLibrary {
protected final Map<String, ComponentInfo<GenericDao<?, ? extends Serializable>>> _daos = new LinkedHashMap<String, ComponentInfo<GenericDao<?, ? extends Serializable>>>();
protected ComponentInfo<? extends GenericDao<?, ? extends Serializable>> addDao(String name, Class<? extends GenericDao<?, ? extends Serializable>> clazz) {
return addDao(name, clazz, new ArrayList<Pair<String, Object>>(), true);
}
protected ComponentInfo<? extends GenericDao<?, ? extends Serializable>> addDao(String name, Class<? extends GenericDao<?, ? extends Serializable>> clazz, List<Pair<String, Object>> params, boolean singleton) {
ComponentInfo<GenericDao<?, ? extends Serializable>> componentInfo = new ComponentInfo<GenericDao<?, ? extends Serializable>>(name, clazz, params, singleton);
for (String key : componentInfo.getKeys()) {
_daos.put(key, componentInfo);
}
return componentInfo;
}
protected Map<String, ComponentInfo<Manager>> _managers = new LinkedHashMap<String, ComponentInfo<Manager>>();
protected Map<String, List<ComponentInfo<Adapter>>> _adapters = new LinkedHashMap<String, List<ComponentInfo<Adapter>>>();
protected ComponentInfo<Manager> addManager(String name, Class<? extends Manager> clazz, List<Pair<String, Object>> params, boolean singleton) {
ComponentInfo<Manager> info = new ComponentInfo<Manager>(name, clazz, params, singleton);
for (String key : info.getKeys()) {
_managers.put(key, info);
}
return info;
}
protected ComponentInfo<Manager> addManager(String name, Class<? extends Manager> clazz) {
return addManager(name, clazz, new ArrayList<Pair<String, Object>>(), true);
}
protected <T> List<ComponentInfo<Adapter>> addAdapterChain(Class<T> interphace, List<Pair<String, Class<? extends T>>> adapters) {
ArrayList<ComponentInfo<Adapter>> lst = new ArrayList<ComponentInfo<Adapter>>(adapters.size());
for (Pair<String, Class<? extends T>> adapter : adapters) {
@SuppressWarnings("unchecked")
Class<? extends Adapter> clazz = (Class<? extends Adapter>)adapter.second();
lst.add(new ComponentInfo<Adapter>(adapter.first(), clazz));
}
_adapters.put(interphace.getName(), lst);
return lst;
}
protected <T> ComponentInfo<Adapter> addOneAdapter(Class<T> interphace, String name, Class<? extends T> adapterClass) {
List<Pair<String, Class<? extends T>>> adapters = new ArrayList<Pair<String, Class<? extends T>>>();
adapters.add(new Pair<String, Class<? extends T>>(name, adapterClass));
return addAdapterChain(interphace, adapters).get(0);
}
}

View File

@ -90,7 +90,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
protected HashMap<String, Adapters<? extends Adapter>> _adapterMap;
protected HashMap<String, ComponentInfo<Manager>> _managerMap;
protected LinkedHashMap<String, ComponentInfo<GenericDao<?, ?>>> _daoMap;
protected LinkedHashMap<String, ComponentInfo<GenericDao<?, ? extends Serializable>>> _daoMap;
protected String _serverName;
protected Object _component;
protected HashMap<Class<?>, Class<?>> _factories;
@ -101,6 +101,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
public ComponentLocator(String server) {
_serverName = server;
Runtime.getRuntime().addShutdownHook(new CleanupThread());
}
public String getLocatorName() {
@ -615,7 +616,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
}
@Override
public Map<String, List<String>> getAdapters() {
public Map<String, List<String>> getAdapterNames() {
HashMap<String, List<String>> result = new HashMap<String, List<String>>();
for (Map.Entry<String, Adapters<? extends Adapter>> entry : _adapterMap.entrySet()) {
Adapters<? extends Adapter> adapters = entry.getValue();
@ -632,13 +633,13 @@ public class ComponentLocator implements ComponentLocatorMBean {
public Map<String, List<String>> getAllAccessibleAdapters() {
Map<String, List<String>> parentResults = new HashMap<String, List<String>>();
Map<String, List<String>> results = getAdapters();
Map<String, List<String>> results = getAdapterNames();
parentResults.putAll(results);
return parentResults;
}
@Override
public Collection<String> getManagers() {
public Collection<String> getManagerNames() {
Collection<String> names = new HashSet<String>();
for (Map.Entry<String, ComponentInfo<Manager>> entry : _managerMap.entrySet()) {
names.add(entry.getValue().name);
@ -647,7 +648,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
}
@Override
public Collection<String> getDaos() {
public Collection<String> getDaoNames() {
Collection<String> names = new HashSet<String>();
for (Map.Entry<String, ComponentInfo<GenericDao<?, ?>>> entry : _daoMap.entrySet()) {
names.add(entry.getValue().name);
@ -666,6 +667,20 @@ public class ComponentLocator implements ComponentLocatorMBean {
}
return new Adapters<Adapter>(key, new ArrayList<ComponentInfo<Adapter>>());
}
protected void resetInterceptors(InterceptorLibrary library) {
library.addInterceptors(s_interceptors);
if (s_interceptors.size() > 0) {
s_callbacks = new Callback[s_interceptors.size() + 2];
int i = 0;
s_callbacks[i++] = NoOp.INSTANCE;
s_callbacks[i++] = new InterceptorDispatcher();
for (AnnotationInterceptor<?> interceptor : s_interceptors) {
s_callbacks[i++] = interceptor.getCallback();
}
s_callbackFilter = new InterceptorFilter();
}
}
protected static ComponentLocator getLocatorInternal(String server, boolean setInThreadLocal, String configFileName, String log4jFilename) {
synchronized(s_once) {
@ -859,18 +874,8 @@ public class ComponentLocator implements ComponentLocatorMBean {
String libraryName = getAttribute(atts, "library");
try {
Class<?> libraryClazz = Class.forName(libraryName);
InterceptorLibrary library = (InterceptorLibrary)libraryClazz.newInstance();
library.addInterceptors(s_interceptors);
if (s_interceptors.size() > 0) {
s_callbacks = new Callback[s_interceptors.size() + 2];
int i = 0;
s_callbacks[i++] = NoOp.INSTANCE;
s_callbacks[i++] = new InterceptorDispatcher();
for (AnnotationInterceptor<?> interceptor : s_interceptors) {
s_callbacks[i++] = interceptor.getCallback();
}
s_callbackFilter = new InterceptorFilter();
}
InterceptorLibrary library = (InterceptorLibrary)libraryClazz.newInstance();
resetInterceptors(library);
} catch (ClassNotFoundException e) {
throw new CloudRuntimeException("Unable to find " + libraryName, e);
} catch (InstantiationException e) {

View File

@ -29,16 +29,16 @@ public interface ComponentLocatorMBean extends ManagementBean {
/**
* @return the list of adapters accessible by this component locator.
**/
Map<String, List<String>> getAdapters();
Map<String, List<String>> getAdapterNames();
/**
* @return the list of managers accessible by this component locator.
**/
Collection<String> getManagers();
Collection<String> getManagerNames();
/**
* @return the list of DAOs accessible by this component locator.
*/
Collection<String> getDaos();
Collection<String> getDaoNames();
}

View File

@ -0,0 +1,109 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.utils.component;
import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.NoOp;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DatabaseCallback;
import com.cloud.utils.db.DatabaseCallbackFilter;
import com.cloud.utils.db.GenericDao;
/**
* MockComponentLocator allows you to define exactly the components you need
* to test your component. This gives you a lot of flexibility in terms of
* defining mock components.
*/
public class MockComponentLocator extends ComponentLocator {
MockComponentLibrary _library = new MockComponentLibrary();
public MockComponentLocator(String server) {
super(server);
}
public ComponentInfo<? extends GenericDao<?, ? extends Serializable>> addDao(String name, Class<? extends GenericDao<?, ? extends Serializable>> dao) {
return _library.addDao(name, dao);
}
public ComponentInfo<Manager> addManager(String name, Class<? extends Manager> manager) {
return _library.addManager(name, manager);
}
public <T> ComponentInfo<Adapter> addOneAdapter(Class<T> interphace, String name, Class<? extends T> adapterClass) {
return _library.addOneAdapter(interphace, name, adapterClass);
}
public <T> List<ComponentInfo<Adapter>> addAdapterChain(Class<T> interphace, List<Pair<String, Class<? extends T>>> adapters) {
return _library.addAdapterChain(interphace, adapters);
}
@Override
protected Pair<XmlHandler, HashMap<String, List<ComponentInfo<Adapter>>>> parse2(String filename) {
Pair<XmlHandler, HashMap<String, List<ComponentInfo<Adapter>>>> result = new Pair<XmlHandler, HashMap<String, List<ComponentInfo<Adapter>>>>(new XmlHandler("fake"), new HashMap<String, List<ComponentInfo<Adapter>>>());
_daoMap = new LinkedHashMap<String, ComponentInfo<GenericDao<?, ? extends Serializable>>>();
_managerMap = new LinkedHashMap<String, ComponentInfo<Manager>>();
_adapterMap = new HashMap<String, Adapters<? extends Adapter>>();
_factories = new HashMap<Class<?>, Class<?>>();
_daoMap.putAll(_library.getDaos());
_managerMap.putAll(_library.getManagers());
result.second().putAll(_library.getAdapters());
_factories.putAll(_library.getFactories());
return result;
}
public void makeActive(InterceptorLibrary interceptors) {
s_singletons.clear();
s_locators.clear();
s_factories.clear();
s_callbacks = new Callback[] { NoOp.INSTANCE, new DatabaseCallback()};
s_callbackFilter = new DatabaseCallbackFilter();
s_interceptors.clear();
resetInterceptors(interceptors);
s_tl.set(this);
parse("fake file");
}
protected class MockComponentLibrary extends ComponentLibraryBase implements ComponentLibrary {
@Override
public Map<String, List<ComponentInfo<Adapter>>> getAdapters() {
return _adapters;
}
@Override
public Map<Class<?>, Class<?>> getFactories() {
return new HashMap<Class<?>, Class<?>>();
}
@Override
public Map<String, ComponentInfo<GenericDao<?, ?>>> getDaos() {
return _daos;
}
@Override
public Map<String, ComponentInfo<Manager>> getManagers() {
return _managers;
}
}
}