/* * ALMA - Atacama Large Millimiter Array * (c) Universidad Tecnica Federico Santa Maria, 2008 * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package alma.acs.container.corba; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import alma.acs.component.client.ComponentClientTestCase; import alma.acs.monitoring.RemoteThreadsClient; import alma.acs.monitoring.RemoteThreadsMBean; import alma.acs.monitoring.RemoteThreadsUtil; import alma.jconttest.DummyComponent; import alma.jconttest.DummyComponentHelper; /** * JUnit test class for testing the {@link alma.acs.monitoring.RemoteThreadsMBean} * work over an ACS Container * @author rtobar * Created on Feb 25, 2008, 7:35:10 PM */ public class ContainerMonitorTest extends ComponentClientTestCase { private DummyComponent comp = null; private RemoteThreadsClient rtc = null; private RemoteThreadsMBean mbean = null; private int max_threads = 0; private int min_threads = 0; private final String DUMMYCOMP_TYPENAME = "IDL:alma/jconttest/DummyComponent:1.0"; private final String MAX_PROP = "jacorb.poa.thread_pool_max"; private final String MIN_PROP = "jacorb.poa.thread_pool_min"; private int MAX_ITERATIONS = 100; private volatile int[][] acsThreads = null; private volatile int[][] jacorbThreads = null; private volatile int acs = 0; private volatile int jacorb = 0; public ContainerMonitorTest(String name) throws Exception { super(name); } // Init all the JMX remote MBean stuff, the JacORB information, // and the connection to the DummyComponent protected void setUp() throws Exception { super.setUp(); int containerPID = 0; try { // The only way to get the java processes list is to use the // jps command (it's like a ps, but for only java processes). // The command output is parsed to get the name of the runnable // class. Then, we search for the alma.acs.container.AcsContainerRunner // class, and then for the name of the ontainer. Finally, we get the // associated PID, which we store. // // The sun.tools.jps.Jps class in the tools.jar jarfile is used // by the jps process. Anyways, this class only has a main // method, so no information can be retrieved by means of // public methods. So, if the main method is invoked in a static // way, the output should be parsed as well as it's being done // now (this is far more complex, since the stdout should be // redirected to another PrinterStream, and then read from it). // Better we execute the jps command and read directly from its // associated InputStream. String s; Process p = Runtime.getRuntime().exec("jps -lm"); BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); // read the output from the command while ((s = stdInput.readLine()) != null) { String[] ss = s.split("[\t ]+"); if (ss.length > 2) { if (ss[1].equals("alma.acs.container.AcsContainerRunner")) for (int i=2; i < ss.length; i++) { if (ss[i].equals("silentContainer")) { containerPID = Integer.valueOf(ss[0]); break; } } } } stdInput.close(); if (containerPID == 0) fail("silentContainer's PID not found."); m_logger.info("Got silentContainer's PID: " + containerPID); } catch (IOException e) { fail(e.getMessage()); } rtc = new RemoteThreadsClient(containerPID); assertNotNull(rtc); assertTrue(rtc.connect()); mbean = rtc.getMBean(); if( acsCorba.getORB() instanceof org.jacorb.orb.ORB ) { max_threads = ((org.jacorb.orb.ORB)acsCorba.getORB()).getConfiguration().getAttributeAsInteger(MAX_PROP); min_threads = ((org.jacorb.orb.ORB)acsCorba.getORB()).getConfiguration().getAttributeAsInteger(MIN_PROP); } m_logger.info("Max/Min for JacORB's thread pool: " + max_threads + "/" + min_threads); assertTrue(max_threads > min_threads); // 10 more threads to stress the container max_threads += 10; org.omg.CORBA.Object compObj = getContainerServices().getDefaultComponent(DUMMYCOMP_TYPENAME); assertNotNull(compObj); comp = DummyComponentHelper.narrow(compObj); String compName = comp.name(); assertNotNull(compName); acsThreads = new int[2][max_threads*MAX_ITERATIONS]; jacorbThreads = new int[2][max_threads*MAX_ITERATIONS]; } public void testStress() throws Exception { Thread []myThreads = new Thread[max_threads]; // Print some info that should be sed'ed and grep'ed by // tat .sed and .grep files m_logger.info("Total number of JacORB threads: " + mbean.getJacORBThreadsCount()); m_logger.info("Total number of ACS threads: " + mbean.getAcsContainerThreadsCount()); String threadInfo = RemoteThreadsUtil.printThreadsInfo(RemoteThreadsUtil.toThreadsInfo( mbean.getThreadsInfo("org.jacorb.poa.RequestProcessor",Thread.State.WAITING)), true ); String[] threadInfoSeparated = threadInfo.split("\n"); for(int i=0; i!= threadInfoSeparated.length; i++) m_logger.info(threadInfoSeparated[i]); // The present threads should be more that the min assertTrue(mbean.getThreadsCount("org.jacorb.poa.RequestProcessor",null) >= min_threads); // The present threads should be less than max assertTrue(mbean.getThreadsCount("org.jacorb.poa.RequestProcessor",null) <= max_threads); // Test the thread counting on idle mode for(int i = 0; i!= max_threads*MAX_ITERATIONS; i++) { acsThreads[0][acs++] = mbean.getAcsContainerThreadsCount(); jacorbThreads[0][jacorb++] = mbean.getThreadsCount("org.jacorb.poa.RequestProcessor",null); } acs = 0; jacorb = 0; // We create "max_threads" threads and use them to communicate with // the DummyComponent to just send information for (int i = 0; i < max_threads; i++) { myThreads[i] = new Thread(new Runnable() { // On each of them we collect data... public void run() { for(int i=0; i!=MAX_ITERATIONS ; i++) { comp.callThatTakesSomeTime(20); acsThreads[1][acs++] = mbean.getAcsContainerThreadsCount(); jacorbThreads[1][jacorb++] = mbean.getThreadsCount("org.jacorb.poa.RequestProcessor",null); } } }); } // init the threads for (int i = 0; i < max_threads; i++) { myThreads[i].start(); } // and join them for (int i = 0; i < max_threads; i++) { myThreads[i].join(); } } protected void tearDown() throws Exception { super.tearDown(); double acsAverageIdle = 0; double acsAverageStress = 0; double jacorbAverageIdle = 0; double jacorbAverageStress = 0; // Calculate the average of all the calls while idle for (int i = 0; i < max_threads*MAX_ITERATIONS; i++) { acsAverageIdle += acsThreads[0][i]; jacorbAverageIdle += jacorbThreads[0][i]; } // Calculate the average of all the calls under stress for (int i = 0; i < max_threads*MAX_ITERATIONS; i++) { acsAverageStress += acsThreads[1][i]; jacorbAverageStress += jacorbThreads[1][i]; } m_logger.info("ACS Container threads average (idle/stress): " + (acsAverageIdle/max_threads/MAX_ITERATIONS) + "/" + (acsAverageStress/max_threads/MAX_ITERATIONS) ); m_logger.info("JacORB threads average (idle/stress): " + (jacorbAverageIdle/max_threads/MAX_ITERATIONS) + "/" + (jacorbAverageStress/max_threads/MAX_ITERATIONS)); } }