001    // jademx - JADE management using JMX
002    // Copyright 2005 Caboodle Networks, Inc.
003    //
004    // This library is free software; you can redistribute it and/or
005    // modify it under the terms of the GNU Lesser General Public
006    // License as published by the Free Software Foundation; either
007    // version 2.1 of the License, or (at your option) any later version.
008    //
009    // This library is distributed in the hope that it will be useful,
010    // but WITHOUT ANY WARRANTY; without even the implied warranty of
011    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012    // Lesser General Public License for more details.
013    //
014    // You should have received a copy of the GNU Lesser General Public
015    // License along with this library; if not, write to the Free Software
016    // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
017    
018    package jade.jademx.unit;
019    
020    
021    import java.util.Date;
022    
023    import jade.jademx.JadeMXSuiteTest;
024    import jade.jademx.agent.JademxAgent;
025    import jade.jademx.agent.JademxPingAgentProxy;
026    import jade.jademx.config.jademx.onto.ConfigAgentSpecifier;
027    import jade.jademx.config.jademx.onto.ConfigPlatform;
028    import jade.jademx.config.jademx.onto.ConfigRuntime;
029    import jade.jademx.config.jademx.onto.JademxConfig;
030    import jade.jademx.mbean.JadeFactory;
031    import jade.jademx.mbean.JadePlatformMBean;
032    import jade.jademx.mbean.JadeRuntimeMBean;
033    import jade.jademx.server.JadeMXServer;
034    import jade.jademx.server.JadeMXServerFactory;
035    import jade.jademx.util.AclMsgCmp;
036    import jade.jademx.util.ThrowableUtil;
037    import jade.lang.acl.ACLMessage;
038    import jade.util.Logger;
039    
040    import javax.management.MBeanServer;
041    import javax.management.ObjectName;
042    
043    import junit.framework.Test;
044    import junit.framework.TestCase;
045    import junit.framework.TestSuite;
046    
047    /** 
048     * unit testing test
049     * @author David Bernstein, <a href="http://www.caboodlenetworks.com"
050     *  >Caboodle Networks, Inc.</a>
051     */
052    public class UnitTestingTest extends TestCase {
053    
054        /** my logger */
055        private final Logger logger = 
056            Logger.getMyLogger(UnitTestingTest.class.getName());
057        
058        // original inject message before AIDs localized
059        //  "(REQUEST"+
060        //  " :sender  ( agent-identifier :name pinger@diamond:1099/JADE )"+
061        //  " :receiver  (set ( agent-identifier :name pingee@diamond:1099/JADE ) )"+
062        //  " :content  \"((action (agent-identifier :name pingee@diamond:1099/JADE) (ping)))\" "+
063        //  " :reply-with  ping1  :language  fipa-sl  :ontology  ping  :protocol  fipa-request"+
064        //  " :conversation-id  ping-conv-1127942689278-18131271 )";
065    
066        /** reply-id used in message to inject */
067        private static final String INJECT_REPLY_ID = "pinger@diamond:1099/JADE1127942689278";
068        /** AID for pingee agent in message to inject */
069        private static final String PINGEE_INJECT_AID = "pingee@diamond:1099/JADE";
070        /** AID for pinger agent in message to inject */
071        private static final String PINGER_INJECT_AID = "pinger@diamond:1099/JADE";
072        /** local name for pingee agent */
073        private static final String PINGEE_LOCAL_NAME = "pingee";
074        
075        /** message to inject */
076        private final static String injectMsg = 
077            "(REQUEST"+
078            " :sender  ( agent-identifier :name pinger )"+
079            " :receiver  (set ( agent-identifier :name pingee ) )"+
080            " :reply-to (set ( agent-identifier :name pinger ) )"+
081            " :content  \"((action (agent-identifier :name pingee@diamond:1099/JADE) (ping)))\" "+
082            " :reply-with  ping1  :language  fipa-sl  :ontology  ping  :protocol  fipa-request"+
083            " :conversation-id  ping-conv-1127942689278-18131271 )";
084        
085        /** message to expect */
086        private final static String expectMsg = 
087            "(INFORM"+
088            " :sender  ( agent-identifier :name pingee@diamond:1099/JADE )"+
089            " :receiver  (set ( agent-identifier :name pinger@diamond:1099/JADE ) )"+
090            " :content  \"((result (action (agent-identifier :name pingee@diamond:1099/JADE) (ping)) pong))\" "+
091            " :reply-with  pinger@diamond:1099/JADE1127942689278  :in-reply-to  ping1  "+
092            ":language  fipa-sl  :ontology  ping  :protocol  fipa-request"+
093            " :conversation-id  ping-conv-1127942689278-18131271 )";
094        
095        // SETUP/TEARDOWN
096        
097        /** MBeanServer being used */
098        private MBeanServer mBeanServer = null;
099        /** created JadeRuntimeMBean */
100        private JadeRuntimeMBean runtime = null;
101        /** ObjectName for JadeRuntimeMBean */
102        private ObjectName runtimeON = null;
103        
104        
105        /* (non-Javadoc)
106         * @see junit.framework.TestCase#setUp()
107         */
108        protected void setUp() throws Exception {
109            // create a jademx config of one ping agent
110            JademxConfig jademxConfig = buildPingerPingeeAgentCfg();
111            // start the configuration
112            // first get JadeMXServer
113            JadeMXServer jadeMXServer = null;
114            try {
115                jadeMXServer = JadeMXServerFactory.jadeMXServerBySysProp();
116            } 
117            catch (Exception e) {
118                fail(ThrowableUtil.errMsg("problem getting jademx server",e));
119            }
120            mBeanServer = jadeMXServer.getMBeanServer();
121            // now get a factory to use
122            JadeFactory jadeFactory = new JadeFactory( jadeMXServer );
123            // instantiate the configuration
124            try {
125                runtime = jadeFactory.instantiateRuntime( jademxConfig );
126            } 
127            catch (Exception e) {
128                fail(ThrowableUtil.errMsg("problem instantiating configuration",e));
129            }
130            // get ObjectName for runtime
131            runtimeON = runtime.getObjectName();
132            logger.log( Logger.FINE,"runtimeON:"+runtimeON);
133        }
134        
135        /* (non-Javadoc)
136         * @see junit.framework.TestCase#tearDown()
137         */
138        protected void tearDown() throws Exception {
139            // shutdown the configuration
140            try {
141                mBeanServer.invoke( runtimeON, 
142                        JadeRuntimeMBean.OPER_SHUTDOWN, 
143                        new Object[]{},
144                        JadeRuntimeMBean.OPER_SHUTDOWN_SIGNATURE );
145            }
146            catch ( Exception e ) {
147                fail(ThrowableUtil.errMsg("problem shutting down JADE runtime", e));
148            }
149        }
150        
151        /**
152         * make a configuration for testing use programmatically
153         */
154        private JademxConfig buildPingerPingeeAgentCfg() {
155            JademxConfig jademxConfig = new JademxConfig();
156            ConfigRuntime runtime = new ConfigRuntime();
157            jademxConfig.addRuntime( runtime );
158            ConfigPlatform platform = new ConfigPlatform();
159            runtime.addPlatform( platform );
160            platform.addOption( "port=1917" );
161            platform.addOption( "nomtp=true" );
162            ConfigAgentSpecifier agentSpecifier;
163            agentSpecifier =
164                new ConfigAgentSpecifier(
165                        "pinger",
166                        "jade.jademx.agent.JademxNopAgent" );
167            platform.addAgentSpecifier( agentSpecifier );
168            agentSpecifier =
169                new ConfigAgentSpecifier(
170                        PINGEE_LOCAL_NAME,
171                        "jade.jademx.agent.JademxPingAgent" );
172            platform.addAgentSpecifier( agentSpecifier );
173            logger.log( Logger.FINE,"jademxconfig:"+jademxConfig);
174            return jademxConfig;
175        }
176        
177        // TESTS
178        
179        /**
180         * test missing expect msg
181         */
182        public void testMissingExpect() {
183    
184            // find the agent MBean
185            ObjectName agentON = null;
186            JademxPingAgentProxy pingAgentProxy = null;
187            try {
188                ObjectName platformONs[] = 
189                    (ObjectName[])mBeanServer.getAttribute( 
190                            runtimeON, JadeRuntimeMBean.ATTR_PLATFORM_OBJECT_NAMES);
191                ObjectName platformON = platformONs[0];
192                logger.log( Logger.FINE,"platformON:"+platformON);
193                agentON = (ObjectName)mBeanServer.invoke( platformON, 
194                        JadePlatformMBean.OPER_GET_AGENT_OBJECT_NAME, 
195                        new Object[]{PINGEE_LOCAL_NAME},
196                        JadePlatformMBean.OPER_GET_AGENT_OBJECT_NAME_SIGNATURE );
197                if ( null == agentON ) {
198                    throw new Exception("null agent ObjectName");
199                }
200                pingAgentProxy = new JademxPingAgentProxy( agentON, mBeanServer );
201            }
202            catch (Exception e) {
203                fail(ThrowableUtil.errMsg("problem finding agent MBean", e));
204            }
205            
206            // make sure agent MBean bound to JademxAgent
207            JademxAgent.assertIsJademxAgent( agentON, mBeanServer );
208            
209            // assert the expected message before expected message set
210            try {
211                JademxAgent.assertExpectedMessage( agentON, mBeanServer );
212                fail("didn't catch missing expected message");
213            }
214            catch ( Throwable t ) {
215                assertTrue(true);
216            }
217    
218        }
219    
220        /**
221         * test missing inject msg
222         */
223        public void testMissingInject() {
224    
225            // find the agent MBean
226            ObjectName agentON = null;
227            JademxPingAgentProxy pingAgentProxy = null;
228            try {
229                ObjectName platformONs[] = 
230                    (ObjectName[])mBeanServer.getAttribute( 
231                            runtimeON, JadeRuntimeMBean.ATTR_PLATFORM_OBJECT_NAMES);
232                ObjectName platformON = platformONs[0];
233                logger.log( Logger.FINE,"platformON:"+platformON);
234                agentON = (ObjectName)mBeanServer.invoke( platformON, 
235                        JadePlatformMBean.OPER_GET_AGENT_OBJECT_NAME, 
236                        new Object[]{PINGEE_LOCAL_NAME},
237                        JadePlatformMBean.OPER_GET_AGENT_OBJECT_NAME_SIGNATURE );
238                if ( null == agentON ) {
239                    throw new Exception("null agent ObjectName");
240                }
241                pingAgentProxy = new JademxPingAgentProxy( agentON, mBeanServer );
242            }
243            catch (Exception e) {
244                fail(ThrowableUtil.errMsg("problem finding agent MBean", e));
245            }
246            
247            // make sure agent MBean bound to JademxAgent
248            JademxAgent.assertIsJademxAgent( agentON, mBeanServer );
249            
250            try {
251                logger.log( Logger.FINE,"setting expect message...");
252                // set the expected message
253                pingAgentProxy.setUnitTestExpectedMessage( expectMsg );
254            }
255            catch ( Exception e ) {
256                fail(ThrowableUtil.errMsg("problem setting agent test setup", e));
257            }
258            
259            // assert the expected message before injected message set
260            try {
261                JademxAgent.assertExpectedMessage( agentON, mBeanServer );
262                fail("didn't catch missing expected message");
263            }
264            catch ( Throwable t ) {
265                assertTrue(true);
266            }
267    
268        }
269    
270        
271        /**
272         * test that can turn on/off comparison for individual slot
273         */
274        public void testComparisonCustomization() {
275            // find the agent MBean
276            ObjectName agentON = null;
277            JademxPingAgentProxy pingAgentProxy = null;
278            try {
279                ObjectName platformONs[] = 
280                    (ObjectName[])mBeanServer.getAttribute( 
281                            runtimeON, JadeRuntimeMBean.ATTR_PLATFORM_OBJECT_NAMES);
282                ObjectName platformON = platformONs[0];
283                logger.log( Logger.FINE,"platformON:"+platformON);
284                agentON = (ObjectName)mBeanServer.invoke( platformON, 
285                        JadePlatformMBean.OPER_GET_AGENT_OBJECT_NAME, 
286                        new Object[]{PINGEE_LOCAL_NAME},
287                        JadePlatformMBean.OPER_GET_AGENT_OBJECT_NAME_SIGNATURE );
288                if ( null == agentON ) {
289                    throw new Exception("null agent ObjectName");
290                }
291                pingAgentProxy = new JademxPingAgentProxy( agentON, mBeanServer );
292            }
293            catch (Exception e) {
294                fail(ThrowableUtil.errMsg("problem finding agent MBean", e));
295            }
296            
297            // make sure agent MBean bound to JademxAgent
298            JademxAgent.assertIsJademxAgent( agentON, mBeanServer );
299            
300            // create a message with extra slot
301            ACLMessage alteredExpectMsg = null;
302            try {
303                alteredExpectMsg = AclMsgCmp.stringToMessage(expectMsg);
304            } 
305            catch (Exception e) {
306                fail(ThrowableUtil.errMsg("problem encoding expect msg", e));
307            }
308            alteredExpectMsg.setReplyByDate( new Date() );
309            String alteredExpectMsgStr = alteredExpectMsg.toString();
310            
311            // set unit testing attributes on agent
312            try {
313                logger.log( Logger.FINE,"setting inject message...");
314                // set the message to inject
315                pingAgentProxy.setUnitTestInjectMessage( injectMsg );
316    
317                logger.log( Logger.FINE,"setting expect message...");
318                // set the expected message
319                pingAgentProxy.setUnitTestExpectedMessage( alteredExpectMsgStr );
320    
321                logger.log( Logger.FINE,"setting timeout...");
322                final String TIMEOUT = "PT38S";
323                pingAgentProxy.setUnitTestTimeout( TIMEOUT );
324                String timeout = pingAgentProxy.getUnitTestTimeout();
325                assertEquals( TIMEOUT, timeout );
326                
327                logger.log( Logger.FINE,"adding variables...");
328                // set message comparison variable properties
329                pingAgentProxy.unitTestAddVariable( PINGER_INJECT_AID, AclMsgCmp.AID_MAP );
330                pingAgentProxy.unitTestAddVariable( PINGEE_INJECT_AID, AclMsgCmp.AID_MAP );
331                pingAgentProxy.unitTestAddVariable( INJECT_REPLY_ID, AclMsgCmp.REPLY_ID_MAP );
332                
333                // important for this test: turn off reply-by comparison
334                pingAgentProxy.setUnitTestCmpReplyBy( false );
335                
336            }
337            catch ( Exception e ) {
338                fail(ThrowableUtil.errMsg("problem setting agent test setup", e));
339            }
340            
341            // assert the expected message
342            logger.log( Logger.FINE,"calling assertExpectedMessage()...");
343            JademxAgent.assertExpectedMessage( agentON, mBeanServer );
344            logger.log( Logger.FINE,"returned from assertExpectedMessage()");
345    
346        }
347        
348      
349        /** test unit testing with calls via MBeanServer */
350        public void testUnitTest() {
351    
352            // find the agent MBean
353            ObjectName agentON = null;
354            JademxPingAgentProxy pingAgentProxy = null;
355            try {
356                ObjectName platformONs[] = 
357                    (ObjectName[])mBeanServer.getAttribute( 
358                            runtimeON, JadeRuntimeMBean.ATTR_PLATFORM_OBJECT_NAMES);
359                ObjectName platformON = platformONs[0];
360                logger.log( Logger.FINE,"platformON:"+platformON);
361                agentON = (ObjectName)mBeanServer.invoke( platformON, 
362                        JadePlatformMBean.OPER_GET_AGENT_OBJECT_NAME, 
363                        new Object[]{PINGEE_LOCAL_NAME},
364                        JadePlatformMBean.OPER_GET_AGENT_OBJECT_NAME_SIGNATURE );
365                if ( null == agentON ) {
366                    throw new Exception("null agent ObjectName");
367                }
368                pingAgentProxy = new JademxPingAgentProxy( agentON, mBeanServer );
369            }
370            catch (Exception e) {
371                fail(ThrowableUtil.errMsg("problem finding agent MBean", e));
372            }
373            
374            // make sure agent MBean bound to JademxAgent
375            JademxAgent.assertIsJademxAgent( agentON, mBeanServer );
376            
377            // set unit testing attributes on agent
378            try {
379                logger.log( Logger.FINE,"setting inject message...");
380                // set the message to inject
381                pingAgentProxy.setUnitTestInjectMessage( injectMsg );
382    
383                logger.log( Logger.FINE,"setting expect message...");
384                // set the expected message
385                pingAgentProxy.setUnitTestExpectedMessage( expectMsg );
386    
387                logger.log( Logger.FINE,"setting timeout...");
388                final String TIMEOUT = "PT38S";
389                pingAgentProxy.setUnitTestTimeout( TIMEOUT );
390                String timeout = pingAgentProxy.getUnitTestTimeout();
391                assertEquals( TIMEOUT, timeout );
392                
393                logger.log( Logger.FINE,"adding variables...");
394                // set message comparison variable properties
395                pingAgentProxy.unitTestAddVariable( PINGER_INJECT_AID, AclMsgCmp.AID_MAP );
396                pingAgentProxy.unitTestAddVariable( PINGEE_INJECT_AID, AclMsgCmp.AID_MAP );
397                pingAgentProxy.unitTestAddVariable( INJECT_REPLY_ID, AclMsgCmp.REPLY_ID_MAP );
398            }
399            catch ( Exception e ) {
400                fail(ThrowableUtil.errMsg("problem setting agent test setup", e));
401            }
402            
403            // assert the expected message
404            logger.log( Logger.FINE,"calling assertExpectedMessage()...");
405            JademxAgent.assertExpectedMessage( agentON, mBeanServer );
406            logger.log( Logger.FINE,"returned from assertExpectedMessage()");
407            try {
408                pingAgentProxy.unitTestClearVariables();
409            }
410            catch ( Exception e ) {
411                fail(ThrowableUtil.errMsg("problem clearing variables", e));
412            }
413    
414        }
415        
416        
417        // suite
418    
419        /**
420         * return the implicit suite of tests
421         * @return the implicit suite of tests
422         */
423        public static Test suite() {
424            return new TestSuite( 
425                    UnitTestingTest.class, 
426                    JadeMXSuiteTest.nameWithClass( UnitTestingTest.class, 
427                    "testing unit testing") );
428        }
429        
430    }