package alma.acs.cdb.tests; import java.util.concurrent.Callable; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import org.omg.CORBA.ORB; import alma.acs.concurrent.ThreadBurstExecutorService; import alma.acs.util.ACSPorts; import com.cosylab.CDB.DAL; import com.cosylab.CDB.JDALHelper; import junit.framework.TestCase; /** * This class stresses the DAL, by sending it different calls combinations, sequentially or concurrently. * It prints some nice numbers on the screen, but it could also give some simple asserts as it is a unit test * @author rtobar */ public class PerformanceTest extends TestCase { private String strIOR = "corbaloc::" + ACSPorts.getIP() + ":" + ACSPorts.getCDBPort() + "/CDB"; private ORB orb; private DAL dal; private static final int CALLS_PER_SECOND_TRIES = 500; private static final int SEQUENTIAL_CALLS_ITERATIONS = 50; private static final int CONCURRENT_CALLS_ITERATIONS = 50; private static final int NUMBER_OF_SEQUENTIAL_CALLS = 100; private static final int NUMBER_OF_CONCURRENT_CALLS = 100; private static final int [] concurrentCallsIterations = {1, 2, 4, 8, 16}; // Existing nodes in the CDB used for querying private static final String MANAGER_DAO = "MACI/Managers/Manager"; private static final String CONTAINER_DAO = "MACI/Containers/Container"; private static final String TESTPS_DAO = "alma/TEST_PS_1"; private static final String FILTERWHEEL_DAO = "alma/FILTERWHEEL1"; private static final String COMPONENTS_DAO = "MACI/Components"; private static final String ABM001_DAO = "MACI/Components/CONTROL/AmbManager/ABM001"; private static final String ABM002_DAO = "MACI/Components/CONTROL/AmbManager/ABM002"; private static final String ARTM_DAO = "MACI/Components/CONTROL/AmbManager/ARTM"; private static final String DMC_DAO = "MACI/Components/CONTROL/AmbManager/DMC"; private static final String ANTENNA_DAO = "MACI/Components/CONTROL/Antenna"; private static final String GPS_DAO = "MACI/Components/CONTROL/GPS"; private static final String OPERATOR_DAO = "MACI/Components/CONTROL/Operator"; private static final String SNDLONODE40_DAO = "MACI/Components/CONTROL/SecondLO/Node0x40/Generic"; private static final String SNDLONODE41_DAO = "MACI/Components/CONTROL/SecondLO/Node0x41/Generic"; private static final String SNDLONODE42_DAO = "MACI/Components/CONTROL/SecondLO/Node0x42/Generic"; private static final String SNDLONODE43_DAO = "MACI/Components/CONTROL/SecondLO/Node0x43/Generic"; // Non-existing nodes in the CDB used for querying private static final String NONEXISTING01 = "MACI/Components/CONTROL/MyOwnAntenna01"; private static final String NONEXISTING02 = "MACI/Components/CONTROL/MyOwnAntenna02"; private static final String NONEXISTING03 = "MACI/Components/CONTROL/MyOwnAntenna03"; private static final String NONEXISTING04 = "MACI/Components/CONTROL/MyOwnAntenna04"; private static final String NONEXISTING05 = "MACI/Components/CONTROL/MyOwnAntenna05"; private static final String NONEXISTING06 = "MACI/Components/CONTROL/MyOwnAntenna06"; private static final String NONEXISTING07 = "MACI/Components/CONTROL/MyOwnAntenna07"; private static final String NONEXISTING08 = "MACI/Components/CONTROL/MyOwnAntenna08"; private static final String NONEXISTING09 = "Lala/Lalo09"; private static final String NONEXISTING10 = "Lala/Lalo10"; private static final String NONEXISTING11 = "Lala/Lalo11"; private static final String NONEXISTING12 = "Lala/Lalo12"; private static final String NONEXISTING13 = "Lala/Lalo13"; private static final String NONEXISTING14 = "Lala/Lalo14"; private static final String NONEXISTING15 = "Lala/Lalo15"; private static final String NONEXISTING16 = "Lala/Lalo16"; // Semi-existing nodes in the CDB used for querying private static final String SEMIEXISTING01 = "MACI/Containers/EmptyContainerDefinition01"; private static final String SEMIEXISTING02 = "MACI/Containers/EmptyContainerDefinition02"; private static final String SEMIEXISTING03 = "MACI/Containers/EmptyContainerDefinition03"; private static final String SEMIEXISTING04 = "MACI/Containers/EmptyContainerDefinition04"; private static final String SEMIEXISTING05 = "MACI/Containers/EmptyContainerDefinition05"; private static final String SEMIEXISTING06 = "MACI/Containers/EmptyContainerDefinition06"; private static final String SEMIEXISTING07 = "MACI/Containers/EmptyContainerDefinition07"; private static final String SEMIEXISTING08 = "MACI/Containers/EmptyContainerDefinition08"; private static final String SEMIEXISTING09 = "MACI/Containers/EmptyContainerDefinition09"; private static final String SEMIEXISTING10 = "MACI/Containers/EmptyContainerDefinition10"; private static final String SEMIEXISTING11 = "MACI/Containers/EmptyContainerDefinition11"; private static final String SEMIEXISTING12 = "MACI/Containers/EmptyContainerDefinition12"; private static final String SEMIEXISTING13 = "MACI/Containers/EmptyContainerDefinition13"; private static final String SEMIEXISTING14 = "MACI/Containers/EmptyContainerDefinition14"; private static final String SEMIEXISTING15 = "MACI/Containers/EmptyContainerDefinition15"; private static final String SEMIEXISTING16 = "MACI/Containers/EmptyContainerDefinition16"; protected void setUp() throws Exception { super.setUp(); String args[] = {}; orb = ORB.init(args, null); dal = JDALHelper.narrow(orb.string_to_object(strIOR)); } private void runConcurrentCalls(String []daos) throws Exception { long start; long end; double average; ThreadBurstExecutorService service; ThreadFactory threadFactory = new ThreadFactory(){ public Thread newThread(Runnable r) { return new Thread(r); } }; for (int j = 0; j != concurrentCallsIterations.length; j++) { System.out.println(" Asking for " + concurrentCallsIterations[j] + " nodes on each call"); average = 0; for (int iteration = 0; iteration != CONCURRENT_CALLS_ITERATIONS; iteration++) { service = new ThreadBurstExecutorService(threadFactory); for (int i = 0; i != NUMBER_OF_CONCURRENT_CALLS; i++) service .submit(new DALClientCallable(daos, concurrentCallsIterations[j]), 30, TimeUnit.SECONDS); start = System.currentTimeMillis(); service.executeAllAndWait(30, TimeUnit.SECONDS); end = System.currentTimeMillis(); average += (end - start); } System.out.println(" Concurrent calls: " + NUMBER_OF_CONCURRENT_CALLS + ". Different nodes: " + daos.length + ". Tries: " + CONCURRENT_CALLS_ITERATIONS + ". Average time: " + average / CONCURRENT_CALLS_ITERATIONS + " [ms]"); } System.out.println(""); } private void runSequentialCalls(String []daos) { long start; long end; double average = 0; for (int iterations = 0; iterations != SEQUENTIAL_CALLS_ITERATIONS; iterations++) { start = System.currentTimeMillis(); for (int i = 0; i != NUMBER_OF_SEQUENTIAL_CALLS; i++) { int index = (int)(Math.random()*(daos.length-1)); try { dal.get_DAO(daos[index]); } catch (Exception e) { // Do nothing } } end = System.currentTimeMillis(); average += (end-start); } System.out.println("Sequential calls: " + NUMBER_OF_SEQUENTIAL_CALLS + ". Different nodes: " + daos.length + ". Tries: " + SEQUENTIAL_CALLS_ITERATIONS + ". Average time: " + average/SEQUENTIAL_CALLS_ITERATIONS + " [ms]"); } public void testConcurrentCalls() throws Exception { System.out.println("Stressing the get_DAO() method with concurrent threads"); System.out.println("======================================================"); runConcurrentCalls( new String[] {MANAGER_DAO} ); runConcurrentCalls( new String[] {MANAGER_DAO, CONTAINER_DAO, TESTPS_DAO, FILTERWHEEL_DAO} ); runConcurrentCalls( new String[] {MANAGER_DAO, CONTAINER_DAO, TESTPS_DAO, FILTERWHEEL_DAO, COMPONENTS_DAO, ABM001_DAO, ABM002_DAO, ARTM_DAO, DMC_DAO, ANTENNA_DAO, GPS_DAO, OPERATOR_DAO, SNDLONODE40_DAO, SNDLONODE41_DAO, SNDLONODE42_DAO, SNDLONODE43_DAO} ); } public void testSequentialCalls() throws Exception { System.out.println("Stressing the get_DAO() method with sequential threads"); System.out.println("======================================================"); runSequentialCalls( new String[] {MANAGER_DAO} ); runSequentialCalls( new String[] {MANAGER_DAO, CONTAINER_DAO, TESTPS_DAO, FILTERWHEEL_DAO} ); runSequentialCalls( new String[] {MANAGER_DAO, CONTAINER_DAO, TESTPS_DAO, FILTERWHEEL_DAO, COMPONENTS_DAO, ABM001_DAO, ABM002_DAO, ARTM_DAO, DMC_DAO, ANTENNA_DAO, GPS_DAO, OPERATOR_DAO, SNDLONODE40_DAO, SNDLONODE41_DAO, SNDLONODE42_DAO, SNDLONODE43_DAO} ); } public void testCallsPerSecond() throws Exception { System.out.println("Measuring average call/s"); System.out.println("========================"); double average = 0; for(int i=0; i!= CALLS_PER_SECOND_TRIES; i++) { CallerTask ct = new CallerTask(MANAGER_DAO); Thread t = new Thread(ct); t.start(); Thread.sleep(1000); ct.end(); average += ct.numberOfCalls(); } System.out.println("Average sequential calls/s: " + (average/CALLS_PER_SECOND_TRIES)); } public void testNonExistingConcurrentCalls() throws Exception { System.out.println("Stressing the get_DAO() MISSING NODES (concurrent threads)"); System.out.println("=========================================================="); runConcurrentCalls( new String[] {NONEXISTING01} ); runConcurrentCalls( new String[] {NONEXISTING01, NONEXISTING02, NONEXISTING03, NONEXISTING04} ); runConcurrentCalls( new String[] {NONEXISTING01, NONEXISTING02, NONEXISTING03, NONEXISTING04, NONEXISTING05, NONEXISTING06, NONEXISTING07, NONEXISTING08, NONEXISTING09, NONEXISTING10, NONEXISTING11, NONEXISTING12, NONEXISTING13, NONEXISTING14, NONEXISTING15, NONEXISTING16} ); } public void testNonExistingSequentialCalls() throws Exception { System.out.println("Stressing the get_DAO() MISSING NODES (sequential threads)"); System.out.println("=========================================================="); runSequentialCalls( new String[] {NONEXISTING01} ); runSequentialCalls( new String[] {NONEXISTING01, NONEXISTING02, NONEXISTING03, NONEXISTING04} ); runSequentialCalls( new String[] {NONEXISTING01, NONEXISTING02, NONEXISTING03, NONEXISTING04, NONEXISTING05, NONEXISTING06, NONEXISTING07, NONEXISTING08, NONEXISTING09, NONEXISTING10, NONEXISTING11, NONEXISTING12, NONEXISTING13, NONEXISTING14, NONEXISTING15, NONEXISTING16} ); } public void testNonExistingCallsPerSecond() throws Exception { System.out.println("Measuring average call/s MISSING NODES"); System.out.println("======================================"); double average = 0; for(int i=0; i!= CALLS_PER_SECOND_TRIES; i++) { CallerTask ct = new CallerTask(NONEXISTING01); Thread t = new Thread(ct); t.start(); Thread.sleep(1000); ct.end(); average += ct.numberOfCalls(); } System.out.println("Average sequential calls/s: " + (average/CALLS_PER_SECOND_TRIES)); } public void testSemiExistingConcurrentCalls() throws Exception { System.out.println("Stressing the get_DAO() MISSING NODES (concurrent threads)"); System.out.println("=========================================================="); runConcurrentCalls( new String[] {SEMIEXISTING01} ); runConcurrentCalls( new String[] {SEMIEXISTING01, SEMIEXISTING02, SEMIEXISTING03, SEMIEXISTING04} ); runConcurrentCalls( new String[] {SEMIEXISTING01, SEMIEXISTING02, SEMIEXISTING03, SEMIEXISTING04, SEMIEXISTING05, SEMIEXISTING06, SEMIEXISTING07, SEMIEXISTING08, SEMIEXISTING09, SEMIEXISTING10, SEMIEXISTING11, SEMIEXISTING12, SEMIEXISTING13, SEMIEXISTING14, SEMIEXISTING15, SEMIEXISTING16} ); } public void testSemiExistingSequentialCalls() throws Exception { System.out.println("Stressing the get_DAO() MISSING NODES (sequential threads)"); System.out.println("=========================================================="); runSequentialCalls( new String[] {SEMIEXISTING01} ); runSequentialCalls( new String[] {SEMIEXISTING01, SEMIEXISTING02, SEMIEXISTING03, SEMIEXISTING04} ); runSequentialCalls( new String[] {SEMIEXISTING01, SEMIEXISTING02, SEMIEXISTING03, SEMIEXISTING04, SEMIEXISTING05, SEMIEXISTING06, SEMIEXISTING07, SEMIEXISTING08, SEMIEXISTING09, SEMIEXISTING10, SEMIEXISTING11, SEMIEXISTING12, SEMIEXISTING13, SEMIEXISTING14, SEMIEXISTING15, SEMIEXISTING16} ); } public void testSemiExistingCallsPerSecond() throws Exception { System.out.println("Measuring average call/s MISSING NODES"); System.out.println("======================================"); double average = 0; for(int i=0; i!= CALLS_PER_SECOND_TRIES; i++) { CallerTask ct = new CallerTask(SEMIEXISTING01); Thread t = new Thread(ct); t.start(); Thread.sleep(1000); ct.end(); average += ct.numberOfCalls(); } System.out.println("Average sequential calls/s: " + (average/CALLS_PER_SECOND_TRIES)); } protected void tearDown() throws Exception { super.tearDown(); dal._release(); orb.destroy(); } private class DALClientCallable implements Callable<Void> { private int _iterations; private String[] _daos; public DALClientCallable(String []daos, int iterations) { _daos = daos; _iterations = iterations; } public Void call() throws Exception { for(int i=0; i!= _iterations; i++) { int index = (int)(Math.random()*(_daos.length-1)); dal.get_DAO(_daos[index]); } return null; } } private class CallerTask implements Runnable { private boolean keepRunning = true; private long _calls = 0; private String _dao; public CallerTask(String dao) { _dao = dao; } public void run() { while (keepRunning) { try { _calls++; dal.get_DAO(_dao); } catch (Exception e) { // Nothing special } } } public void end() { keepRunning = false; } public long numberOfCalls() { return _calls; } } }