/**********************************************************************
Copyright (c) 2014 Kaarel Kann and others. All rights reserved.
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.

Contributors :
 ...
***********************************************************************/
package org.datanucleus.test;

import org.junit.*;
import javax.jdo.*;

import java.util.Random;
import java.util.concurrent.Semaphore;

import mydomain.model.*;
import org.datanucleus.util.NucleusLogger;

public class SimpleTest
{
    private Random r = new Random();

    /**
     * Test for the retrieval of objects using pm.getObjectById, in a separate ExecutionContext multithreaded.
     * @throws Exception If an error occurs in the multithreading process or creating a PMF.
     */
    @Test
    public void testGetObjectByIdInExecutionContext()
    throws Exception
    {
        NucleusLogger.GENERAL.info(">> test START");
        // TODO Obtain PMF using standard test mechanism
        final PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("MyTest");

        // Create data
        PersistenceManager pm = pmf.getPersistenceManager();
        Transaction tx = pm.currentTransaction();
        try
        {
            tx.begin();
            for (int i = 0; i < 2000; i++)
            {
                pm.makePersistent(new User((long)i));            
            }
            tx.commit();
        }
        finally
        {
            if (tx.isActive())
            {
                tx.rollback();
            }
            pm.close();
        }

        int threadCount = 1;
        final int count = 200000;
        final Semaphore semaphore = new Semaphore(threadCount);
        semaphore.acquire(threadCount);

        // Run test
        long start = System.currentTimeMillis();
        NucleusLogger.GENERAL.debug(">> Starting threads");

        for (int i = 0; i < threadCount; i++)
        {
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    for (int j = 0; j < count; j++) 
                    {
                        PersistenceManager pm = pmf.getPersistenceManager();
                        try
                        {
                            pm.currentTransaction().begin();
                            for (long ctr = 0; ctr < 5; ctr++) 
                            {
                                User ro = null;
                                long id = r.nextInt(2000);
                                try 
                                {
                                    ro = pm.getObjectById(User.class, id);
                                } 
                                catch (Exception e) 
                                {
                                    ro = new User(id);
                                }
                                ro.getBalance();
                            }
                            pm.currentTransaction().commit();
                        }
                        catch (Exception e)
                        {
                            NucleusLogger.GENERAL.error(">> Exception in test", e);
                        }
                        finally 
                        {
                            pm.close();
                        }
                    }
                    semaphore.release();
                }
            }).start();
        }

        semaphore.acquire(threadCount);
        System.out.println("COMPLETE: getObjectById time(ms)=" + (System.currentTimeMillis() - start));
        NucleusLogger.GENERAL.info(">> test END");

        pmf.close();
    }
}

@@ -1136,16 +1136,62 @@
 readed.%0A
+     * This uses 2000 objects with 1 threads.%0A
      * @
@@ -1344,17 +1344,668 @@
 nContext
-(
+1()%0A    throws Exception%0A    %7B%0A        performGetObjectByIdMultithreadTest(1, 2000, 200000);%0A    %7D%0A%0A    /**%0A     * Test for the retrieval of objects using pm.getObjectById, in a separate ExecutionContext multithreaded.%0A     * This uses 60000 objects with 10 threads.%0A     * @throws Exception If an error occurs in the multithreading process or creating a PMF.%0A     */%0A    @Test%0A    public void testGetObjectByIdInExecutionContext2()%0A    throws Exception%0A    %7B%0A        performGetObjectByIdMultithreadTest(10, 2000, 60000);%0A    %7D%0A%0A    public void performGetObjectByIdMultithreadTest(final int numThreads, final int numObjects, final int numTriesPerThread
 )%0A    th
@@ -2444,20 +2444,26 @@
  0; i %3C 
-2000
+numObjects
 ; i++)%0A 
@@ -2767,17 +2767,26 @@
 Count = 
-1
+numThreads
 ;%0A      
@@ -2805,22 +2805,33 @@
 count = 
-200000
+numTriesPerThread
 ;%0A      
@@ -3389,32 +3389,98 @@
 tenceManager();%0A
+                        Transaction tx = pm.currentTransaction();%0A
                 
@@ -3545,39 +3545,18 @@
         
-pm.currentTransaction()
+tx
 .begin()
@@ -3751,20 +3751,26 @@
 nextInt(
-2000
+numObjects
 );%0A     
@@ -4228,39 +4228,18 @@
         
-pm.currentTransaction()
+tx
 .commit(
@@ -4498,32 +4498,186 @@
               %7B%0A
+                            if (tx.isActive())%0A                            %7B%0A                                tx.rollback();%0A                            %7D%0A
                 
@@ -4933,16 +4933,111 @@
 jectById
+(objs=%22 + numObjects + %22, threads=%22 + numThreads + %22, triesPerThread=%22 + numTriesPerThread + %22)
  time(ms

add extra test with multithreads