You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sirona.apache.org by rm...@apache.org on 2014/03/23 17:21:24 UTC

svn commit: r1580521 - in /incubator/sirona/trunk/agent/javaagent: ./ src/main/java/org/apache/sirona/javaagent/ src/test/java/org/apache/sirona/javaagent/ src/test/java/org/apache/test/sirona/javaagent/

Author: rmannibucau
Date: Sun Mar 23 16:21:23 2014
New Revision: 1580521

URL: http://svn.apache.org/r1580521
Log:
adding few more tests

Added:
    incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/InJvmTransformerRunner.java
      - copied, changed from r1580475, incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/JavaAgentRunner.java
    incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/Transformers.java
      - copied, changed from r1580475, incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/AgentArgs.java
    incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/OpenEJBTest.java
    incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/OpenJPATest.java
      - copied, changed from r1580475, incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/DebugTest.java
Removed:
    incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/DebugTest.java
Modified:
    incubator/sirona/trunk/agent/javaagent/pom.xml
    incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/javaagent/SironaTransformer.java
    incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/SimpleTest.java

Modified: incubator/sirona/trunk/agent/javaagent/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/pom.xml?rev=1580521&r1=1580520&r2=1580521&view=diff
==============================================================================
--- incubator/sirona/trunk/agent/javaagent/pom.xml (original)
+++ incubator/sirona/trunk/agent/javaagent/pom.xml Sun Mar 23 16:21:23 2014
@@ -67,6 +67,31 @@
       <version>3.2.1</version>
       <scope>test</scope>
     </dependency>
+    <!-- saw some issues in EE context so importing it brutally for testing -->
+    <dependency>
+      <groupId>org.apache.openejb</groupId>
+      <artifactId>javaee-api</artifactId>
+      <version>6.0-5</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.openjpa</groupId>
+      <artifactId>openjpa</artifactId>
+      <version>2.3.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.openejb</groupId>
+      <artifactId>openejb-core</artifactId>
+      <version>4.6.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>2.4</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>

Modified: incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/javaagent/SironaTransformer.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/javaagent/SironaTransformer.java?rev=1580521&r1=1580520&r2=1580521&view=diff
==============================================================================
--- incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/javaagent/SironaTransformer.java (original)
+++ incubator/sirona/trunk/agent/javaagent/src/main/java/org/apache/sirona/javaagent/SironaTransformer.java Sun Mar 23 16:21:23 2014
@@ -47,7 +47,7 @@ public class SironaTransformer implement
     protected byte[] doTransform(final String className, final byte[] classfileBuffer) {
         try {
             final ClassReader reader = new ClassReader(classfileBuffer);
-            final ClassWriter writer = new SironaClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
+            final ClassWriter writer = new SironaClassWriter(reader, ClassWriter.COMPUTE_FRAMES);
             final SironaClassVisitor advisor = new SironaClassVisitor(writer, className);
             reader.accept(advisor, ClassReader.SKIP_FRAMES);
 

Copied: incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/InJvmTransformerRunner.java (from r1580475, incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/JavaAgentRunner.java)
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/InJvmTransformerRunner.java?p2=incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/InJvmTransformerRunner.java&p1=incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/JavaAgentRunner.java&r1=1580475&r2=1580521&rev=1580521&view=diff
==============================================================================
--- incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/JavaAgentRunner.java (original)
+++ incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/InJvmTransformerRunner.java Sun Mar 23 16:21:23 2014
@@ -16,234 +16,146 @@
  */
 package org.apache.sirona.javaagent;
 
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.text.StrSubstitutor;
-import org.junit.Ignore;
-import org.junit.internal.TextListener;
-import org.junit.runner.Description;
-import org.junit.runner.JUnitCore;
-import org.junit.runner.Result;
-import org.junit.runner.notification.Failure;
-import org.junit.runner.notification.RunNotifier;
+import org.apache.commons.io.IOUtils;
+import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
+import org.apache.openjpa.enhance.AsmAdaptor;
+import org.apache.openjpa.enhance.PCClassFileTransformer;
+import org.apache.openjpa.enhance.PCEnhancer;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.PersistenceMetaDataFactory;
 import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.ParentRunner;
 import org.junit.runners.model.InitializationError;
 import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+import serp.bytecode.BCClass;
+import serp.bytecode.Project;
 
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
+import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-// only works with standard runner and surefire
-public class JavaAgentRunner extends BlockJUnit4ClassRunner {
-    public JavaAgentRunner(final Class<?> klass) throws InitializationError {
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+public class InJvmTransformerRunner extends BlockJUnit4ClassRunner {
+    private final Class<?>[] transformers;
+    private ClassLoader testLoader = null;
+    private ClassLoader originalLoader = null;
+
+    public InJvmTransformerRunner(final Class<?> klass) throws InitializationError {
         super(klass);
-    }
 
-    // internal call to execute a single test
-    public static void main(final String[] args) throws Exception {
-        final Class<?> testClass = Class.forName(args[0]);
+        final Transformers customTransformers = klass.getAnnotation(Transformers.class);
+        if (customTransformers != null) {
+            transformers = customTransformers.value();
+        } else {
+            transformers = new Class[] { SironaTransformer.class };
+        }
+
+        Thread.currentThread().setContextClassLoader(getTestLoader());
+        try {
+            final Class<?> testTransformedClass = testLoader.loadClass(getTestClass().getName());
+            final Field f = ParentRunner.class.getDeclaredField("fTestClass");
+            f.setAccessible(true);
+            f.set(this, new TestClass(testTransformedClass));
+        } catch (final Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            Thread.currentThread().setContextClassLoader(originalLoader);
+        }
+    }
 
-        final BlockJUnit4ClassRunner filteredRunner = new BlockJUnit4ClassRunner(testClass) {
-            @Override
-            protected List<FrameworkMethod> getChildren() {
-                try {
-                    return Arrays.asList(new FrameworkMethod(testClass.getMethod(args[1])));
-                } catch (final NoSuchMethodException e) {
-                    throw new IllegalArgumentException(e);
+    private ClassLoader getTestLoader() {
+        if (testLoader == null) {
+            originalLoader = Thread.currentThread().getContextClassLoader();
+            testLoader = new URLClassLoader(new URL[0]) {
+                @Override
+                public String toString() {
+                    return InJvmTransformerRunner.class.getSimpleName() + "-" + super.toString();
                 }
-            }
-        };
 
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final JUnitCore jUnitCore = new JUnitCore();
-        jUnitCore.addListener(new TextListener(new PrintStream(baos)));
-        final Result result = jUnitCore.run(filteredRunner);
+                @Override
+                public Class<?> loadClass(String name) throws ClassNotFoundException {
+                    if (!name.startsWith(getTestClass().getName())) {
+                        return getParent().loadClass(name);
+                    }
 
-        if (result.wasSuccessful()) {
-            System.exit(0);
+                    try {
+                        final String resourceName = name.replaceAll("\\.", "/") + ".class";
+                        final InputStream is = getResourceAsStream(resourceName);
+                        if (is == null) {
+                            throw new ClassNotFoundException(name);
+                        }
+
+                        final String className = resourceName.replace(".class", "");
+
+                        byte[] buffer = IOUtils.toByteArray(is);
+                        for (final Class<?> t : transformers) {
+                            if (SironaTransformer.class.equals(t)) {
+                                final SironaTransformer transformer = new SironaTransformer(false);
+                                buffer = transformer.transform(this, className, null, null, buffer);
+                            } else if (PCClassFileTransformer.class.equals(t)) {
+                                if (name.endsWith("Entity")) {
+                                    // hacky but avoid to build a full openjpa project/context
+                                    final PersistenceMetaDataFactory factory = new PersistenceMetaDataFactory();
+                                    factory.setTypes("org.apache.test.sirona.javaagent.OpenJPATest$ServiceSquareEntity");
+
+                                    final MetaDataRepository repos = new MetaDataRepository();
+                                    repos.setConfiguration(new OpenJPAConfigurationImpl());
+                                    repos.setMetaDataFactory(factory);
+
+                                    final BCClass type = new Project().loadClass(new ByteArrayInputStream(buffer), new URLClassLoader(new URL[0], originalLoader));
+                                    final PCEnhancer enhancer = new PCEnhancer(repos.getConfiguration(), type, repos, this);
+                                    enhancer.setAddDefaultConstructor(true);
+                                    enhancer.setEnforcePropertyRestrictions(true);
+
+                                    if (enhancer.run() != PCEnhancer.ENHANCE_NONE) {
+                                        final BCClass pcb = enhancer.getPCBytecode();
+                                        final byte[] transformed = AsmAdaptor.toByteArray(pcb, pcb.toByteArray());
+                                        if (transformed != null) {
+                                            buffer = transformed;
+                                        }
+                                    }
+                                }
+                            } else {
+                                buffer = ClassFileTransformer.class.cast(t.newInstance()).transform(this, className, null, null, buffer);
+                            }
+                        }
+                        return defineClass(name, buffer, 0, buffer.length);
+                    } catch (final Throwable t) {
+                        throw new ClassNotFoundException(t.getMessage(), t);
+                    }
+                }
+            };
         }
-        System.err.println(new String(baos.toByteArray()));
-        System.exit(-1);
+        return testLoader;
     }
 
     @Override
-    protected Statement classBlock(final RunNotifier notifier) {
+    protected Statement withBeforeClasses(final Statement statement) {
+        final Statement beforeClasses = super.withBeforeClasses(statement);
         return new Statement() {
             @Override
             public void evaluate() throws Throwable {
-                for (final FrameworkMethod mtd : getChildren()) {
-                    if (mtd.getAnnotation(Ignore.class) != null) {
-                        notifier.fireTestIgnored(describeChild(mtd));
-                        continue;
-                    }
-
-                    final Description description = describeChild(mtd);
-                    notifier.fireTestRunStarted(description);
-                    try {
-                        executeMethod(mtd, description, notifier);
-                    } catch (final Exception e) {
-                        notifier.fireTestFailure(new Failure(description, e));
-                    } finally {
-                        notifier.fireTestFinished(description);
-                    }
-                }
+                Thread.currentThread().setContextClassLoader(testLoader);
+                beforeClasses.evaluate();
             }
         };
     }
 
-    private void executeMethod(final FrameworkMethod mtd, final Description description, final RunNotifier notifier) throws IOException, InterruptedException {
-        final Process process = Runtime.getRuntime().exec(buildProcessArgs(mtd));
-
-        slurp(process.getInputStream()).await();
-        slurp(process.getErrorStream()).await();
-
-        Runtime.getRuntime().addShutdownHook(new Thread() { // ctrl+x during the build
-            @Override
-            public void run() {
-                try {
-                    process.exitValue();
-                } catch (final IllegalStateException ise) {
-                    process.destroy();
-                }
-            }
-        });
-
-        process.waitFor();
-
-        if (process.exitValue() != 0) {
-            notifier.fireTestFailure(new Failure(description, new RuntimeException("exit code = " + process.exitValue())));
-        }
-    }
-
-    protected String[] buildProcessArgs(final FrameworkMethod mtd) throws IOException {
-        final Collection<String> args = new ArrayList<String>();
-
-        args.add( findJava() );
-
-        AgentArgs agentArgs = mtd.getAnnotation( AgentArgs.class );
-
-        String maxMem = agentArgs == null ? "" : agentArgs.maxMem();
-
-        if ( maxMem.length() > 0 )
-        {
-            args.add( "-Xmx" + maxMem );
-        }
-
-        String minMem = agentArgs == null ? "" : agentArgs.minMem();
-
-        if ( minMem.length() > 0 )
-        {
-            args.add( "-Xms" + minMem );
-        }
-
-        String javaAgentArgs =
-            agentArgs == null ? null : StrSubstitutor.replace( agentArgs.value(), System.getProperties() );
-        args.add( "-javaagent:" + buildJavaagent() + "=" + ( javaAgentArgs == null ? "" : javaAgentArgs ) );
-
-        if ( Boolean.getBoolean( "test.debug.remote" ) )
-        {
-            args.add( "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" + Integer.getInteger(
-                "test.debug.remote.port", 5005 ) );
-        }
-        if ( agentArgs != null && agentArgs.noVerify() )
-        {
-            args.add( "-noverify" );
-        }
-
-        String sysProps = agentArgs == null ? "" : agentArgs.sysProps();
-
-        if (sysProps.length() > 0){
-             String[] splittedProps = StringUtils.split( sysProps, "|" );
-            for (String props : splittedProps)
-            {
-                String[] prop = StringUtils.split( props, "=" );
-                String key = prop[0];
-                String value = "";
-                if (prop.length>1){
-                    value = prop[1];
-                }
-                args.add( "-D" + key + "=" + StrSubstitutor.replace(  value, System.getProperties() ) );
-            }
-        }
-
-        args.add( "-cp" );
-        args.add(removeAgentFromCp(System.getProperty("surefire.test.class.path", System.getProperty("java.class.path"))));
-        args.add(JavaAgentRunner.class.getName());
-        args.add(mtd.getMethod().getDeclaringClass().getName());
-        args.add(mtd.getName());
-
-        System.out.println("Running " + args.toString().replace(",", "").substring(1).replace("]", ""));
-
-        return args.toArray(new String[args.size()]);
-    }
-
-    private static String removeAgentFromCp(final String property) {
-        final String path = "target" + File.separator + "classes";
-        final String sep = System.getProperty("path.separator");
-        final String[] segments = property.split(sep);
-        final StringBuilder builder = new StringBuilder(property.length());
-        for (final String segment : segments) {
-            if (!segment.endsWith(path)) {
-                builder.append(segment).append(sep);
-            }
-        }
-        builder.setLength(builder.length() - 1);
-        return builder.toString();
-    }
-
-    private static CountDownLatch slurp(final InputStream in) {
-        final CountDownLatch latch = new CountDownLatch(1);
-        new Thread() {
+    @Override
+    protected Statement withAfterClasses(final Statement statement) {
+        final Statement afterClasses = super.withAfterClasses(statement);
+        return new Statement() {
             @Override
-            public void run() {
-                int i;
+            public void evaluate() throws Throwable {
                 try {
-                    while ((i = in.read()) != -1) {
-                        System.out.write(i);
-                    }
-                    latch.countDown();
-                } catch (final Exception e) {
-                    latch.countDown();
+                    afterClasses.evaluate();
+                } finally {
+                    Thread.currentThread().setContextClassLoader(originalLoader);
                 }
             }
-        }.start();
-        return latch;
-    }
-
-    protected String buildJavaagent() throws IOException {
-        final File[] files = new File(System.getProperty("javaagent.jar.directory", "target")).listFiles(new FilenameFilter() {
-            @Override
-            public boolean accept(File dir, String name) {
-                return name.startsWith( System.getProperty( "javaagent.jar.name.start", "sirona-javaagent-" )) //
-                        && name.endsWith(".jar") //
-                        && name.endsWith("-shaded.jar");
-            }
-        });
-        return files[0].getAbsolutePath();
-    }
-
-    private static String findJava() {
-        {
-            String home = System.getProperty("java.home");
-            if (home != null) {
-                return new File(home, "bin/java").getAbsolutePath();
-            }
-        }
-        for (final String env : new String[]{"JAVA_HOME", "JRE_HOME"}) {
-            final String home = System.getenv(env);
-            if (home != null) {
-                return new File(home, "bin/java").getAbsolutePath();
-            }
-        }
-        return "java";
+        };
     }
 }

Copied: incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/Transformers.java (from r1580475, incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/AgentArgs.java)
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/Transformers.java?p2=incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/Transformers.java&p1=incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/AgentArgs.java&r1=1580475&r2=1580521&rev=1580521&view=diff
==============================================================================
--- incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/AgentArgs.java (original)
+++ incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/sirona/javaagent/Transformers.java Sun Mar 23 16:21:23 2014
@@ -21,24 +21,8 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-/**
- *
- */
-@Target( ElementType.METHOD)
-@Retention ( RetentionPolicy.RUNTIME )
-public @interface AgentArgs
-{
-    String value();
-
-    String maxMem() default "";
-
-    String minMem() default "";
-
-    boolean noVerify() default false;
-
-    /**
-     *
-     * @return system properties to use in the forked agent format: props1=value|props2=value
-     */
-    String sysProps() default "";
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Transformers {
+    Class<?>[] value() default { SironaTransformer.class };
 }

Added: incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/OpenEJBTest.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/OpenEJBTest.java?rev=1580521&view=auto
==============================================================================
--- incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/OpenEJBTest.java (added)
+++ incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/OpenEJBTest.java Sun Mar 23 16:21:23 2014
@@ -0,0 +1,259 @@
+/*
+ * 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.test.sirona.javaagent;
+
+import org.apache.openejb.util.proxy.LocalBeanProxyFactory;
+import org.apache.sirona.javaagent.InJvmTransformerRunner;
+import org.apache.sirona.repositories.Repository;
+import org.apache.xbean.finder.AnnotationFinder;
+import org.apache.xbean.finder.archive.ClassesArchive;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ejb.Lock;
+import javax.ejb.LockType;
+import javax.ejb.Singleton;
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.PersistenceContext;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.List;
+
+import static java.util.Collections.emptyList;
+import static org.junit.Assert.assertEquals;
+
+@RunWith(InJvmTransformerRunner.class)
+public class OpenEJBTest {
+    @Before
+    @After
+    public void reset() {
+        Repository.INSTANCE.reset();
+    }
+
+    @Test
+    public void checkScanning() {
+        // do bytecode parsing so ensure we are still valid
+        assertEquals(1, new AnnotationFinder(new ClassesArchive(TicTacToeServiceEJB.class))
+                .link().findMetaAnnotatedFields(PersistenceContext.class).size());
+    }
+
+    @Test
+    public void checkEJBAreInstrumented() throws Throwable {
+        assertEquals(0, Repository.INSTANCE.counters().size());
+        TicTacToeServiceEJB.class.cast(LocalBeanProxyFactory.newProxyInstance(
+                Thread.currentThread().getContextClassLoader(),
+                new InvocationHandler() {
+                    @Override
+                    public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+                        return method.invoke(new TicTacToeServiceEJB(), args);
+                    }
+                }, TicTacToeServiceEJB.class))
+                .touch();
+        assertEquals(2, Repository.INSTANCE.counters().size());
+    }
+
+    @Singleton
+    @Lock(LockType.READ)
+    public static class TicTacToeServiceEJB {
+        @PersistenceContext(unitName = "tic-tac-toe")
+        private EntityManager em;
+
+        @Inject
+        private Integer size;
+
+        public void touch() {
+            // no-op
+        }
+
+        public Square play(final String partyId) {
+            return computerMove(partyId);
+        }
+
+        private Square computerMove(final String partyId) {
+            final Square[][] table = gameAsArray(partyId);
+            for (int i = 0; i < size; i++) {
+                for (int j = 0; j < size; j++) {
+                    if (table[i][j] == null) {
+                        return Square.newSquare(partyId, Square.Player.O, i + 1, j + 1);
+                    }
+                }
+            }
+            return null;
+        }
+
+        @TransactionAttribute(TransactionAttributeType.SUPPORTS)
+        public boolean hasPlayer(final String partyId, final int x, final int y) {
+            try {
+                final Square square = em.createNamedQuery("Square.findAllByPartyAndPosition", Square.class)
+                        .setParameter("partyId", partyId)
+                        .setParameter("x", x)
+                        .setParameter("y", y)
+                        .getSingleResult();
+                return square.getPlayer() != null;
+            } catch (final NoResultException nre) {
+                return false;
+            }
+        }
+
+        public boolean hasWon(final Square square) {
+            final Square.Player player = square.getPlayer();
+            final int x = square.getX() - 1;
+            final int y = square.getY() - 1;
+
+            final Square[][] array = gameAsArray(square.getPartyId());
+
+            for (int i = 0; i < size; i++) { // vertical
+                if (!isTheSamePlayer(player, array[x][i])) {
+                    break;
+                }
+                if (i == size - 1) {
+                    return true;
+                }
+            }
+            for (int i = 0; i < size; i++) { // horizontal
+                if (!isTheSamePlayer(player, array[i][y])) {
+                    break;
+                }
+                if (i == size - 1) {
+                    return true;
+                }
+            }
+            if (x == y) { // diagonal
+                for (int i = 0; i < size; i++) {
+                    if (!isTheSamePlayer(player, array[i][i])) {
+                        break;
+                    }
+                    if (i == size - 1) {
+                        return true;
+                    }
+                }
+            } else if (x == size - y - 1) { // anti-diagonal
+                for (int i = 0; i < size; i++) {
+                    final int xtmp = size - i - 1;
+                    if (!isTheSamePlayer(player, array[xtmp][i])) {
+                        break;
+                    }
+                    if (i == size - 1) {
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        public void savePosition(final Square square) {
+            em.persist(square);
+        }
+
+        private boolean isTheSamePlayer(final Square.Player player, final Square square) {
+            return square != null && square.getPlayer() != null && square.getPlayer().equals(player);
+        }
+
+        public Square[][] gameAsArray(final String partyId) {
+            final List<Square> entities = em.createNamedQuery("Square.findAllByParty", Square.class)
+                    .setParameter("partyId", partyId)
+                    .getResultList();
+
+            final Square[][] table = new Square[size][];
+            for (int i = 0; i < size; i++) {
+                table[i] = new Square[size];
+            }
+
+            if (entities != null) {
+                for (final Square s : entities) {
+                    table[s.getX() - 1][s.getY() - 1] = s;
+                }
+            }
+
+            return table;
+        }
+
+        public Collection<Square> findAll() {
+            final List<Square> list = em.createNamedQuery("Square.findAll", Square.class).getResultList();
+            if (list == null) {
+                return emptyList();
+            }
+            return list;
+        }
+    }
+
+    public static class Square {
+        public static enum Player {
+            O, X
+        }
+
+        private long id;
+        private Player player;
+
+        private String partyId;
+        private int x;
+        private int y;
+
+        public long getId() {
+            return id;
+        }
+
+        public String getPartyId() {
+            return partyId;
+        }
+
+        public void setPartyId(final String partyId) {
+            this.partyId = partyId;
+        }
+
+        public Player getPlayer() {
+            return player;
+        }
+
+        public void setPlayer(final Player player) {
+            this.player = player;
+        }
+
+        public int getX() {
+            return x;
+        }
+
+        public void setX(final int x) {
+            this.x = x;
+        }
+
+        public int getY() {
+            return y;
+        }
+
+        public void setY(final int y) {
+            this.y = y;
+        }
+
+        public static Square newSquare(final String partyId, final Square.Player player, final int x, final int y) {
+            final Square newServiceSquare = new Square();
+            newServiceSquare.setX(x);
+            newServiceSquare.setY(y);
+            newServiceSquare.setPartyId(partyId);
+            newServiceSquare.setPlayer(player);
+            return newServiceSquare;
+        }
+    }
+}

Copied: incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/OpenJPATest.java (from r1580475, incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/DebugTest.java)
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/OpenJPATest.java?p2=incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/OpenJPATest.java&p1=incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/DebugTest.java&r1=1580475&r2=1580521&rev=1580521&view=diff
==============================================================================
--- incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/DebugTest.java (original)
+++ incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/OpenJPATest.java Sun Mar 23 16:21:23 2014
@@ -16,40 +16,116 @@
  */
 package org.apache.test.sirona.javaagent;
 
-import org.apache.sirona.javaagent.AgentContext;
-import org.apache.sirona.javaagent.JavaAgentRunner;
+import org.apache.openjpa.enhance.PCClassFileTransformer;
+import org.apache.sirona.javaagent.InJvmTransformerRunner;
+import org.apache.sirona.javaagent.SironaTransformer;
+import org.apache.sirona.javaagent.Transformers;
+import org.apache.sirona.repositories.Repository;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-@RunWith(JavaAgentRunner.class)
-public class DebugTest {
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@Transformers({PCClassFileTransformer.class, SironaTransformer.class })
+@RunWith(InJvmTransformerRunner.class)
+public class OpenJPATest {
+    @Before
+    @After
+    public void reset() {
+        Repository.INSTANCE.reset();
+    }
+
     @Test
-    public void debug() throws Throwable {
-        new ServiceNoStaticTransform().f();
+    public void checkTheEntityIsUsableAndTransformationDidntFail() throws Throwable {
+        assertEquals(0, Repository.INSTANCE.counters().size());
+        final ServiceSquareEntity serviceSquareEntity = new ServiceSquareEntity();
+        serviceSquareEntity.setPlayer(ServiceSquareEntity.Player.O);
+        assertEquals("O", serviceSquareEntity.getPlayer().name());
+        assertEquals(5, Repository.INSTANCE.counters().size());
     }
 
-    public static class ServiceNoStaticTransform {
-        public void f() {
-            try {
-                throw new NullPointerException();
-            } catch (final NullPointerException iae) {
-                // no-op
-            }
-        }
-
-        public void f2() {
-            AgentContext localAgentContext = AgentContext.startOn(this, "org.apache.test.sirona.javaagent.DebugTest$ServiceNoStaticTransform.f");
-            try {
-                try {
-                    throw new NullPointerException();
-                } catch (NullPointerException iae) {
-                    localAgentContext.stop(null);
-                    return;
-                }
-            } catch (Throwable localThrowable) {
-                localAgentContext.stopWithException(localThrowable);
-                throw new RuntimeException(localThrowable);
-            }
+    @Entity
+    @NamedQueries({
+            @NamedQuery(
+                    name = "ServiceSquare.findAll",
+                    query = "select i from ServiceSquare i"),
+            @NamedQuery(
+                    name = "ServiceSquare.findAllByParty",
+                    query = "select i from ServiceSquare i where i.partyId = :partyId"),
+            @NamedQuery(
+                    name = "ServiceSquare.findAllByPartyAndPosition",
+                    query = "select i from ServiceSquare i where i.partyId = :partyId and i.x = :x and i.y = :y"),
+    })
+    public static class ServiceSquareEntity {
+        public static enum Player {
+            O, X
+        }
+
+        @Id
+        @GeneratedValue
+        private long id;
+
+        @Enumerated(EnumType.STRING)
+        private Player player;
+
+        private String partyId;
+        private int x;
+        private int y;
+
+        public long getId() {
+            return id;
+        }
+
+        public String getPartyId() {
+            return partyId;
+        }
+
+        public void setPartyId(final String partyId) {
+            this.partyId = partyId;
+        }
+
+        public Player getPlayer() {
+            return player;
+        }
+
+        public void setPlayer(final Player player) {
+            this.player = player;
+        }
+
+        public int getX() {
+            return x;
+        }
+
+        public void setX(final int x) {
+            this.x = x;
+        }
+
+        public int getY() {
+            return y;
+        }
+
+        public void setY(final int y) {
+            this.y = y;
+        }
+
+        public static ServiceSquareEntity newSquare(final String partyId, final ServiceSquareEntity.Player player, final int x, final int y) {
+            final ServiceSquareEntity newServiceSquareEntity = new ServiceSquareEntity();
+            newServiceSquareEntity.setX(x);
+            newServiceSquareEntity.setY(y);
+            newServiceSquareEntity.setPartyId(partyId);
+            newServiceSquareEntity.setPlayer(player);
+            return newServiceSquareEntity;
         }
     }
 }

Modified: incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/SimpleTest.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/SimpleTest.java?rev=1580521&r1=1580520&r2=1580521&view=diff
==============================================================================
--- incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/SimpleTest.java (original)
+++ incubator/sirona/trunk/agent/javaagent/src/test/java/org/apache/test/sirona/javaagent/SimpleTest.java Sun Mar 23 16:21:23 2014
@@ -102,6 +102,13 @@ public class SimpleTest {
     }
 
     @Test
+    public void alreadyTryCatchWithReturn() {
+        assertHits("org.apache.test.sirona.javaagent.SimpleTest$ServiceTransform.alreadyTryCatchWithReturnPrimitive", 0);
+        assertTrue(new ServiceTransform().alreadyTryCatchWithReturnPrimitive());
+        assertHits("org.apache.test.sirona.javaagent.SimpleTest$ServiceTransform.alreadyTryCatchWithReturnPrimitive", 1);
+    }
+
+    @Test
     public void primitive() {
         assertHits("org.apache.test.sirona.javaagent.SimpleTest$ServiceTransform.soPrimitive", 0);
         ServiceTransform.soPrimitive();
@@ -173,6 +180,14 @@ public class SimpleTest {
                 // no-op
             }
         }
+
+        public boolean alreadyTryCatchWithReturnPrimitive() {
+            try {
+                return true;
+            } catch (final NullPointerException iae) {
+                return false;
+            }
+        }
     }
 
     public static class ServiceNoStaticTransform {