Author: ivol Date: Fri Oct 15 15:29:53 2010 New Revision: 175 Log: [AMDATU-107] Moves unit tests to separate project, needed to properly test bundles in OSGi container before installing them into the local maven repository (and will also be much faster since OSGi framework needs to be started only once)
Added: trunk/unit-tests/ trunk/unit-tests/pom.xml trunk/unit-tests/src/ trunk/unit-tests/src/main/ trunk/unit-tests/src/main/java/ trunk/unit-tests/src/main/java/org/ trunk/unit-tests/src/main/java/org/amdatu/ trunk/unit-tests/src/main/java/org/amdatu/test/ trunk/unit-tests/src/main/java/org/amdatu/test/osgi/ trunk/unit-tests/src/main/java/org/amdatu/test/osgi/Activator.java trunk/unit-tests/src/test/ trunk/unit-tests/src/test/java/ trunk/unit-tests/src/test/java/org/ trunk/unit-tests/src/test/java/org/amdatu/ trunk/unit-tests/src/test/java/org/amdatu/test/ trunk/unit-tests/src/test/java/org/amdatu/test/tenant/ trunk/unit-tests/src/test/java/org/amdatu/test/tenant/TenantManagementServiceTest.java trunk/unit-tests/src/test/java/org/amdatu/test/tenant/mock/ trunk/unit-tests/src/test/java/org/amdatu/test/tenant/mock/TenantDAOMock.java Removed: trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/test/TenantManagementServiceTest.java trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/test/mock/TenantDAOMock.java Modified: trunk/platform-bundles/tenant-service/pom.xml trunk/pom.xml Modified: trunk/platform-bundles/tenant-service/pom.xml ============================================================================== --- trunk/platform-bundles/tenant-service/pom.xml (original) +++ trunk/platform-bundles/tenant-service/pom.xml Fri Oct 15 15:29:53 2010 @@ -13,61 +13,7 @@ <name>Amdatu Platform - Tenant Service</name> <description>This bundle provides a tenant management service with tenant CRUD operations</description> - - <!-- See issues: - http://issues.ops4j.org/browse/PAXEXAM-81 - http://svn.apache.org/repos/asf/felix/releases/karaf-1.0.0/itests/pom.xml - http://pastebin.com/nUjAZENT - --> - - - <dependencies> - <!-- Test scope dependencies --> - <!-- This is required to be first so that pax-exam classloader is not messed up with a newer version of felix - which would lead to java.lang.NoSuchMethodError: org.apache.felix.framework.Logger.<init>(I)V --> - <dependency> - <groupId>org.ops4j.pax.exam</groupId> - <artifactId>pax-exam</artifactId> - <version>${pax.exam.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.ops4j.pax.exam</groupId> - <artifactId>pax-exam-junit</artifactId> - <version>${pax.exam.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.ops4j.pax.exam</groupId> - <artifactId>pax-exam-container-default</artifactId> - <version>${pax.exam.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.amdatu.platform</groupId> - <artifactId>filebased-configuration</artifactId> - <scope>test</scope> - <type>bundle</type> - </dependency> - <dependency> - <groupId>org.amdatu.platform</groupId> - <artifactId>httpcontext</artifactId> - <scope>test</scope> - <type>bundle</type> - </dependency> - <dependency> - <groupId>org.amdatu.platform</groupId> - <artifactId>config-template-manager</artifactId> - <scope>test</scope> - <type>bundle</type> - </dependency> - <dependency> - <groupId>org.amdatu.platform</groupId> - <artifactId>shindig-application</artifactId> - <scope>test</scope> - <type>bundle</type> - </dependency> - + <dependencies> <!-- Regular dependencies --> <dependency> <groupId>org.amdatu.platform</groupId> @@ -110,21 +56,7 @@ <plugin> <artifactId>maven-antrun-plugin</artifactId> </plugin> - - <plugin> - <groupId>org.apache.servicemix.tooling</groupId> - <artifactId>depends-maven-plugin</artifactId> - <executions> - <execution> - <id>generate-depends-file</id> - <goals> - <goal>generate-depends-file</goal> - </goals> - </execution> - </executions> - </plugin> - + </plugins> - </build> </project> Modified: trunk/pom.xml ============================================================================== --- trunk/pom.xml (original) +++ trunk/pom.xml Fri Oct 15 15:29:53 2010 @@ -185,6 +185,7 @@ <module>gadget-bundles</module> <module>libraries</module> <module>example-bundles</module> + <module>unit-tests</module> </modules> <repositories> Added: trunk/unit-tests/pom.xml ============================================================================== --- (empty file) +++ trunk/unit-tests/pom.xml Fri Oct 15 15:29:53 2010 @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.amdatu</groupId> + <artifactId>amdatu</artifactId> + <version>0.0.5-SNAPSHOT</version> + </parent> + <groupId>org.amdatu.platform</groupId> + <artifactId>unit-tests</artifactId> + <packaging>bundle</packaging> + <name>Amdatu Unit Tests</name> + <description>This bundle contains unit tests for the project</description> + + <!-- See issues: + http://issues.ops4j.org/browse/PAXEXAM-81 + http://svn.apache.org/repos/asf/felix/releases/karaf-1.0.0/itests/pom.xml + http://pastebin.com/nUjAZENT + --> + <dependencies> + <!-- Test scope dependencies --> + <!-- This is required to be first so that pax-exam classloader is not messed up with a newer version of felix + which would lead to java.lang.NoSuchMethodError: org.apache.felix.framework.Logger.<init>(I)V --> + <dependency> + <groupId>org.ops4j.pax.exam</groupId> + <artifactId>pax-exam</artifactId> + <version>${pax.exam.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.ops4j.pax.exam</groupId> + <artifactId>pax-exam-junit</artifactId> + <version>${pax.exam.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.ops4j.pax.exam</groupId> + <artifactId>pax-exam-container-default</artifactId> + <version>${pax.exam.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.amdatu.platform</groupId> + <artifactId>filebased-configuration</artifactId> + <scope>test</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.platform</groupId> + <artifactId>httpcontext</artifactId> + <scope>test</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.platform</groupId> + <artifactId>config-template-manager</artifactId> + <scope>test</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.platform</groupId> + <artifactId>shindig-application</artifactId> + <scope>test</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.platform</groupId> + <artifactId>tenant-service</artifactId> + <scope>test</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.platform</groupId> + <artifactId>cassandra-application</artifactId> + <version>0.0.5-SNAPSHOT</version> + <scope>test</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.platform</groupId> + <artifactId>cassandra-persistencemanager</artifactId> + <scope>test</scope> + <type>bundle</type> + </dependency> + <dependency> + <groupId>org.amdatu.platform</groupId> + <artifactId>cassandra-listener</artifactId> + <scope>test</scope> + <type>bundle</type> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Activator>org.amdatu.test.osgi</Bundle-Activator> + <Bundle-SymbolicName>org.amdatu.test</Bundle-SymbolicName> + </instructions> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.servicemix.tooling</groupId> + <artifactId>depends-maven-plugin</artifactId> + <executions> + <execution> + <id>generate-depends-file</id> + <goals> + <goal>generate-depends-file</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.ops4j.pax.exam</groupId> + <artifactId>maven-paxexam-plugin</artifactId> + <executions> + <execution> + <id>generate-config</id> + <goals> + <goal>generate-config</goal> + </goals> + </execution> + </executions> + <configuration> + <options> + <platform>${target-framework}</platform> + </options> + </configuration> + </plugin> + </plugins> + </build> +</project> Added: trunk/unit-tests/src/main/java/org/amdatu/test/osgi/Activator.java ============================================================================== --- (empty file) +++ trunk/unit-tests/src/main/java/org/amdatu/test/osgi/Activator.java Fri Oct 15 15:29:53 2010 @@ -0,0 +1,42 @@ +/* +/* + Copyright (C) 2010 Amdatu.org + + This program 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 + (at your option) 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 org.amdatu.test.osgi; + +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.osgi.framework.BundleContext; + +/** + * This class represents the OSGi activator for the unit test bundle + * @author ivol + */ +public class Activator extends DependencyActivatorBase { + /** + * {@inheritDoc} + */ + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + } + + /** + * {@inheritDoc} + */ + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + } +} Added: trunk/unit-tests/src/test/java/org/amdatu/test/tenant/TenantManagementServiceTest.java ============================================================================== --- (empty file) +++ trunk/unit-tests/src/test/java/org/amdatu/test/tenant/TenantManagementServiceTest.java Fri Oct 15 15:29:53 2010 @@ -0,0 +1,176 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program 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 + (at your option) 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 org.amdatu.test.tenant; + +import static org.ops4j.pax.exam.CoreOptions.felix; +import static org.ops4j.pax.exam.CoreOptions.frameworks; +import static org.ops4j.pax.exam.CoreOptions.mavenBundle; +import static org.ops4j.pax.exam.CoreOptions.mavenConfiguration; +import static org.ops4j.pax.exam.CoreOptions.options; +import static org.ops4j.pax.exam.CoreOptions.provision; +import static org.ops4j.pax.exam.CoreOptions.systemProperty; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import junit.framework.Assert; + +import org.amdatu.platform.tenant.Tenant; +import org.amdatu.platform.tenant.TenantDAO; +import org.amdatu.platform.tenant.TenantException; +import org.amdatu.platform.tenant.TenantManagementService; +import org.amdatu.test.tenant.mock.TenantDAOMock; +import org.apache.felix.dm.DependencyManager; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.ops4j.pax.exam.Inject; +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.junit.Configuration; +import org.ops4j.pax.exam.junit.JUnit4TestRunner; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceReference; + +/** + * This class provides a Unit test for testing the Tenant Management Service. + * @author ivol + */ +// TODO: using this test framework must be generalized, move dependencies to root pom +// TODO: service ranking mechanism to enforce that mock dao is used must be tested after solving other issues +// TODO: TenantImpl and TenantDAO has to be moved temporarily to the exported package in order for this test to use them + at RunWith(JUnit4TestRunner.class) +public class TenantManagementServiceTest { + @Inject + protected BundleContext m_bundleContext; + + @Configuration + public Option[] configure() { + return options( + mavenConfiguration(), + + // Run test in a Felix container + frameworks(felix()), + + // Setting this system property unfortunately is necessary with the current Cassandra implementation + systemProperty("org.osgi.framework.system.packages.extra").value("sun.misc,com.sun.management"), + + // Install bundles we need to execute our test + provision( + mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").versionAsInProject(), + mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject(), + mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.configadmin").versionAsInProject(), + mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.log").versionAsInProject(), + mavenBundle().groupId("org.ops4j.pax.web").artifactId("pax-web-jetty-bundle").versionAsInProject(), + mavenBundle().groupId("org.ops4j.pax.web").artifactId("pax-web-jsp").versionAsInProject(), + mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.commons.mime").versionAsInProject(), + mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.commons.osgi").versionAsInProject(), + + // Amdatu platform bundles + mavenBundle().groupId("org.amdatu.platform").artifactId("filebased-configuration").versionAsInProject(), + mavenBundle().groupId("org.amdatu.platform").artifactId("httpcontext").versionAsInProject(), + mavenBundle().groupId("org.amdatu.platform").artifactId("config-template-manager").versionAsInProject(), + mavenBundle().groupId("org.amdatu.platform").artifactId("cassandra-application").versionAsInProject(), + mavenBundle().groupId("org.amdatu.platform").artifactId("shindig-application").versionAsInProject(), + mavenBundle().groupId("org.amdatu.platform").artifactId("cassandra-listener").versionAsInProject(), + mavenBundle().groupId("org.amdatu.platform").artifactId("cassandra-persistencemanager").versionAsInProject(), + mavenBundle().groupId("org.amdatu.platform").artifactId("tenant-service").versionAsInProject())); + } + + @Test + public void crudTest() { + System.out.println("> TESTING: ************ Running Tenant CRUD test ************"); + + // First we register a new Mocked TenantDAO service and register it with a higher service rank then the default + // Cassandra DAO such that our test framework will pick it up + DependencyManager depMgr = new DependencyManager(m_bundleContext); + Hashtable<String, Integer> ht = new Hashtable<String, Integer>(); + ht.put(Constants.SERVICE_RANKING, 1); + depMgr.add(depMgr.createComponent().setImplementation(TenantDAOMock.class).setInterface( + TenantDAO.class.getName(), ht)); + System.out.println("> TESTING: TenantDAOMock service registered"); + + ServiceReference tenantMgrSR = m_bundleContext.getServiceReference(TenantManagementService.class.getName()); + TenantManagementService tenantManagementService = + (TenantManagementService) m_bundleContext.getService(tenantMgrSR); + System.out.println("> TESTING: Testing " + tenantManagementService); + + try { + run(tenantManagementService); + } + catch (TenantException e) { + Assert.fail("An error has occurred: " + e.toString()); + e.printStackTrace(); + } + } + + private void run(TenantManagementService tenantService) throws TenantException { + Tenant[] allTenants = tenantService.getAllTenants(); + Assert + .assertTrue("There are already tenants present in the storage", + tenantService.getAllTenants().length == 0); + + int tenantCount = allTenants.length; + Tenant tenant = tenantService.createTentant("org.amdatu.test.integration.tests.testtenant", "TEST"); + tenantService.updateTenant(tenant); + + Assert.assertTrue("Added and updated 1 tenant, but the Tenant service now holds " + + tenantService.getAllTenants().length + " tenants, expected: " + (tenantCount + 1), tenantService + .getAllTenants().length == tenantCount + 1); + + // Try to add a tenant with the same id, should throw an exception + try { + tenantService.createTentant("org.amdatu.test.integration.tests.testtenant", "sdfsdfd"); + Assert.assertTrue("Tenant with the same id could be created twice", false); + } + catch (TenantException e) { + } + + tenantService.deleteTenant(tenant); + + Assert.assertTrue(tenantService.getAllTenants().length == tenantCount); + + Tenant tenant1 = tenantService.createTentant("org.amdatu.test.integration.tests.testtenant.1", "TEST 1"); + Tenant tenant2 = tenantService.createTentant("org.amdatu.test.integration.tests.testtenant.2", "TEST 2"); + Tenant tenant3 = tenantService.createTentant("org.amdatu.test.integration.tests.testtenant.3", "TEST 3"); + tenant1.getProperties().put("hostname", "localhost"); + tenant2.getProperties().put("hostname", "localhost"); + tenant3.getProperties().put("hostname", "amdatu.org"); + tenantService.updateTenant(tenant1); + tenantService.updateTenant(tenant2); + tenantService.updateTenant(tenant3); + + Map<String, String> filter = new HashMap<String, String>(); + filter.put("hostname", "localhost"); + Assert.assertTrue(tenantService.getTenants(filter).length == 2); + + filter.put("hostname", "amdatu.org"); + Assert.assertTrue(tenantService.getTenants(filter).length == 1); + + tenantService.deleteTenant(tenant1); + tenantService.deleteTenant(tenant2); + tenantService.deleteTenant(tenant3); + + // What happens if I remove a tenant that was already removed? + try { + tenantService.deleteTenant(tenant); + Assert.assertTrue("Tenant with the same id could be deleted twice", false); + } + catch (TenantException e) { + } + } +} Added: trunk/unit-tests/src/test/java/org/amdatu/test/tenant/mock/TenantDAOMock.java ============================================================================== --- (empty file) +++ trunk/unit-tests/src/test/java/org/amdatu/test/tenant/mock/TenantDAOMock.java Fri Oct 15 15:29:53 2010 @@ -0,0 +1,82 @@ +/* + Copyright (C) 2010 Amdatu.org + + This program 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 + (at your option) 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 org.amdatu.test.tenant.mock; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.amdatu.platform.tenant.Tenant; +import org.amdatu.platform.tenant.TenantDAO; +import org.amdatu.platform.tenant.TenantException; +import org.amdatu.platform.tenant.TenantImpl; + +/** + * This service mocks the TenantDAO, implementing an in-memory DAO. + * @author ivol + */ +public class TenantDAOMock implements TenantDAO { + private List<Tenant> m_tenants = new ArrayList<Tenant>(); + + public Tenant create(String id, String name) throws TenantException { + try { + read(id); + } + catch (TenantException e) { + TenantImpl tenant = new TenantImpl(id, name, new HashMap<String, String>()); + m_tenants.add(tenant); + return copy(tenant); + } + throw new TenantException("Tenant with id " + id + " already exists"); + } + + public List<Tenant> readAll() throws TenantException { + List<Tenant> tenantCopy = new ArrayList<Tenant>(); + for (Tenant tenant : m_tenants) { + tenantCopy.add(copy(tenant)); + } + return tenantCopy; + } + + public Tenant read(String id) throws TenantException { + for (Tenant tenant : m_tenants) { + if (id.equals(tenant.getId())) { + return tenant; + } + } + throw new TenantException("Tenant with id '" + id + "' does not exist"); + } + + public void update(Tenant tenant) throws TenantException { + Tenant t = read(tenant.getId()); + t.setName(tenant.getName()); + } + + public void delete(Tenant tenant) throws TenantException { + for (Tenant t : m_tenants) { + if (tenant.getId().equals(t.getId())) { + m_tenants.remove(tenant); + return; + } + } + throw new TenantException("Tenant with id '" + tenant.getId() + "' could not be removed"); + } + + private Tenant copy(Tenant tenant) { + return new TenantImpl(tenant.getId(), tenant.getName(), tenant.getProperties()); + } +}
