All Downloads are FREE. Search and download functionalities are using the official Maven repository.

test.tck.msgflow.NonInviteClientTransactionsStateMachineTest Maven / Gradle / Ivy

There is a newer version: 1.3.0-91
Show newest version
/*
* Conditions Of Use
*
* This software was developed by employees of the National Institute of
* Standards and Technology (NIST), and others.
* This software is has been contributed to the public domain.
* As a result, a formal license is not needed to use the software.
*
* This software is provided "AS IS."
* NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
* AND DATA ACCURACY.  NIST does not warrant or make any representations
* regarding the use of the software or the results thereof, including but
* not limited to the correctness, accuracy, reliability or usefulness of
* the software.
*
*
*/
package test.tck.msgflow;

import junit.framework.*;

import javax.sip.*;
import javax.sip.message.*;
import java.util.*;
import test.tck.*;

/**
 *
 * The test tries to verify that Non Invite Client Transactions correctly change
 * states as specified by the rfc3261. The Tested Implementation is used
 * to send requests and the ReferenceImplementation issues (or not) corresponding
 * responses. ClientTransaction states are constantly queried
 * and compared to those in the state machine described in
 * section 17.1.2 of rfc3261
 *
 *
 *                                   | Request from TU
 *                                   | send request
 *               Timer E             V
 *               send request  +-----------+
 *                   +---------|           |-------------------+
 *                   |         |  Trying   |  Timer F          |
 *                   +-------->|           |  or Transport Err.|
 *                             +-----------+  inform TU        |
 *                200-699         |  |                         |
 *                resp. to TU     |  |1xx                      |
 *                +---------------+  |resp. to TU              |
 *                |                  |                         |
 *                |   Timer E        V       Timer F           |
 *                |   send req +-----------+ or Transport Err. |
 *                |  +---------|           | inform TU         |
 *                |  |         |Proceeding |------------------>|
 *                |  +-------->|           |-----+             |
 *                |            +-----------+     |1xx          |
 *                |              |      ^        |resp to TU   |
 *                | 200-699      |      +--------+             |
 *                | resp. to TU  |                             |
 *                |              |                             |
 *                |              V                             |
 *                |            +-----------+                   |
 *                |            |           |                   |
 *                |            | Completed |                   |
 *                |            |           |                   |
 *                |            +-----------+                   |
 *                |              ^   |                         |
 *                |              |   | Timer K                 |
 *                +--------------+   | -                       |
 *                                   |                         |
 *                                   V                         |
 *             NOTE:           +-----------+                   |
 *                             |           |                   |
 *         transitions         | Terminated|<------------------+
 *         labeled with        |           |
 *         the event           +-----------+
 *         over the action
 *         to take
 *
 *                 Figure 6: non-INVITE client transaction
 *
 * TODO test timeout events
 *
* * @author Emil Ivov * Network Research Team, Louis Pasteur University, Strasbourg, France. * This code is in the public domain. * @version 1.0 */ public class NonInviteClientTransactionsStateMachineTest extends MessageFlowHarness { public NonInviteClientTransactionsStateMachineTest(String name) { super(name); } //==================== tests ============================== /** * Tries to walk a TI client transaction through the following scenario * Trying-->Proceeding-->Completed-->Terminated. Apart from state * transitions, we also test, retransmissions and proper hiding/passing * of messages to the TU. */ public void testTryingProceedingCompletedTerminatedScenario() { try { Request register = createTiRegisterRequest(); ClientTransaction tran = null; try { eventCollector.collectRequestEvent(riSipProvider); tran = tiSipProvider.getNewClientTransaction(register); tran.sendRequest(); } catch (SipException ex) { throw new TiUnexpectedError( "A SipExceptionOccurred while trying to send request!", ex); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to regiest a SipListener with an RI SipProvider", ex); } waitForMessage(); RequestEvent registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); if (registerReceivedEvent == null || registerReceivedEvent.getRequest() == null) throw new TiUnexpectedError("The REGISTER request was not received by the RI!"); //At this point the ClientTransaction should be TRYING! assertEquals(TransactionState.TRYING, tran.getState()); //Check Request retransmission try { eventCollector.collectRequestEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to regiest a SipListener with an RI SipProvider", ex); } //Wait for the retransmission timer to fire if it had not already done so. if (tran.getRetransmitTimer() > MESSAGES_ARRIVE_FOR) sleep((long) tran.getRetransmitTimer() - MESSAGES_ARRIVE_FOR); //subtract the time we waited for the REGISTER //Wait for the retransmitted request to arrive waitForMessage(); registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); assertNotNull( "The REGISTER request was not retransmitted!", registerReceivedEvent); assertNotNull( "The REGISTER request was not retransmitted!", registerReceivedEvent.getRequest()); assertEquals( Request.REGISTER, registerReceivedEvent.getRequest().getMethod()); //At this point the ClientTransaction should STILL be TRYING! assertEquals(TransactionState.TRYING, tran.getState()); //Send a TRYING response try { eventCollector.collectResponseEvent(tiSipProvider); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with TI", ex); } try { Response res = riMessageFactory.createResponse( Response.TRYING, registerReceivedEvent.getRequest()); addStatus(registerReceivedEvent.getRequest(), res); riSipProvider.sendResponse(res); } catch (Throwable ex) { throw new TckInternalError( "The TCK could not send a trying response back to the TI", ex); } waitForMessage(); //Analyze the TRYING response and Tran state back at the TI ResponseEvent responseEvent = eventCollector.extractCollectedResponseEvent(); assertNotNull( "The Tested Implementation did not pass a 1xx response to the TU!", responseEvent); assertNotNull( "The Tested Implementation did not pass a 1xx response to the TU!", responseEvent.getResponse()); assertTrue( "A response different from TRYING was passed to the TU!", responseEvent.getResponse().getStatusCode() == Response.TRYING); assertSame( "The TRYING response was not associated with the right transaction", tran, responseEvent.getClientTransaction()); //verify the the tran state is now PROCEEDING assertEquals( "The ClientTransaction did not pass in the PROCEEDING state after " + "receiving 1xx provisional response", tran.getState(), TransactionState.PROCEEDING); //Send a 200 OK (final) response from the RI try { eventCollector.collectResponseEvent(tiSipProvider); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with TI", ex); } //The OK response shouldn't trigger any ACKs so let's register //a listener with the RI to verify whether that is the case SipEventCollector ackCollector = new SipEventCollector(); try { ackCollector.collectRequestEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to regiest a SipListener with an RI SipProvider", ex); } Response ok = null; try { ok = riMessageFactory.createResponse( Response.OK, registerReceivedEvent.getRequest()); addStatus(registerReceivedEvent.getRequest(), ok); riSipProvider.sendResponse((Response) ok.clone()); } catch (Throwable ex) { throw new TckInternalError( "The TCK could not send a OK response back to the TI", ex); } waitForMessage(); //Analyze the OK response and Tran state back at the TI responseEvent = eventCollector.extractCollectedResponseEvent(); assertNotNull( "The Tested Implementation did not pass a 200-699 response to the TU!", responseEvent); assertNotNull( "The Tested Implementation did not pass a 200-699 response to the TU!", responseEvent.getResponse()); assertSame( "The OK response was not associated with the right transaction", tran, responseEvent.getClientTransaction()); assertSame( "A response different from OK was passed to the TU", tran, responseEvent.getClientTransaction()); assertEquals( "The ClientTransaction did not pass in the COMPLETED state after " + "receiving 200-699 final response", tran.getState(), TransactionState.COMPLETED); //check whether the ackCollector has caught any fish RequestEvent ackReceivedEvent = ackCollector.extractCollectedRequestEvent(); assertNull( "The TI sent an ACK request in a non INVITE transaction", ackReceivedEvent); //Now let's retransmit the final response. See again that no acks are sent try { eventCollector.collectResponseEvent(tiSipProvider); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with TI", ex); } //go fish the ack try { ackCollector.collectRequestEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to regiest a SipListener with an RI SipProvider", ex); } try { riSipProvider.sendResponse((Response) ok.clone()); } catch (Throwable ex) { throw new TckInternalError( "The TCK could not send a OK response back to the TI", ex); } waitForMessage(); //The TU shouldn't see the retransmitted OK response responseEvent = eventCollector.extractCollectedResponseEvent(); assertNull( "The Tested Implementation passed a retransmitted 200-699 response " + "to the TU.", responseEvent); //We must still be in the completed state. assertTrue( "The ClientTransaction did not stay long enough in the COMPLETED " + "state.", tran.getState().equals(TransactionState.COMPLETED) || tran.getState().equals(TransactionState.TERMINATED)); //check whether the ackCollector has caught any fish ackReceivedEvent = ackCollector.extractCollectedRequestEvent(); assertNull( "The TI replied with an ACK to a nonINVITE request", ackReceivedEvent); } catch (Throwable exc) { exc.printStackTrace(); fail(exc.getClass().getName() + ": " + exc.getMessage()); } assertTrue(new Exception().getStackTrace()[0].toString(), true); } /** * Tries to walk a TI client transaction through the following scenario * Trying-->Completed-->Terminated. Apart from state * transitions, we also test, retransmissions and proper hiding/passing * of messages to the TU. */ public void testTryingCompletedTerminatedScenario() { try { Request register = createTiRegisterRequest(); ClientTransaction tran = null; try { eventCollector.collectRequestEvent(riSipProvider); tran = tiSipProvider.getNewClientTransaction(register); tran.sendRequest(); } catch (SipException ex) { throw new TiUnexpectedError( "A SipExceptionOccurred while trying to send request!", ex); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to regiest a SipListener with an RI SipProvider", ex); } waitForMessage(); RequestEvent registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); if (registerReceivedEvent == null || registerReceivedEvent.getRequest() == null) throw new TiUnexpectedError("The REGISTER request was not received by the RI!"); //At this point the ClientTransaction should be TRYING! assertEquals(TransactionState.TRYING, tran.getState()); //Check Request retransmission try { eventCollector.collectRequestEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to regiest a SipListener with an RI SipProvider", ex); } //Wait for the retransmission timer to fire if it had not already done so. if (tran.getRetransmitTimer() > MESSAGES_ARRIVE_FOR) sleep((long) tran.getRetransmitTimer() - MESSAGES_ARRIVE_FOR); //subtract the time we waited for the REGISTER //Wait for the retransmitted request to arrive waitForMessage(); registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); assertNotNull( "The REGISTER request was not retransmitted!", registerReceivedEvent); assertNotNull( "The REGISTER request was not retransmitted!", registerReceivedEvent.getRequest()); assertEquals( Request.REGISTER, registerReceivedEvent.getRequest().getMethod()); //At this point the ClientTransaction should STILL be TRYING! assertEquals(TransactionState.TRYING, tran.getState()); //Send a 200 OK (final) response from the RI try { eventCollector.collectResponseEvent(tiSipProvider); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with TI", ex); } //The OK response shouldn't trigger any ACKs so let's register //a listener with the RI to verify whether that is the case SipEventCollector ackCollector = new SipEventCollector(); try { ackCollector.collectRequestEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to regiest a SipListener with an RI SipProvider", ex); } Response ok = null; try { ok = riMessageFactory.createResponse( Response.OK, registerReceivedEvent.getRequest()); addStatus(registerReceivedEvent.getRequest(), ok); riSipProvider.sendResponse((Response) ok.clone()); } catch (Throwable ex) { throw new TckInternalError( "The TCK could not send a OK response back to the TI", ex); } waitForMessage(); //Analyze the OK response and Tran state back at the TI ResponseEvent responseEvent = eventCollector.extractCollectedResponseEvent(); assertNotNull( "The Tested Implementation did not pass a 200-699 response to the TU!", responseEvent); assertNotNull( "The Tested Implementation did not pass a 200-699 response to the TU!", responseEvent.getResponse()); assertSame( "The OK response was not associated with the right transaction", tran, responseEvent.getClientTransaction()); assertSame( "A response different from OK was passed to the TU", tran, responseEvent.getClientTransaction()); assertEquals( "The ClientTransaction did not pass in the COMPLETED state after " + "receiving 200-699 final response", tran.getState(), TransactionState.COMPLETED); //check whether the ackCollector has caught any fish RequestEvent ackReceivedEvent = ackCollector.extractCollectedRequestEvent(); assertNull( "The TI sent an ACK request in a non INVITE transaction", ackReceivedEvent); //Now let's retransmit the final response. See again that no acks are sent try { eventCollector.collectResponseEvent(tiSipProvider); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with TI", ex); } //go fish the ack try { ackCollector.collectRequestEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to regiest a SipListener with an RI SipProvider", ex); } try { riSipProvider.sendResponse((Response) ok.clone()); } catch (Throwable ex) { throw new TckInternalError( "The TCK could not send a OK response back to the TI", ex); } waitForMessage(); //The TU shouldn't see the retransmitted OK response responseEvent = eventCollector.extractCollectedResponseEvent(); assertNull( "The Tested Implementation passed a retransmitted 200-699 response " + "to the TU.", responseEvent); //We must still be in the completed state. assertTrue( "The ClientTransaction did not stay long enough in the COMPLETED " + "state.", tran.getState().equals(TransactionState.COMPLETED) || tran.getState().equals(TransactionState.TERMINATED)); //check whether the ackCollector has caught any fish ackReceivedEvent = ackCollector.extractCollectedRequestEvent(); assertNull( "The TI replied with an ACK to a nonINVITE request", ackReceivedEvent); } catch (Throwable exc) { exc.printStackTrace(); fail(exc.getClass().getName() + ": " + exc.getMessage()); } assertTrue(new Exception().getStackTrace()[0].toString(), true); } //==================== end of tests //====== STATIC JUNIT ========== public static Test suite() { return new TestSuite(NonInviteClientTransactionsStateMachineTest.class); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy