You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by an...@apache.org on 2011/01/20 00:20:48 UTC

svn commit: r1061061 - /openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulConcurrentLookupTest.java

Author: andygumbrecht
Date: Wed Jan 19 23:20:48 2011
New Revision: 1061061

URL: http://svn.apache.org/viewvc?rev=1061061&view=rev
Log:
Using real non-pooled multithreaded access to test concurrent code execution on a stateful bean.

Added:
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulConcurrentLookupTest.java

Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulConcurrentLookupTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulConcurrentLookupTest.java?rev=1061061&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulConcurrentLookupTest.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulConcurrentLookupTest.java Wed Jan 19 23:20:48 2011
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2011 The Apache OpenEJB development community.
+ *
+ * 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.apache.openejb.core.stateful;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.ejb.Local;
+import javax.ejb.Stateful;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.assembler.classic.StatefulSessionContainerInfo;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.client.LocalInitialContextFactory;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.jee.ConcurrentMethod;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.NamedMethod;
+import org.apache.openejb.jee.StatefulBean;
+import org.apache.openejb.jee.Timeout;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * Using real non-pooled multithreaded access to test concurrent code execution on a stateful bean.
+ * The test also employs a test for failure.
+ */
+public class StatefulConcurrentLookupTest {
+
+    private static final int THREAD_COUNT = 1000;
+
+    @BeforeClass
+    public static synchronized void beforeClass() throws Exception {
+        System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
+
+        final ConfigurationFactory config = new ConfigurationFactory();
+        final Assembler assembler = new Assembler();
+
+        assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
+        assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+        assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
+
+        final StatefulSessionContainerInfo statefulContainerInfo = config.configureService(StatefulSessionContainerInfo.class);
+        assembler.createContainer(statefulContainerInfo);
+
+        final EjbJar ejbJar = new EjbJar();
+
+        final StatefulBean bean1 = new StatefulBean(MyLocalBeanImpl.class);
+        final Timeout timeout1 = new Timeout();
+        timeout1.setTimeout(10);
+        timeout1.setUnit(TimeUnit.SECONDS);
+        final ConcurrentMethod method1 = new ConcurrentMethod();
+        method1.setMethod(new NamedMethod("*"));
+        method1.setAccessTimeout(timeout1);
+        bean1.getConcurrentMethod().add(method1);
+
+        ejbJar.addEnterpriseBean(bean1);
+
+        assembler.createApplication(config.configureApplication(ejbJar));
+    }
+
+    @Test
+    public void testLookup() throws Exception {
+
+        final CountDownLatch latchInit = new CountDownLatch(THREAD_COUNT);
+        final CountDownLatch latchComplete = new CountDownLatch(THREAD_COUNT);
+
+        final List<TestRunnable> runnables = new ArrayList<TestRunnable>();
+        final List<Thread> threads = new ArrayList<Thread>();
+
+        int i = 0;
+        for (; i < THREAD_COUNT; i++) {
+            runnables.add(new TestRunnable("Lookup." + i, false, latchInit, latchComplete));
+            threads.add(new Thread(runnables.get(i)));
+        }
+
+        for (final Thread thread : threads) {
+            thread.setDaemon(false);
+            thread.start();
+        }
+
+        for (final Thread thread : threads) {
+            thread.join();
+        }
+
+        for (final TestRunnable runnable : runnables) {
+            if (runnable.isSuccess()) {
+                i--;
+            }
+        }
+
+        StatefulConcurrentLookupTest.print("testLookup: Threads successfully processed - " + (THREAD_COUNT - i));
+        assertEquals(THREAD_COUNT, (THREAD_COUNT - i));
+    }
+
+    @Test
+    public void testLookupWithFail() throws Exception {
+
+        final CountDownLatch latchInit = new CountDownLatch(THREAD_COUNT);
+        final CountDownLatch latchComplete = new CountDownLatch(THREAD_COUNT);
+
+        final List<TestRunnable> runnables = new ArrayList<TestRunnable>();
+        final List<Thread> threads = new ArrayList<Thread>();
+
+        int i = 0;
+        for (; i < THREAD_COUNT; i++) {
+            runnables.add(new TestRunnable("Lookup.Fail." + i, true, latchInit, latchComplete));
+            threads.add(new Thread(runnables.get(i)));
+        }
+
+        for (final Thread thread : threads) {
+            thread.setDaemon(false);
+            thread.start();
+        }
+
+        for (final Thread thread : threads) {
+            thread.join();
+        }
+
+        for (final TestRunnable runnable : runnables) {
+            if (!runnable.isSuccess()) {
+                i--;
+            }
+        }
+
+        StatefulConcurrentLookupTest.print("testLookupWithFail: Threads successfully processed - " + (THREAD_COUNT - i));
+        assertEquals(THREAD_COUNT, (THREAD_COUNT - i));
+    }
+
+    private static class TestRunnable implements Runnable {
+
+        private final CountDownLatch latchInit;
+        private final CountDownLatch latchComplete;
+        private final String name;
+        private final boolean throh;
+        private boolean success = false;
+
+        private TestRunnable(final String name, final boolean throh, final CountDownLatch latchInit, final CountDownLatch latchComplete) {
+            this.name = name;
+            this.throh = throh;
+            this.latchInit = latchInit;
+            this.latchComplete = latchComplete;
+        }
+
+        @Override
+        public void run() {
+
+            InitialContext ctx = null;
+
+            try {
+                ctx = new InitialContext();
+            } catch (NamingException ex) {
+                Logger.getLogger(StatefulConcurrentLookupTest.class.getName()).log(Level.SEVERE, null, ex);
+            } finally {
+                //Get all threads raring to go.
+                latchInit.countDown();
+            }
+
+            try {
+                latchInit.await();
+            } catch (InterruptedException e) {
+                //Ignore
+            }
+
+            //All threads will now fight for concurrent access
+            try {
+
+                final MyLocalBean bean = (MyLocalBean) ctx.lookup("MyLocalBeanImplLocal");
+                bean.set(this.name, this.throh);
+                success = this.name.equals(bean.get());
+
+            } catch (Throwable t) {
+                success = false;
+                //StatefulConcurrentLookupTest.print(t.getMessage());
+            } finally {
+                latchComplete.countDown();
+            }
+
+            try {
+                latchComplete.await();
+            } catch (InterruptedException e) {
+                //Ignore
+            }
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public boolean isSuccess() {
+            return success;
+        }
+    }
+
+    private static synchronized void print(final String txt) {
+        System.out.println(txt);
+    }
+
+    @Local
+    public static interface MyLocalBean {
+
+        void set(final String txt, final boolean throh);
+
+        String get();
+    }
+
+    @Stateful
+    public static class MyLocalBeanImpl implements MyLocalBean {
+
+        private String txt = "default";
+        private boolean throh = false;
+
+        @Override
+        public void set(final String txt, final boolean throh) {
+            this.txt = txt;
+            this.throh = throh;
+        }
+
+        @Override
+        public String get() {
+
+            if (this.throh) {
+                throw new UnsupportedOperationException(this.txt);
+            }
+
+            return this.txt;
+        }
+    }
+}