001: /*
002: * Conditions Of Use
003: *
004: * This software was developed by employees of the National Institute of
005: * Standards and Technology (NIST), and others.
006: * This software is has been contributed to the public domain.
007: * As a result, a formal license is not needed to use the software.
008: *
009: * This software is provided "AS IS."
010: * NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
011: * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
012: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
013: * AND DATA ACCURACY. NIST does not warrant or make any representations
014: * regarding the use of the software or the results thereof, including but
015: * not limited to the correctness, accuracy, reliability or usefulness of
016: * the software.
017: *
018: *
019: */
020: package test.tck.msgflow;
021:
022: import junit.framework.*;
023:
024: import javax.sip.*;
025: import javax.sip.message.*;
026: import javax.sip.header.*;
027: import java.util.List;
028: import java.util.*;
029: import java.text.*;
030: import test.tck.*;
031:
032: /**
033: * <p>Title: TCK</p>
034: * <p>Description: JAIN SIP 1.1 Technology Compatibility Kit</p>
035: * <p>Copyright: Copyright (c) 2003</p>
036: * <p>Company: NIST</p>
037: * @author Emil Ivov
038: * Network Research Team, Louis Pasteur University, Strasbourg, France.
039: * This code is in the public domain.
040: * @version 1.0
041: */
042:
043: public class SipProviderTest extends MessageFlowHarness {
044:
045: public SipProviderTest(String name) {
046: super (name, true);
047: }
048:
049: //======================= tests ====================================
050: /**
051: * Sends a single invite request and checks whether it arrives normally
052: * at the other end.
053: */
054: public void testSendRequest() {
055: try {
056: //create an empty invite request.
057: Request invite = createTiInviteRequest(null, null, null);
058: Request receivedRequest = null;
059: try {
060: //Send using TI and collect using RI
061: eventCollector.collectRequestEvent(riSipProvider);
062: waitForMessage();
063: tiSipProvider.sendRequest(invite);
064: waitForMessage();
065: RequestEvent receivedRequestEvent = eventCollector
066: .extractCollectedRequestEvent();
067: assertNotNull(
068: "The sent request was not received at the other end!",
069: receivedRequestEvent);
070: assertNotNull(
071: "The sent request was not received at the other end!",
072: receivedRequestEvent.getRequest());
073: } catch (TooManyListenersException ex) {
074: throw new TckInternalError(
075: "The following exception was thrown while trying to add "
076: + "a SipListener to an RI SipProvider",
077: ex);
078: } catch (SipException ex) {
079: ex.printStackTrace();
080: fail("A SipException exception was thrown while "
081: + "trying to send a request.");
082: }
083: } catch (Throwable exc) {
084: exc.printStackTrace();
085: fail(exc.getClass().getName() + ": " + exc.getMessage());
086: }
087: assertTrue(new Exception().getStackTrace()[0].toString(), true);
088: }
089:
090: /**
091: *Sends a empty request and assures that the other side does not see the request.
092: *
093: */
094: public void testSendNullRequest() {
095: try {
096: try {
097: Request nullRequest = riMessageFactory
098: .createRequest("");
099:
100: //Send using RI and collect using TI
101: eventCollector.collectRequestEvent(tiSipProvider);
102: riSipProvider.sendRequest(nullRequest);
103: waitForMessage();
104: RequestEvent receivedRequestEvent = eventCollector
105: .extractCollectedRequestEvent();
106:
107: if (receivedRequestEvent != null)
108: throw new TiUnexpectedError(
109: "The the sent null string request should not generate a request event!");
110: } catch (TooManyListenersException ex) {
111: throw new TiUnexpectedError(
112: "A TooManyListenersException was thrown while trying to add "
113: + "a SipListener to a TI SipProvider.",
114: ex);
115: } catch (SipException ex) {
116: throw new TckInternalError(
117: "The RI failed to send the request!", ex);
118: } catch (ParseException ex) {
119: throw new TiUnexpectedError(
120: "The null request did not parse and create an empty message!");
121: }
122:
123: } catch (Throwable exc) {
124: exc.printStackTrace();
125: fail(exc.getClass().getName() + ": " + exc.getMessage());
126: }
127: assertTrue(new Exception().getStackTrace()[0].toString(), true);
128: }
129:
130: /**
131: * Send a simple invite request from the RI and check whether it is properly
132: * delivered by the TI SipProvider
133: */
134: public void testReceiveRequest() {
135: try {
136: //create an empty invite request.
137: Request invite = createRiInviteRequest(null, null, null);
138: RequestEvent receivedRequestEvent = null;
139: try {
140: //Send using RI and collect using TI
141: eventCollector.collectRequestEvent(tiSipProvider);
142: riSipProvider.sendRequest(invite);
143: waitForMessage();
144: receivedRequestEvent = eventCollector
145: .extractCollectedRequestEvent();
146: assertNotNull(
147: "The sent request was not received at the other end!",
148: receivedRequestEvent);
149: assertNotNull(
150: "The sent request was not received at the other end!",
151: receivedRequestEvent.getRequest());
152: } catch (TooManyListenersException ex) {
153: //This time adding the listener is (sort of) part of the test
154: //so we fail instead of just "throwing on" the exc
155: ex.printStackTrace();
156: fail("A TooManyListenersException was thrown while trying to add "
157: + "a SipListener to a TI SipProvider.");
158: } catch (SipException ex) {
159: throw new TckInternalError(
160: "The RI failed to send the request!", ex);
161: }
162: //question: should we compare sent and received request?
163: //my opinion: finding a discrepancy while comparing requests
164: //would most probably mean a parse error and parsing is not what
165: //we are currently testing
166: //Transaction initiating requests should not have a server transaction
167: //associated with them as the application might decide to handle the
168: //request statelessly
169: assertNull(
170: "The Tested Implementation has implicitly created a ServerTransaction "
171: + "for the received request. Transactions should only be created "
172: + "explicitly using the SipProvider.getNewXxxTransaction() method.",
173: receivedRequestEvent.getServerTransaction());
174: } catch (Throwable exc) {
175: exc.printStackTrace();
176: fail(exc.getClass().getName() + ": " + exc.getMessage());
177: }
178: assertTrue(new Exception().getStackTrace()[0].toString(), true);
179: }
180:
181: /**
182: * Sends a single ACK request from the RI, and tests if the TI passes it to the
183: * application
184: *
185: * ACKs MUST NOT be filtered for stateless proxy applications, they must forward them
186: */
187: public void testReceiveACK() {
188: try {
189: //create an empty ACK request.
190: Request ack = createRiInviteRequest(null, null, null);
191: ack.setMethod(Request.ACK);
192: RequestEvent receivedRequestEvent = null;
193: try {
194: //Send using RI and collect using TI
195: eventCollector.collectRequestEvent(tiSipProvider);
196: riSipProvider.sendRequest(ack);
197: waitForMessage();
198: receivedRequestEvent = eventCollector
199: .extractCollectedRequestEvent();
200: assertNotNull(
201: "The sent ACK event was not received at the other end!",
202: receivedRequestEvent);
203: assertNotNull(
204: "The sent ACK was not received at the other end!",
205: receivedRequestEvent.getRequest());
206: } catch (TooManyListenersException ex) {
207: //This time adding the listener is (sort of) part of the test
208: //so we fail instead of just "throwing on" the exc
209: ex.printStackTrace();
210: fail("A TooManyListenersException was thrown while trying to add "
211: + "a SipListener to a TI SipProvider.");
212: } catch (SipException ex) {
213: throw new TckInternalError(
214: "The RI failed to send the request!", ex);
215: }
216: //question: should we compare sent and received request?
217: //my opinion: finding a discrepancy while comparing requests
218: //would most probably mean a parse error and parsing is not what
219: //we are currently testing
220: //Transaction initiating requests should not have a server transaction
221: //associated with them as the application might decide to handle the
222: //request statelessly
223: assertNull(
224: "The Tested Implementation has implicitly created a ServerTransaction "
225: + "for the received request. Transactions should only be created "
226: + "explicitly using the SipProvider.getNewXxxTransaction() method.",
227: receivedRequestEvent.getServerTransaction());
228: } catch (Throwable exc) {
229: exc.printStackTrace();
230: fail(exc.getClass().getName() + ": " + exc.getMessage());
231: }
232: assertTrue(new Exception().getStackTrace()[0].toString(), true);
233: }
234:
235: /**
236: * Sends a request from the RI, generates a response at the TI side, sends
237: * it back and checks whether it arrives at the RI.
238: */
239: public void testSendResponse() {
240: try {
241: // 1. Create and send the original request
242:
243: Request invite = createRiInviteRequest(null, null, null);
244: RequestEvent receivedRequestEvent = null;
245: try {
246: //Send using RI and collect using TI
247: eventCollector.collectRequestEvent(tiSipProvider);
248: riSipProvider.sendRequest(invite);
249: waitForMessage();
250: receivedRequestEvent = eventCollector
251: .extractCollectedRequestEvent();
252: if (receivedRequestEvent == null
253: || receivedRequestEvent.getRequest() == null)
254: throw new TiUnexpectedError(
255: "The sent request was not received by the RI!");
256: } catch (TooManyListenersException ex) {
257: throw new TiUnexpectedError(
258: "A TooManyListenersException was thrown while trying to add "
259: + "a SipListener to a TI SipProvider.",
260: ex);
261: } catch (SipException ex) {
262: throw new TckInternalError(
263: "The RI failed to send the request!", ex);
264: }
265: Request receivedRequest = receivedRequestEvent.getRequest();
266: // 2. Create and send the response
267: //Create an ok response. We are not testing the message factory so let's
268: //not leave it a chance to mess something up and specify the response
269: //as completely as possible.
270: List via = new LinkedList();
271: via.add(receivedRequest.getHeader(ViaHeader.NAME));
272: Response ok = null;
273: try {
274: ok = tiMessageFactory.createResponse(Response.OK,
275: (CallIdHeader) receivedRequest
276: .getHeader(CallIdHeader.NAME),
277: (CSeqHeader) receivedRequest
278: .getHeader(CSeqHeader.NAME),
279: (FromHeader) receivedRequest
280: .getHeader(FromHeader.NAME),
281: (ToHeader) receivedRequest
282: .getHeader(ToHeader.NAME), via,
283: (MaxForwardsHeader) receivedRequest
284: .getHeader(MaxForwardsHeader.NAME));
285:
286: // JvB: set to-tag for RFC3261 compliance
287: ((ToHeader) ok.getHeader("To")).setTag("ok");
288:
289: addStatus(receivedRequest, ok);
290: } catch (ParseException ex) {
291: throw new TiUnexpectedError(
292: "Failed to create an OK response!", ex);
293: }
294: //Send the response using the TI and collect using RI
295: try {
296: eventCollector.collectResponseEvent(riSipProvider);
297: } catch (TooManyListenersException ex) {
298: throw new TckInternalError(
299: "Error while trying to add riSipProvider");
300: }
301: try {
302: tiSipProvider.sendResponse(ok);
303: } catch (SipException ex) {
304: ex.printStackTrace();
305: fail("A SipException occurred while trying to send an ok response.");
306: }
307: waitForMessage();
308: ResponseEvent responseEvent = eventCollector
309: .extractCollectedResponseEvent();
310: assertNotNull(
311: "The sent response was not received by the RI!",
312: responseEvent);
313: assertNotNull(
314: "The sent response was not received by the RI!",
315: responseEvent.getResponse());
316: } catch (Throwable exc) {
317: exc.printStackTrace();
318: fail(exc.getClass().getName() + ": " + exc.getMessage());
319: }
320: assertTrue(new Exception().getStackTrace()[0].toString(), true);
321:
322: }
323:
324: /**
325: * Sends a request from the TI, generates a response at the RI side, sends
326: * it back and checks whether it arrives at the TI.
327: */
328: public void testReceiveResponse() {
329: try {
330: // 1. Create and send the original request
331:
332: Request invite = createTiInviteRequest(null, null, null);
333: RequestEvent receivedRequestEvent = null;
334: try {
335: //Send using TI and collect using RI
336: eventCollector.collectRequestEvent(riSipProvider);
337: tiSipProvider.sendRequest(invite);
338: waitForMessage();
339: receivedRequestEvent = eventCollector
340: .extractCollectedRequestEvent();
341: if (receivedRequestEvent == null
342: || receivedRequestEvent.getRequest() == null)
343: throw new TckInternalError(
344: "The sent request was not received by the RI!");
345: } catch (TooManyListenersException ex) {
346: throw new TckInternalError(
347: "A TooManyListenersException was thrown while trying to add "
348: + "a SipListener to an RI SipProvider.",
349: ex);
350: } catch (SipException ex) {
351: throw new TiUnexpectedError(
352: "The TI failed to send the request!", ex);
353: }
354: Request receivedRequest = receivedRequestEvent.getRequest();
355: // 2. Create and send the response
356: Response ok = null;
357: try {
358: ok = riMessageFactory.createResponse(Response.OK,
359: receivedRequest);
360:
361: // JvB: set to-tag for RFC3261 compliance
362: ((ToHeader) ok.getHeader("To")).setTag("ok");
363:
364: addStatus(receivedRequest, ok);
365: } catch (ParseException ex) {
366: throw new TckInternalError(
367: "Failed to create an OK response!", ex);
368: }
369: //Send the response using the RI and collect using TI
370: try {
371: eventCollector.collectResponseEvent(tiSipProvider);
372: } catch (TooManyListenersException ex) {
373: throw new TiUnexpectedError(
374: "Error while trying to add riSipProvider");
375: }
376: try {
377: riSipProvider.sendResponse(ok);
378: } catch (SipException ex) {
379: throw new TckInternalError(
380: "Could not send back the response", ex);
381: }
382: waitForMessage();
383: ResponseEvent responseEvent = eventCollector
384: .extractCollectedResponseEvent();
385: //3. Now ... do we like what we got?
386: assertNotNull("The TI failed to receive the response!",
387: responseEvent);
388: assertNotNull("The TI failed to receive the response!",
389: responseEvent.getResponse());
390: assertNull(
391: "The TI had implicitly created a client transaction! "
392: + "Transactions should only be created explicitly using "
393: + "the SipProvider.getNewXxxTransaction() method.",
394: responseEvent.getClientTransaction());
395: } catch (Throwable exc) {
396: exc.printStackTrace();
397: fail(exc.getClass().getName() + ": " + exc.getMessage());
398: }
399: assertTrue(new Exception().getStackTrace()[0].toString(), true);
400: }
401:
402: /**
403: * Test whether new ClientTransactions are properly created.
404: */
405: public void testGetNewClientTransaction() {
406: try {
407: Request invite = createTiInviteRequest(null, null, null);
408: ClientTransaction tran = null;
409: try {
410: tran = tiSipProvider.getNewClientTransaction(invite);
411: } catch (TransactionUnavailableException exc) {
412: exc.printStackTrace();
413: fail("A TransactionUnavailableException was thrown while trying to "
414: + "create a new client transaction");
415: }
416: assertNotNull(
417: "A null ClientTransaction was returned by SipProvider."
418: + "getNewClientTransaction().", tran);
419: String tranBranch = tran.getBranchId();
420: String reqBranch = ((ViaHeader) invite
421: .getHeader(ViaHeader.NAME)).getBranch();
422: assertEquals(
423: "The newly created transaction did not have the same "
424: + "branch id as the request that created it",
425: tranBranch, reqBranch);
426: assertNotNull(
427: "The transaction's getRequest() method returned a null Request ",
428: tran.getRequest());
429: assertEquals(
430: "The transaction's getRequest() method returned a Request "
431: + "that did not match the one that we used to create it!",
432: tran.getRequest(), invite);
433: } catch (Throwable exc) {
434: exc.printStackTrace();
435: fail(exc.getClass().getName() + ": " + exc.getMessage());
436: }
437: assertTrue(new Exception().getStackTrace()[0].toString(), true);
438:
439: }
440:
441: /**
442: * Sends a request from the RI and tests whether the tested implementation
443: * properly creates a ServerTransaction.
444: */
445: public void testGetNewServerTransaction() {
446: try {
447: Request invite = createRiInviteRequest(null, null, null);
448: ServerTransaction tran = null;
449: RequestEvent receivedRequestEvent = null;
450: try {
451: //Send using RI and collect using TI
452: eventCollector.collectRequestEvent(tiSipProvider);
453: riSipProvider.sendRequest(invite);
454: waitForMessage();
455: receivedRequestEvent = eventCollector
456: .extractCollectedRequestEvent();
457: if (receivedRequestEvent == null
458: || receivedRequestEvent.getRequest() == null)
459: throw new TiUnexpectedError(
460: "The sent request was not received by the RI!");
461: } catch (TooManyListenersException ex) {
462: throw new TiUnexpectedError(
463: "A TooManyListenersException was thrown while trying to add "
464: + "a SipListener to a TI SipProvider.",
465: ex);
466: } catch (SipException ex) {
467: throw new TckInternalError(
468: "The RI failed to send the request!", ex);
469: }
470: try {
471: //issue 16 on dev.java.net - create tran using received invite
472: //and not the ri request object.
473: //report and fix thereof - larryb@dev.java.net
474: tran = tiSipProvider
475: .getNewServerTransaction(receivedRequestEvent
476: .getRequest());
477: } catch (TransactionUnavailableException exc) {
478: exc.printStackTrace();
479: fail("A TransactionUnavailableException was thrown while trying to "
480: + "create a new client transaction");
481: } catch (TransactionAlreadyExistsException exc) {
482: exc.printStackTrace();
483: fail("A TransactionAlreadyExistsException was thrown while trying to "
484: + "create a new server transaction");
485: }
486: assertNotNull(
487: "A null ServerTransaction was returned by SipProvider."
488: + "getNewServerTransaction().", tran);
489: String tranBranch = tran.getBranchId();
490: String reqBranch = ((ViaHeader) invite
491: .getHeader(ViaHeader.NAME)).getBranch();
492: assertEquals(
493: "The newly created transaction did not have the same "
494: + "branch id as the request that created it!",
495: tranBranch, reqBranch);
496: assertNotNull(
497: "The newly created transaction returned a null Dialog. "
498: + "Please check the docs on Transaction.getDialog()",
499: tran.getDialog());
500: assertNotNull(
501: "The transaction's getRequest() method returned a null Request ",
502: tran.getRequest());
503: assertEquals(
504: "The transaction's getRequest() method returned a Request "
505: + "that did not match the one that we used to create it!",
506: tran.getRequest(), receivedRequestEvent
507: .getRequest());
508: // BUG reported by Ben Evans: comparing
509: // RI and TI objects using equals() is bound to fail
510: // if they are different implementations.
511:
512: } catch (Throwable exc) {
513: exc.printStackTrace();
514: fail(exc.getClass().getName() + ": " + exc.getMessage());
515: }
516: assertTrue(new Exception().getStackTrace()[0].toString(), true);
517: }
518:
519: //==================== end of tests
520:
521: //====== STATIC JUNIT ==========
522: public static Test suite() {
523: return new TestSuite(SipProviderTest.class);
524: }
525:
526: }
527: /**
528: *
529: */
|