/* * ALMA - Atacama Large Millimiter Array * (c) European Southern Observatory, 2004 * Copyright by ESO (in the framework of the ALMA collaboration), * All rights reserved * * 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; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import org.omg.CORBA.StringHolder; import alma.ACS.stringSeqHolder; import alma.ACSErrTypeCommon.CouldntPerformActionEx; import alma.ACSErrTypeCommon.wrappers.AcsJCouldntPerformActionEx; import alma.JavaContainerError.wrappers.AcsJContainerServicesEx; import alma.acs.component.ComponentQueryDescriptor; import alma.acs.component.client.AdvancedComponentClient; import alma.acs.component.client.ComponentClientTestCase; import alma.acs.container.corba.AcsCorba; import alma.acs.testsupport.tat.TATJUnitRunner.KeepTestOutput; import alma.acs.util.StopWatch; import alma.jconttest.ContainerServicesTester; import alma.jconttest.ContainerServicesTesterHelper; import alma.jconttest.DummyComponent; import alma.jconttest.DummyComponentHelper; import alma.maciErrType.wrappers.AcsJNoPermissionEx; /** * @author hsommer * created Sep 17, 2004 3:49:45 PM */ @KeepTestOutput // Todo: remove once we resolved the issue with spurious COMM_FAILURE exceptions. public class ComponentTestclient extends ComponentClientTestCase { private static final String CONTSRVCOMP_INSTANCE = "CONT_SERVICES_TESTER"; private static final String DEFAULT_DUMMYCOMP_INSTANCE = "DefaultDummyComp"; private static final String DUMMYCOMP2_TYPENAME = "IDL:alma/jconttest/DummyComponent2:1.0"; private ContainerServicesTester m_contSrvTesterComp; public ComponentTestclient() throws Exception { super("ComponentTestclient"); // System.out.println("JacORB dump incoming = " + System.getProperty("jacorb.debug.dump_incoming_messages")); // System.out.println("JacORB dump outgoing = " + System.getProperty("jacorb.debug.dump_outgoing_messages")); } protected void setUp() throws Exception { super.setUp(); org.omg.CORBA.Object compObj = getContainerServices().getComponent(CONTSRVCOMP_INSTANCE); assertNotNull(compObj); m_contSrvTesterComp = ContainerServicesTesterHelper.narrow(compObj); } protected void tearDown() throws Exception { if (m_contSrvTesterComp != null) { getContainerServices().releaseComponent(CONTSRVCOMP_INSTANCE); m_contSrvTesterComp = null; } super.tearDown(); } public void testComponentName() { StringHolder nameHolder = new StringHolder(); boolean ret = m_contSrvTesterComp.testComponentName(nameHolder); assertTrue("test execution successful on the server component", ret); assertEquals(CONTSRVCOMP_INSTANCE, nameHolder.value); } public void testStateManager() { StringHolder stateNameHolder = new StringHolder(); boolean ret = m_contSrvTesterComp.testStateManager(stateNameHolder); assertTrue("test execution successful on the server component", ret); assertEquals("OPERATIONAL", stateNameHolder.value); } /** * This test will use custom client side timeout, ignoring Container Timeout. * It is the client version of {@link #testGetReferenceWithCustomClientSideTimeout()} * where m_contSrvTesterComp will take over the role of this junit test client for testing the timeout. **/ public void testTimeout() throws Exception { try { org.omg.CORBA.Object compObj = getContainerServices().getComponent(DEFAULT_DUMMYCOMP_INSTANCE); DummyComponent comp = DummyComponentHelper.narrow(compObj); int waitTime = 18 ; //secs. (should be at most 10 s longer than 'timeout' // because component deactivation blocks only 10 seconds on a still running operation. int timeout = 10 ; //secs. //first let's try to call the IF without applicable client-side timeout try { comp.callThatTakesSomeTime(waitTime * 1000); } catch(org.omg.CORBA.TIMEOUT e){ fail("It is not supposed to get a timeout before waitTime"); } // then we call the ContainerServices to assign a timeout of 10 seconds compObj = getContainerServices().getReferenceWithCustomClientSideTimeout(compObj, timeout); comp = DummyComponentHelper.narrow(compObj); //we call again the IF StopWatch sw = new StopWatch(m_logger); try { comp.callThatTakesSomeTime(waitTime * 1000); fail("It is supposed to get a timeout before waitTime"); } catch(org.omg.CORBA.TIMEOUT e){ m_logger.info("Good: Got TIMEOUT exception from calling " + DEFAULT_DUMMYCOMP_INSTANCE + "#callThatTakesSomeTime with configured client timeout = " + timeout + " seconds."); } int elapsedTime = (int) sw.getLapTimeMillis()/1000; if(Math.abs(elapsedTime-timeout) > 1) { String msg = "TIMEOUT exception caught as expected, but after " + elapsedTime + " seconds instead of the expected " + timeout + " seconds."; fail(msg); } } finally { // the release call should block for the remaining 8 s that 'callThatTakesSomeTime' executes after our client timeout. getContainerServices().releaseComponent(DEFAULT_DUMMYCOMP_INSTANCE); } } public void testGetReferenceWithCustomClientSideTimeout() { boolean ret = m_contSrvTesterComp.testGetReferenceWithCustomClientSideTimeout(); assertTrue("test execution successful on the server component", ret); } public void testGetDynamicDummyComponent() { StringHolder compNameHolder = new StringHolder(); boolean ret = m_contSrvTesterComp.testGetDynamicDummyComponent(compNameHolder); assertTrue("test execution successful on the server component", ret); System.out.println("got dummy component called " + compNameHolder.value); // assertEquals("OPERATIONAL", compNameHolder.value); } public void testGetThreadFactory() { boolean ret = m_contSrvTesterComp.testGetThreadFactory(40, 100000, true); assertTrue("test execution successful on the server component", ret); } public void testFindDummyComponentsByType() throws Exception { String[] curls = null; try { stringSeqHolder curlRet = new stringSeqHolder(); m_contSrvTesterComp.testFindDummyComponentsByType(curlRet); curls = curlRet.value; } catch (CouldntPerformActionEx ex) { throw AcsJCouldntPerformActionEx.fromCouldntPerformActionEx(ex); } assertNotNull(curls); assertEquals(2, curls.length); assertEquals("DefaultDummyComp", curls[0]); } public void testGetCollocatedComponent() throws Exception { try { // a new component in the same container as our main test component m_contSrvTesterComp.testGetCollocatedComponent(ComponentQueryDescriptor.ANY, DUMMYCOMP2_TYPENAME, CONTSRVCOMP_INSTANCE); Thread.sleep(1500); // now we check whether a non-activated target component also works m_contSrvTesterComp.testGetCollocatedComponent("MyCollocatedDummy2", ComponentQueryDescriptor.ANY, "MyCollocationTargetDummy"); Thread.sleep(1500); } catch (CouldntPerformActionEx ex) { throw AcsJCouldntPerformActionEx.fromCouldntPerformActionEx(ex); } } public void testGetComponentNonSticky() throws Exception { // without previous activation, the call should fail try { m_contSrvTesterComp.testGetComponentNonSticky(DEFAULT_DUMMYCOMP_INSTANCE, false); fail("Exception expected, since non-sticky comp ref should not have been available."); } catch (CouldntPerformActionEx ex) { ;// expected } // now our test is the real client that activates the component beforehand getContainerServices().getComponent(DEFAULT_DUMMYCOMP_INSTANCE); try { // this time the test comp should get the non-sticky ref m_contSrvTesterComp.testGetComponentNonSticky(DEFAULT_DUMMYCOMP_INSTANCE, false); } catch (CouldntPerformActionEx ex) { throw AcsJCouldntPerformActionEx.fromCouldntPerformActionEx(ex); } try { // and the same thing again, but this time testing that releasing the non-sticky ref goes ok m_contSrvTesterComp.testGetComponentNonSticky(DEFAULT_DUMMYCOMP_INSTANCE, true); } catch (CouldntPerformActionEx ex) { throw AcsJCouldntPerformActionEx.fromCouldntPerformActionEx(ex); } getContainerServices().releaseComponent(DEFAULT_DUMMYCOMP_INSTANCE); // returns only when comp has been unloaded try { // with the target comp gone, this call should fail again m_contSrvTesterComp.testGetComponentNonSticky(DEFAULT_DUMMYCOMP_INSTANCE, true); fail("Exception expected, since non-sticky comp ref should not have been available."); } catch (CouldntPerformActionEx ex) { // expected AcsJCouldntPerformActionEx jEx = AcsJCouldntPerformActionEx.fromCouldntPerformActionEx(ex); assertEquals("testGetComponentNonSticky failed for component 'DefaultDummyComp'", jEx.getMessage()); } } public void testComponentListening() throws Exception { // a second client to the manager. Shares Corba stuff, but has its own connection to the manager. OtherComponentClient secondClient = new OtherComponentClient(null, m_managerLoc, "ComponentTestclient-secondClient", acsCorba); BlockingComponentListener blockLizzy = new BlockingComponentListener(m_logger); getContainerServices().registerComponentListener(blockLizzy); m_logger.info("Second client will activate and kill '" + DEFAULT_DUMMYCOMP_INSTANCE + "'. This test is not a client and should not be notified."); secondClient.getComponent(DEFAULT_DUMMYCOMP_INSTANCE); secondClient.forceReleaseComponent(DEFAULT_DUMMYCOMP_INSTANCE); Thread.sleep(2000); // to make sure we would have gotten the notification if there were any assertEquals(0, blockLizzy.getAllCompsAvailable().size()); assertEquals(0, blockLizzy.getAllCompNamesUnavailable().size()); getContainerServices().getComponent(DEFAULT_DUMMYCOMP_INSTANCE); m_logger.info("A second client will request again and kill '" + DEFAULT_DUMMYCOMP_INSTANCE + "'. This test has already activated the component, thus only the component unloading should yield 1 notification."); blockLizzy.clearAndExpect(1); secondClient.getComponent(DEFAULT_DUMMYCOMP_INSTANCE); secondClient.forceReleaseComponent(DEFAULT_DUMMYCOMP_INSTANCE); assertTrue("Failed to get expected notification from manager within 10 seconds", blockLizzy.awaitNotifications(10, TimeUnit.SECONDS)); assertEquals(0, blockLizzy.getAllCompsAvailable().size()); assertEquals(1, blockLizzy.getAllCompNamesUnavailable().size()); m_logger.info("A third client will request and kill '" + DEFAULT_DUMMYCOMP_INSTANCE + "'. This test is still registered as a client, thus 2 notifications for component loading and unloading are expected."); blockLizzy.clearAndExpect(2); secondClient.getComponent(DEFAULT_DUMMYCOMP_INSTANCE); secondClient.forceReleaseComponent(DEFAULT_DUMMYCOMP_INSTANCE); assertTrue("Failed to get expected notification from manager within 10 seconds", blockLizzy.awaitNotifications(10, TimeUnit.SECONDS)); assertEquals(1, blockLizzy.getAllCompsAvailable().size()); assertEquals(1, blockLizzy.getAllCompNamesUnavailable().size()); secondClient.tearDown(); } } /** * Helper client that allows activating and destroying a component independently of our test, * in the sense that the manager thinks it's a different application. */ class OtherComponentClient extends AdvancedComponentClient { public OtherComponentClient(Logger logger, String managerLoc, String clientName, AcsCorba externalAcsCorba) throws Exception { super(logger, managerLoc, clientName, externalAcsCorba); } org.omg.CORBA.Object getComponent(String name) throws AcsJContainerServicesEx { return getContainerServices().getComponent(name); } /** * Commands the manager directly to forcefully release the given component. * Note that such a call is only OK for a unit test, but not for normal operational code. * @param name name of the component to be forcefully released * @throws AcsJNoPermissionEx */ void forceReleaseComponent(String name) throws AcsJNoPermissionEx { // first a regular release so that this client's container services count down the reference getContainerServices().releaseComponent(name); // and now the forceful release that will unload the component regardless of other clients' references to it int numClients = getAcsManagerProxy().force_release_component(getAcsManagerProxy().getManagerHandle(), name); m_logger.info("Forcibly released component " + name + " which had " + numClients + " other clients."); } }