Author: [email protected]
Date: Thu Feb  2 14:52:57 2012
New Revision: 2052

Log:
- Fixed review comments on AMDATU-548;
- Implemented AMDATU-549;
- Fixed the build ;)

Added:
   
trunk/amdatu-core/itest/tests/src/test/java/org/amdatu/core/itest/tests/tenant/MultiTenantBenchmarkTest.java
   (contents, props changed)
   
trunk/amdatu-core/itest/tests/src/test/java/org/amdatu/core/itest/tests/tenant/TenantTestEventHandler.java
   (contents, props changed)
Modified:
   trunk/amdatu-core/itest/tenant-test/pom.xml
   trunk/amdatu-core/itest/tests/pom.xml
   
trunk/amdatu-core/itest/tests/src/test/java/org/amdatu/core/itest/tests/tenant/mock/

Modified: trunk/amdatu-core/itest/tenant-test/pom.xml
==============================================================================
--- trunk/amdatu-core/itest/tenant-test/pom.xml (original)
+++ trunk/amdatu-core/itest/tenant-test/pom.xml Thu Feb  2 14:52:57 2012
@@ -23,7 +23,7 @@
     <artifactId>org.amdatu.core.itest</artifactId>
     <version>0.3.0-SNAPSHOT</version>
   </parent>
-  <artifactId>org.amdatu.core.itest.tenant-test</artifactId>
+  <artifactId>org.amdatu.core.itest.tenant</artifactId>
   <packaging>bundle</packaging>
   <name>Amdatu Core - (Temporary) Multi-tenancy integration test code.</name>
 

Modified: trunk/amdatu-core/itest/tests/pom.xml
==============================================================================
--- trunk/amdatu-core/itest/tests/pom.xml       (original)
+++ trunk/amdatu-core/itest/tests/pom.xml       Thu Feb  2 14:52:57 2012
@@ -47,7 +47,7 @@
       </dependency>
       <dependency>
         <groupId>org.amdatu.core</groupId>
-        <artifactId>org.amdatu.core.itest.tenant-test</artifactId>
+        <artifactId>org.amdatu.core.itest.tenant</artifactId>
         <version>${project.version}</version>
         <scope>provided</scope>
         <type>bundle</type>
@@ -66,7 +66,7 @@
     </dependency>
     <dependency>
       <groupId>org.amdatu.core</groupId>
-      <artifactId>org.amdatu.core.itest.tenant-test</artifactId>
+      <artifactId>org.amdatu.core.itest.tenant</artifactId>
       <type>bundle</type>
     </dependency>
   </dependencies>

Added: 
trunk/amdatu-core/itest/tests/src/test/java/org/amdatu/core/itest/tests/tenant/MultiTenantBenchmarkTest.java
==============================================================================
--- (empty file)
+++ 
trunk/amdatu-core/itest/tests/src/test/java/org/amdatu/core/itest/tests/tenant/MultiTenantBenchmarkTest.java
        Thu Feb  2 14:52:57 2012
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2010-2012 The Amdatu Foundation
+ * 
+ * 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.amdatu.core.itest.tests.tenant;
+
+import static junit.framework.Assert.assertTrue;
+import static org.amdatu.tenant.TenantConstants.PID_KEY;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.ops4j.pax.exam.CoreOptions.cleanCaches;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.CoreOptions.systemTimeout;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.inject.Inject;
+
+import org.amdatu.core.itest.base.CoreBundles;
+import org.amdatu.core.itest.base.CoreConfigs;
+import org.amdatu.core.itest.base.TestContext;
+import org.amdatu.core.itest.tenant.MyDependentService;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.ExamReactorStrategy;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.exam.spi.reactors.EagerSingleStagedReactorFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.cm.Configuration;
+
+/**
+ * Benchmark test for multi-tenancy. Tests whether it is possible to run a 
"large" number of tenants in a single container.
+ * 
+ * @author <a href="mailto:[email protected]";>Amdatu Project 
Team</a>
+ */
+@RunWith(JUnit4TestRunner.class)
+@ExamReactorStrategy(EagerSingleStagedReactorFactory.class)
+public class MultiTenantBenchmarkTest {
+
+    private static final int TENANT_COUNT = 100;
+
+    @Inject
+    private BundleContext m_bundleContext;
+    private TestContext m_testContext;
+    private TenantTestEventHandler m_eventHandler;
+    private final List<Configuration> m_configurations = new 
ArrayList<Configuration>();
+
+    @org.ops4j.pax.exam.junit.Configuration
+    public Option[] config() {
+        return options(
+            cleanCaches(),
+            junitBundles(),
+            CoreBundles.provisionAll(),
+            
provision(mavenBundle().groupId("org.amdatu.core").artifactId("org.amdatu.core.itest.tenant")
+                .versionAsInProject()),
+            systemTimeout(10000));
+    }
+
+    /**
+     * Sets up an individual test case.
+     * 
+     * @throws Exception not part of this set up.
+     */
+    @Before
+    public void setUp() throws Exception {
+        m_testContext = new TestContext(m_bundleContext);
+        CoreConfigs.provisionAllExcluding(m_testContext, CoreConfigs.TENANT);
+
+        m_eventHandler = 
TenantTestEventHandler.install(m_testContext.getDependencyManager());
+
+        m_testContext.waitForSystemToSettle();
+    }
+
+    /**
+     * Tears down the test case.
+     */
+    @After
+    public void tearDown() {
+        for (Configuration config : m_configurations) {
+            try {
+                config.delete();
+            }
+            catch (Exception exception) {
+                // Ignore...
+            }
+        }
+        m_configurations.clear();
+        m_testContext.tearDown();
+    }
+
+    /**
+     * Tests that for a single OSGi-container many tenant services can be 
materialized.
+     * 
+     * @throws Exception not part of this test case.
+     */
+    @Test
+    public void testBenchmark() throws Exception {
+        List<String> createdTenantIDs = new ArrayList<String>(TENANT_COUNT);
+
+        // Ramp up: create up to TENANT_COUNT tenants (start at one as we get 
a _PLATFORM tenant for free)...
+        for (int i = 1; i < TENANT_COUNT; i++) {
+            String tenantId = generateTenantId(i);
+            addTenantConfig(createTenantConfiguration(tenantId));
+            createdTenantIDs.add(tenantId);
+        }
+
+        // Wait until the system has been settled and all tenants are 
activated...
+        m_testContext.waitForSystemToSettle();
+
+        assertEquals(TENANT_COUNT, getConfigurationCount());
+        
+        List<String> msgs = m_eventHandler.getMessages();
+        // We've created TENANT_COUNT - 1 tenants, each one registering two 
services,
+        // so we should see 2 * (TENANT_COUNT - 1) messages in our log 
appears...
+        int expectedTenantMsgCount = 2 * (TENANT_COUNT - 1);
+        assertEquals(expectedTenantMsgCount, msgs.size());
+
+        List<Configuration> tmpConfigs = new 
ArrayList<Configuration>(m_configurations);
+
+        // Make a call to each and every tenant...
+        List<String> seenList = new ArrayList<String>(createdTenantIDs);
+        for (Configuration config : tmpConfigs) {
+            String tenantId = (String) config.getProperties().get(PID_KEY);
+
+            MyDependentService service = getServiceInstance(tenantId);
+            assertNotNull(service.sayIt());
+
+            // Mark this tenant as seen...
+            seenList.remove(tenantId);
+        }
+
+        assertEquals("Not all tenants were seen/called?!", 0, seenList.size());
+
+        msgs = m_eventHandler.getMessages();
+        // We should have seen *no* new tenants coming in, or old tenants 
leaving us...
+        assertEquals(0, msgs.size());
+
+        // Ramp down: remove each and every tenant instance...
+        for (Configuration config : tmpConfigs) {
+            assertTrue(removeTenantConfig(config));
+        }
+
+        // Wait until the system has been settled and all tenants are 
activated...
+        m_testContext.waitForSystemToSettle();
+
+        msgs = m_eventHandler.getMessages();
+        assertEquals(expectedTenantMsgCount, msgs.size());
+    }
+
+    /**
+     * @param tenantId
+     * @return
+     */
+    private MyDependentService getServiceInstance(String tenantId) throws 
Exception {
+        return m_testContext.getService(MyDependentService.class, 
String.format("(%1$s=%2$s)", PID_KEY, tenantId));
+    }
+
+    /**
+     * @param tenantId the tenant identifier to use.
+     * @return the configuration for creating a new tenant.
+     */
+    private Properties createTenantConfiguration(String tenantId) {
+        Properties properties = new Properties();
+        properties.put(PID_KEY, tenantId);
+        return properties;
+    }
+
+    /**
+     * @return a "unique" tenant identifier, never <code>null</code>.
+     */
+    private String generateTenantId(int i) {
+        return String.format("Tenant-%s", Integer.toString(i));
+    }
+
+    /**
+     * Returns the number of configurations.
+     * 
+     * @return the configuration count + 1 for the _PLATFORM tenant service.
+     */
+    private int getConfigurationCount() {
+        synchronized (m_configurations) {
+            return m_configurations.size() + 1;
+        }
+    }
+
+    /**
+     * @param properties
+     * @throws Exception
+     */
+    private boolean removeTenantConfig(Configuration config) throws Exception {
+        boolean found;
+        synchronized (m_configurations) {
+            found = m_configurations.remove(config);
+        }
+        if (found) {
+            config.delete();
+        }
+        return found;
+    }
+
+    /**
+     * @param properties
+     * @throws Exception
+     */
+    private Configuration addTenantConfig(Properties properties) throws 
Exception {
+        Configuration config = 
m_testContext.updateFactoryConfig(CoreConfigs.TENANT.getPid(), properties);
+        synchronized (m_configurations) {
+            m_configurations.add(config);
+        }
+        return config;
+    }
+}

Added: 
trunk/amdatu-core/itest/tests/src/test/java/org/amdatu/core/itest/tests/tenant/TenantTestEventHandler.java
==============================================================================
--- (empty file)
+++ 
trunk/amdatu-core/itest/tests/src/test/java/org/amdatu/core/itest/tests/tenant/TenantTestEventHandler.java
  Thu Feb  2 14:52:57 2012
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010-2012 The Amdatu Foundation
+ * 
+ * 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.amdatu.core.itest.tests.tenant;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventConstants;
+import org.osgi.service.event.EventHandler;
+
+/**
+ * Provides an event handler used in the multi-tenancy tests.
+ * 
+ * @author <a href="mailto:[email protected]";>Amdatu Project 
Team</a>
+ */
+class TenantTestEventHandler implements EventHandler {
+
+    private final List<String> m_messages = new ArrayList<String>();
+
+    /**
+     * Install a new instance of this {@link TenantTestEventHandler} with the 
OSGi framework.
+     * 
+     * @param dm the dependency manager to use, cannot be <code>null</code>.
+     * @return the registered event handler, never <code>null</code>.
+     */
+    public static TenantTestEventHandler install(DependencyManager dm) {
+        Properties properties = new Properties();
+        properties.put(EventConstants.EVENT_TOPIC, new String[] { 
"org/osgi/service/log/LogEntry/LOG_INFO" });
+        properties.put(EventConstants.EVENT_FILTER, "(message=MTL:*)");
+
+        TenantTestEventHandler result = new TenantTestEventHandler();
+
+        // Register our own event handler to the framework...
+        dm.add(dm.createComponent()
+            .setInterface(EventHandler.class.getName(), properties)
+            .setImplementation(result)
+            );
+
+        return result;
+    }
+
+    /**
+     * @return a copy of the current messages.
+     */
+    public List<String> getMessages() {
+        List<String> result;
+        synchronized (m_messages) {
+            result = new ArrayList<String>(m_messages);
+            m_messages.clear();
+        }
+        return result;
+    }
+
+    /**
+     * @see 
org.osgi.service.event.EventHandler#handleEvent(org.osgi.service.event.Event)
+     */
+    public void handleEvent(Event event) {
+        String msg = (String) event.getProperty("message");
+        synchronized (m_messages) {
+            m_messages.add(msg.substring(4));
+        }
+    }
+}
\ No newline at end of file
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to