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

test.tck.msgflow.NonInviteServerTransactionsStateMachineTest 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 javax.sip.header.*;
import java.util.*;
import java.text.*;
import test.tck.*;

/**
 *
 * The test tries to verify that Invite Server Transactions correctly change
 * states as specified by the rfc3261. The Reference Implementation is used
 * to send requests and a Tested Implementation ServerTransaction's states are
 * queried and compared to those in the state machine described in
 * section 17.2.1 of rfc3261
 *
 *
 *                        |Request received
 *                                  |pass to TU
 *                                  V
 *                            +-----------+
 *                            |           |
 *                            | Trying    |-------------+
 *                            |           |             |
 *                            +-----------+             |200-699 from TU
 *                                  |                   |send response
 *                                  |1xx from TU        |
 *                                  |send response      |
 *                                  |                   |
 *               Request            V      1xx from TU  |
 *               send response+-----------+send response|
 *                   +--------|           |--------+    |
 *                   |        | Proceeding|        |    |
 *                   +------->|           |<-------+    |
 *            +<--------------|           |             |
 *            |Trnsprt Err    +-----------+             |
 *            |Inform TU            |                   |
 *            |                     |                   |
 *            |                     |200-699 from TU    |
 *            |                     |send response      |
 *            |  Request            V                   |
 *            |  send response+-----------+             |
 *            |      +--------|           |             |
 *            |      |        | Completed |<------------+
 *            |      +------->|           |
 *            +<--------------|           |
 *            |Trnsprt Err    +-----------+
 *            |Inform TU            |
 *            |                     |Timer J fires
 *            |                     |-
 *            |                     |
 *            |                     V
 *            |               +-----------+
 *            |               |           |
 *            +-------------->| Terminated|
 *                            |           |
 *                            +-----------+
 *
 *                Figure 8: non-INVITE server transaction
 *
 *
* * @author Emil Ivov * Network Research Team, Louis Pasteur University, Strasbourg, France. * This code is in the public domain. * @version 1.0 */ public class NonInviteServerTransactionsStateMachineTest extends MessageFlowHarness { public NonInviteServerTransactionsStateMachineTest(String name) { super(name); } //==================== tests ============================== /** * Tries to steer a TI server 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 testTryingProceedingCompletedScenario() { try { Request register = createRiRegisterRequest(); SipEventCollector responseCollector = new SipEventCollector(); //Before Sending the request we should first register a listener with the //RI that would catch the TRYING response try { responseCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to register a SipListener with an RI SipProvider", ex); } //Send the initial request try { eventCollector.collectRequestEvent(tiSipProvider); riSipProvider.sendRequest(register); } catch (SipException ex) { throw new TckInternalError( "A SipExceptionOccurred while trying to send request!", ex); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with a TI SipProvider", ex); } waitForMessage(); RequestEvent registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); if (registerReceivedEvent == null || registerReceivedEvent.getRequest() == null) throw new TiUnexpectedError("The initial register request was not received by the TI!"); //Let's create the transaction ServerTransaction tran = null; try { tran = tiSipProvider.getNewServerTransaction( registerReceivedEvent.getRequest()); } catch (Exception ex) { ex.printStackTrace(); fail( ex.getClass().getName() + "was thrown while trying to " + "create the server transaction"); } assertNotNull( "tiSipProvider.getNewServerTransaction() returned null", tran); //At this point the ServerTransaction should be TRYING! assertEquals(TransactionState.TRYING, tran.getState()); //Send a TRYING response Response trying = null; try { trying = tiMessageFactory.createResponse( Response.TRYING, registerReceivedEvent.getRequest()); tran.sendResponse(trying); } catch (Exception ex) { throw new TiUnexpectedError( "Failed to send a TRYING response", ex); } waitForMessage(); //The transaction should now be PROCEEDING assertEquals( "The transaction did not pass into the PROCEEDING state " + "upon transmission of a 1xx response.", TransactionState.PROCEEDING, tran.getState()); ResponseEvent responseEvent = responseCollector.extractCollectedResponseEvent(); assertNotNull( "The TRYING response has not been sent by the TI.", responseEvent); assertTrue( "A response different from 100 was sent by the TI", Response.TRYING == responseEvent.getResponse().getStatusCode()); //Resend the REGISTER and see that the TRYING response is resent try { //listen for the Trying response responseCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to register a SipListener with an RI SipProvider", ex); } try { eventCollector.collectRequestEvent(tiSipProvider); riSipProvider.sendRequest(register); } catch (SipException ex) { throw new TckInternalError( "A SipExceptionOccurred while trying to send request!", ex); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with a TI SipProvider", ex); } //Wait for the REGISTER waitForMessage(); registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); assertNull( "Retransmitted REGISTERs should not be passed to the TU", registerReceivedEvent); //Wait for a retransmitted TRYING response waitForMessage(); //Verify whether there was a TRYING response responseEvent = responseCollector.extractCollectedResponseEvent(); assertNotNull( "No TRYING response has been resent by the TI upon reception " + "of a retransmitted REGISTER request", responseEvent); assertTrue( "A response different from 100 was sent by the TI upon " + "reception of a retransmitted REGISTER", Response.TRYING == responseEvent.getResponse().getStatusCode()); //Create & send RINGING. See that it is properly sent //and that tran state doesn't change Response ringing = null; try { ringing = tiMessageFactory.createResponse( Response.RINGING, tran.getRequest()); ((ToHeader) ringing.getHeader(ToHeader.NAME)).setTag( Integer.toString(hashCode())); } catch (ParseException ex) { throw new TiUnexpectedError( "A ParseException was thrown while trying to create a ringing " + "response using TI", ex); } try { //listen for the RINGING response responseCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to register a SipListener with an RI SipProvider", ex); } try { tran.sendResponse(ringing); } catch (SipException ex) { ex.printStackTrace(); fail("The TI failed to send a RINGING response"); } //The Transaction should still be PROCEEDING assertEquals( "The Transaction did not remain PROCEEDING after transmitting a RINGING response", TransactionState.PROCEEDING, tran.getState()); //Check whether the RINGING is received by the RI. waitForMessage(); responseEvent = responseCollector.extractCollectedResponseEvent(); assertNotNull( "The RINGING response was not received by the RI", responseEvent); assertTrue( "A response different from RINGING was sent by the TI", Response.RINGING == responseEvent.getResponse().getStatusCode()); //Resend the REGISTER, see that it is hidden from the TU and see that //the _RINGING_ response is resent (and not the TRYING) try { //listen for the Trying response responseCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to register a SipListener with an RI SipProvider", ex); } try { eventCollector.collectRequestEvent(tiSipProvider); riSipProvider.sendRequest(register); } catch (SipException ex) { throw new TckInternalError( "A SipExceptionOccurred while trying to send request!", ex); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with a TI SipProvider", ex); } //Wait for the REGISTER waitForMessage(); registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); assertNull( "Retransmitted REGISTERs should not be passed to the TU", registerReceivedEvent); //Wait for a retransmitted RINGING response waitForMessage(); //Verify whether there was a RINGING response responseEvent = responseCollector.extractCollectedResponseEvent(); assertNotNull( "No RINGING response has been sent by the TI upon reception " + "of an REGISTER request", responseEvent); assertTrue( "A response different from RINGING was sent by the TI upon " + "reception of a retransmitted REGISTER", Response.RINGING == responseEvent.getResponse().getStatusCode()); //We should still be proceeding assertEquals( "The server transaction left the PROCEEDING state.", TransactionState.PROCEEDING, tran.getState()); //Send 200 - 699 from TU and see the tran goes COMPLETED Response ok = null; try { ok = tiMessageFactory.createResponse( Response.OK, tran.getRequest()); ((ToHeader) ok.getHeader(ToHeader.NAME)).setTag( Integer.toString(hashCode())); } catch (ParseException ex) { throw new TiUnexpectedError( "A ParseException was thrown while trying to create a busy_here " + "response using TI", ex); } try { //listen for the BUSY_HERE response responseCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to register a SipListener with an RI SipProvider", ex); } try { tran.sendResponse(ok); } catch (SipException ex) { ex.printStackTrace(); fail("The TI failed to send a OK response"); } //The Transaction should now be COMPLETED assertEquals( "The Transaction did not remain COMPLETED after transmitting a BUSY_HERE response", TransactionState.COMPLETED, tran.getState()); //Check whether the OK is received by the RI. waitForMessage(); responseEvent = responseCollector.extractCollectedResponseEvent(); assertNotNull( "The OK response was not received by the RI", responseEvent); assertTrue( "A response different from OK was sent by the TI", Response.OK == responseEvent.getResponse().getStatusCode()); //Resend the initial from REGISTER from the RI and see that TI //resends the 200 - 699 (see that tran state remains COMPLETED) try { //listen for the OK response responseCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to register a SipListener with an RI SipProvider", ex); } try { eventCollector.collectRequestEvent(tiSipProvider); riSipProvider.sendRequest(register); } catch (SipException ex) { throw new TckInternalError( "A SipExceptionOccurred while trying to send request!", ex); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with a TI SipProvider", ex); } //Wait for the REGISTER waitForMessage(); registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); assertNull( "Retransmitted REGISTERs should not be passed to the TU", registerReceivedEvent); //Wait for a retransmitted OK response waitForMessage(); //Verify whether there was an OK response responseEvent = responseCollector.extractCollectedResponseEvent(); assertNotNull( "No OK response has been sent by the TI upon reception " + "of a retransmitted REGISTER request", responseEvent); assertTrue( "A response different from OK was sent by the TI upon " + "reception of a retransmitted invite REGISTER", Response.OK == responseEvent.getResponse().getStatusCode()); //We should still be COMPLETED assertEquals( "The server transaction left the COMPLETED state.", TransactionState.COMPLETED, tran.getState()); } catch (Throwable exc) { exc.printStackTrace(); fail(exc.getClass().getName() + ": " + exc.getMessage()); } assertTrue(new Exception().getStackTrace()[0].toString(), true); } /** * Tries to steer a TI server transaction through the following scenario * Trying-->Completed. Apart from state * transitions, we also test, retransmissions and proper hiding/passing * of messages to the TU. */ public void testTryingCompletedScenario() { try { Request register = createRiRegisterRequest(); SipEventCollector responseCollector = new SipEventCollector(); //Before Sending the request we should first register a listener with the //RI that would catch the TRYING response try { responseCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to register a SipListener with an RI SipProvider", ex); } //Send the initial request try { eventCollector.collectRequestEvent(tiSipProvider); riSipProvider.sendRequest(register); } catch (SipException ex) { throw new TckInternalError( "A SipExceptionOccurred while trying to send request!", ex); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with a TI SipProvider", ex); } waitForMessage(); RequestEvent registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); if (registerReceivedEvent == null || registerReceivedEvent.getRequest() == null) throw new TiUnexpectedError("The initial REGISTER request was not received by the TI!"); //Let's create the transaction ServerTransaction tran = null; try { tran = tiSipProvider.getNewServerTransaction( registerReceivedEvent.getRequest()); } catch (Exception ex) { ex.printStackTrace(); fail( ex.getClass().getName() + "was thrown while trying to " + "create the server transaction"); } assertNotNull( "tiSipProvider.getNewServerTransaction() returned null", tran); //At this point the ServerTransaction should be TRYING! assertEquals(TransactionState.TRYING, tran.getState()); //Send a TRYING response Response trying = null; try { trying = tiMessageFactory.createResponse( Response.TRYING, registerReceivedEvent.getRequest()); tran.sendResponse(trying); } catch (Exception ex) { throw new TiUnexpectedError( "Failed to send a TRYING response", ex); } //The transaction should now be PROCEEDING assertEquals( "The transaction did not pass into the PROCEEDING state " + "upon transmission of a 1xx response.", TransactionState.PROCEEDING, tran.getState()); waitForMessage(); ResponseEvent responseEvent = responseCollector.extractCollectedResponseEvent(); assertNotNull( "The TRYING response has not been sent by the TI.", responseEvent); assertTrue( "A response different from 100 was sent by the TI", Response.TRYING == responseEvent.getResponse().getStatusCode()); //Resend the REGISTER and see that the TRYING response is resent try { //listen for the Trying response responseCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to register a SipListener with an RI SipProvider", ex); } try { eventCollector.collectRequestEvent(tiSipProvider); riSipProvider.sendRequest(register); } catch (SipException ex) { throw new TckInternalError( "A SipExceptionOccurred while trying to send request!", ex); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with a TI SipProvider", ex); } //Wait for the REGISTER waitForMessage(); registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); assertNull( "Retransmitted REGISTERs should not be passed to the TU", registerReceivedEvent); //Wait for a retransmitted TRYING response waitForMessage(); //Verify whether there was a TRYING response responseEvent = responseCollector.extractCollectedResponseEvent(); assertNotNull( "No TRYING response has been resent by the TI upon reception " + "of a retransmitted REGISTER request", responseEvent); assertTrue( "A response different from 100 was sent by the TI upon " + "reception of a retransmitted REGISTER", Response.TRYING == responseEvent.getResponse().getStatusCode()); //Send 200 - 699 from TU and see the tran goes COMPLETED Response ok = null; try { ok = tiMessageFactory.createResponse( Response.OK, tran.getRequest()); ((ToHeader) ok.getHeader(ToHeader.NAME)).setTag( Integer.toString(hashCode())); } catch (ParseException ex) { throw new TiUnexpectedError( "A ParseException was thrown while trying to create a busy_here " + "response using TI", ex); } try { //listen for the BUSY_HERE response responseCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to register a SipListener with an RI SipProvider", ex); } try { tran.sendResponse(ok); } catch (SipException ex) { ex.printStackTrace(); fail("The TI failed to send a OK response"); } //The Transaction should now be COMPLETED assertEquals( "The Transaction did not remain COMPLETED after transmitting a BUSY_HERE response", TransactionState.COMPLETED, tran.getState()); //Check whether the OK is received by the RI. waitForMessage(); responseEvent = responseCollector.extractCollectedResponseEvent(); assertNotNull( "The OK response was not received by the RI", responseEvent); assertTrue( "A response different from OK was sent by the TI", Response.OK == responseEvent.getResponse().getStatusCode()); //Resend the initial from REGISTER from the RI and see that TI //resends the 200 - 699 (see that tran state remains COMPLETED) try { //listen for the OK response responseCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError( "Failed to register a SipListener with an RI SipProvider", ex); } try { eventCollector.collectRequestEvent(tiSipProvider); riSipProvider.sendRequest(register); } catch (SipException ex) { throw new TckInternalError( "A SipExceptionOccurred while trying to send request!", ex); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "Failed to register a SipListener with a TI SipProvider", ex); } //Wait for the REGISTER waitForMessage(); registerReceivedEvent = eventCollector.extractCollectedRequestEvent(); assertNull( "Retransmitted REGISTERs should not be passed to the TU", registerReceivedEvent); //Wait for a retransmitted OK response waitForMessage(); //Verify whether there was an OK response responseEvent = responseCollector.extractCollectedResponseEvent(); assertNotNull( "No OK response has been sent by the TI upon reception " + "of a retransmitted REGISTER request", responseEvent); assertTrue( "A response different from OK was sent by the TI upon " + "reception of a retransmitted invite REGISTER", Response.OK == responseEvent.getResponse().getStatusCode()); //We should still be COMPLETED assertEquals( "The server transaction left the COMPLETED state.", TransactionState.COMPLETED, tran.getState()); } 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(NonInviteServerTransactionsStateMachineTest.class); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy