Author: dblevins
Date: Tue Jun 22 04:03:11 2010
New Revision: 956768

URL: http://svn.apache.org/viewvc?rev=956768&view=rev
Log:
Stub for a testcase for the JMX Monitoring.
OPENEJB-1303: JMX API Tests
OPENEJB-1272 OPENEJB-1275

Added:
    
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessStatisticsTest.java
   (with props)

Added: 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessStatisticsTest.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessStatisticsTest.java?rev=956768&view=auto
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessStatisticsTest.java
 (added)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessStatisticsTest.java
 Tue Jun 22 04:03:11 2010
@@ -0,0 +1,311 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.stateless;
+
+import junit.framework.TestCase;
+import org.apache.openejb.api.Monitor;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.assembler.classic.StatelessSessionContainerInfo;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.core.ivm.naming.InitContextFactory;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.StatelessBean;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.naming.InitialContext;
+import java.lang.management.ManagementFactory;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * INVOCATIONS MBEAN
+ * <p/>
+ * All beans have this set of attributes and operations by default:
+ * <p/>
+ * javax.management.MBeanAttributeInfo[description=, name=InvocationCount, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=InvocationTime, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=MonitoredMethods, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanOperationInfo[description=, name=FilterAttributes, 
returnType=void, signature=[javax.management.MBeanParameterInfo[description="", 
name=excludeRegex, type=java.lang.String, descriptor={}], 
javax.management.MBeanParameterInfo[description="", name=includeRegex, 
type=java.lang.String, descriptor={}]], impact=unknown, descriptor={}]
+ * <p/>
+ * Then for every method there will be these attributes and operations:
+ * <p/>
+ * javax.management.MBeanAttributeInfo[description=, name=someMethod().Count, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().GeometricMean, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().Kurtosis, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=someMethod().Max, 
type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=someMethod().Mean, 
type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=someMethod().Min, 
type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().Percentile01, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().Percentile10, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().Percentile25, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().Percentile50, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().Percentile75, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().Percentile90, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().Percentile99, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().SampleSize, type=int, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().Skewness, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().StandardDeviation, type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=someMethod().Sum, 
type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=someMethod().Sumsq, 
type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=someMethod().Variance, type=double, read-only, descriptor={}]
+ * javax.management.MBeanOperationInfo[description=, 
name=someMethod().setSampleSize, returnType=void, 
signature=[javax.management.MBeanParameterInfo[description=, name=p1, type=int, 
descriptor={}]], impact=unknown, descriptor={}]
+ * javax.management.MBeanOperationInfo[description=, 
name=someMethod().sortedValues, returnType=[D, signature=[], impact=unknown, 
descriptor={}]
+ * javax.management.MBeanOperationInfo[description=, name=someMethod().values, 
returnType=[D, signature=[], impact=unknown, descriptor={}]
+ * <p/>
+ * Attribute values that should be tested:
+ * javax.management.MBeanAttributeInfo[description=, name=InvocationCount, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=InvocationTime, 
type=long, read-only, descriptor={}]
+ * <p/>
+ * Atribute values that should be tested per method:
+ * <p/>
+ * javax.management.MBeanAttributeInfo[description=, name=someMethod().Count, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanOperationInfo[description=, name=someMethod().values, 
returnType=[D, signature=[], impact=unknown, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=someMethod().Max, 
type=double, read-only, descriptor={}]
+ * <p/>
+ * We should test that all expected attributes are there, but when testing 
each method's values
+ * are updated correctly we only need to check that count is correct, 
values.length == count, max is as expected.
+ * To determine that max is as expected one technique would be to make each 
method sleep for a different amount of time
+ * and test that the max is at least that length.
+ * <p/>
+ * POOL MBEAN
+ * <p/>
+ * All expected attributes and operations
+ * javax.management.MBeanAttributeInfo[description=, name=AccessTimeouts, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=AccessTimeouts.Latest, type=java.lang.String, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Aged, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Aged.Latest, 
type=java.lang.String, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Available, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Flushed, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Flushed.Latest, 
type=java.lang.String, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Flushes, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Flushes.Latest, 
type=java.lang.String, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=GarbageCollected, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=GarbageCollected.Latest, type=java.lang.String, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=IdleTimeout, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=IdleTimeouts, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=IdleTimeouts.Latest, 
type=java.lang.String, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Instances, type=int, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Interval, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=MaxAge, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=MaxAgeOffset, 
type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=MaxSize, type=int, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=MinSize, type=int, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=MinimumInstances, 
type=int, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Overdrafts, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Overdrafts.Latest, 
type=java.lang.String, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=PoolVersion, 
type=java.util.concurrent.atomic.AtomicInteger, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=ReplaceAged, 
type=boolean, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Replaced, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Replaced.Latest, 
type=java.lang.String, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Sweeps, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Sweeps.Latest, 
type=java.lang.String, read-only, descriptor={}]
+ * javax.management.MBeanOperationInfo[description=, name=FilterAttributes, 
returnType=void, signature=[javax.management.MBeanParameterInfo[description="", 
name=excludeRegex, type=java.lang.String, descriptor={}], 
javax.management.MBeanParameterInfo[description="", name=includeRegex, 
type=java.lang.String, descriptor={}]], impact=unknown, descriptor={}]
+ * <p/>
+ * Attribute values that only need to be checked once (configuration 
constants):
+ * javax.management.MBeanAttributeInfo[description=, name=MaxAge, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=MaxAgeOffset, 
type=double, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=MaxSize, type=int, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=MinSize, type=int, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Interval, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=ReplaceAged, 
type=boolean, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=IdleTimeout, 
type=long, read-only, descriptor={}]
+ * <p/>
+ * Attribute values that should be checked with a new pool and again on a 
maxed pool:
+ * javax.management.MBeanAttributeInfo[description=, name=Available, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=MinimumInstances, 
type=int, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Instances, type=int, 
read-only, descriptor={}]
+ * <p/>
+ * Flusing related.  Check before/after
+ * javax.management.MBeanAttributeInfo[description=, name=Flushed, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Flushes, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=PoolVersion, 
type=java.util.concurrent.atomic.AtomicInteger, read-only, descriptor={}]
+ * <p/>
+ * Requires an invocation against a maxed pool with all instances checked out, 
must be a strict pool
+ * javax.management.MBeanAttributeInfo[description=, name=AccessTimeouts, 
type=long, read-only, descriptor={}]
+ * <p/>
+ * See PoolTest on how to potentially test for these
+ * javax.management.MBeanAttributeInfo[description=, name=Aged, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=IdleTimeouts, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=ReplaceAged, 
type=boolean, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Replaced, type=long, 
read-only, descriptor={}]
+ * <p/>
+ * Should be greater than 1 and 'Latest' should be no less than 
System.currentTimeMillis() - Interval
+ * javax.management.MBeanAttributeInfo[description=, name=Sweeps, type=long, 
read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, name=Sweeps.Latest, 
type=java.lang.String, read-only, descriptor={}]
+ * <p/>
+ * Only testable with a non-strict pool, specified how many instances beyond 
max have been created
+ * javax.management.MBeanAttributeInfo[description=, name=Overdrafts, 
type=long, read-only, descriptor={}]
+ * <p/>
+ * Not testable:
+ * javax.management.MBeanAttributeInfo[description=, name=GarbageCollected, 
type=long, read-only, descriptor={}]
+ * javax.management.MBeanAttributeInfo[description=, 
name=GarbageCollected.Latest, type=java.lang.String, read-only, descriptor={}]
+ *
+ * @version $Rev$ $Date$
+ */
+public class StatelessStatisticsTest extends TestCase {
+
+    /**
+     * This whole method is a template, feel free to split it anyway you like
+     * Fine to have one big
+     *
+     * @throws Exception
+     */
+    public void test() throws Exception {
+
+        System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, 
InitContextFactory.class.getName());
+
+        ConfigurationFactory config = new ConfigurationFactory();
+        Assembler assembler = new Assembler();
+
+        
assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+        
assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
+
+        // containers
+        StatelessSessionContainerInfo statelessContainerInfo = 
config.configureService(StatelessSessionContainerInfo.class);
+        statelessContainerInfo.properties.setProperty("AccessTimeout", "100");
+        statelessContainerInfo.properties.setProperty("PoolSize", "15");
+        statelessContainerInfo.properties.setProperty("PoolMin", "3");
+        statelessContainerInfo.properties.setProperty("StrictPooling", "true");
+        assembler.createContainer(statelessContainerInfo);
+
+        // Setup the descriptor information
+
+        CounterBean.instances.set(0);
+
+        EjbJar ejbJar = new EjbJar("StatsModule");
+        ejbJar.addEnterpriseBean(new StatelessBean(CounterBean.class));
+
+        assembler.createApplication(config.configureApplication(ejbJar));
+
+        javax.naming.Context context = new InitialContext();
+        CounterBean bean = (CounterBean) 
context.lookup("CounterBeanLocalBean");
+
+        // TODO: invoke each method a different number of times
+        bean.red();
+        bean.green();
+        bean.blue();
+
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        ObjectName invocationsName = new 
ObjectName("openejb.management:J2EEServer=openejb,J2EEApplication=null,EJBModule=StatsModule,StatelessSessionBean=CounterBean,j2eeType=Invocations,name=CounterBean");
+        ObjectName poolName = new 
ObjectName("openejb.management:J2EEServer=openejb,J2EEApplication=null,EJBModule=StatsModule,StatelessSessionBean=CounterBean,j2eeType=Pool,name=CounterBean");
+
+        // TODO grab the mbeanInfo and check the expected attributes exist and 
have the correct return types and parameters
+        MBeanInfo invocationsMBeanInfo = server.getMBeanInfo(invocationsName);
+        MBeanInfo poolMBeanInfo = server.getMBeanInfo(poolName);
+
+        // TODO The hardest part, check the values of each
+
+        System.out.println("// Attributes:");
+        for (MBeanAttributeInfo info : poolMBeanInfo.getAttributes()) {
+            System.out.println("// " + info);
+        }
+
+        System.out.println("// Operations:");
+        for (MBeanOperationInfo info : poolMBeanInfo.getOperations()) {
+            System.out.println("// " + info);
+        }
+    }
+
+    /**
+     * convenience method for checking out a specific number of instances.
+     * Can be used like so:
+     * <p/>
+     * // checkout some instances from the pool
+     * CountDownLatch startingPistol = checkout(bean, 7);
+     * <p/>
+     * // Look at pool stats
+     * ...
+     * 
+     * // Release them all back into the pool
+     * startingPistol.countDown();
+     *
+     * @param bean
+     * @param count
+     * @return
+     * @throws InterruptedException
+     */
+    private CountDownLatch checkout(final CounterBean bean, int count) throws 
InterruptedException {
+        final CountDownLatch startingLine = new CountDownLatch(count);
+        final CountDownLatch startingPistol = new CountDownLatch(1);
+
+        for (int i = 0; i < count; i++) {
+            Thread thread = new Thread(new Runnable() {
+                public void run() {
+                    bean.checkout(startingLine, startingPistol);
+                }
+            });
+            thread.setDaemon(true);
+            thread.start();
+        }
+
+        startingLine.await(60, TimeUnit.SECONDS);
+
+        return startingPistol;
+    }
+
+
+    @Monitor
+    public static class CounterBean {
+
+        public static AtomicInteger instances = new AtomicInteger();
+        public static AtomicInteger discardedInstances = new AtomicInteger();
+
+        private int count;
+
+        public CounterBean() {
+            count = instances.incrementAndGet();
+        }
+
+        @PostConstruct
+        private void construct() {
+        }
+
+        @PreDestroy
+        private void destroy() {
+        }
+
+        public void red() {
+        }
+
+        public void green() {
+        }
+
+        public void blue() {
+        }
+
+        public void checkout(CountDownLatch startingLine, CountDownLatch 
startPistol) {
+            try {
+                startingLine.countDown();
+                startPistol.await(60, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                Thread.interrupted();
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+}

Propchange: 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessStatisticsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to