001: package test.tck.factory;
002:
003: import java.lang.reflect.InvocationTargetException;
004: import java.lang.reflect.Method;
005: import java.text.ParseException;
006: import java.util.LinkedList;
007: import java.util.List;
008: import java.util.ListIterator;
009: import java.util.TreeSet;
010:
011: import javax.sip.address.Address;
012: import javax.sip.address.SipURI;
013: import javax.sip.header.CSeqHeader;
014: import javax.sip.header.CallIdHeader;
015: import javax.sip.header.ContentLengthHeader;
016: import javax.sip.header.ContentTypeHeader;
017: import javax.sip.header.ExtensionHeader;
018: import javax.sip.header.FromHeader;
019: import javax.sip.header.Header;
020: import javax.sip.header.MaxForwardsHeader;
021: import javax.sip.header.ToHeader;
022: import javax.sip.header.ViaHeader;
023: import javax.sip.message.Message;
024: import javax.sip.message.Request;
025: import javax.sip.message.Response;
026:
027: import junit.framework.Test;
028: import junit.framework.TestSuite;
029: import test.tck.TckInternalError;
030: import test.tck.TiUnexpectedError;
031:
032: public class MessageFactoryTest extends FactoryTestHarness {
033:
034: protected String method;
035:
036: protected javax.sip.address.URI tiRequestURI;
037: protected CallIdHeader ticallId;
038: protected FromHeader tifrom;
039: protected ToHeader tito;
040: protected MaxForwardsHeader timaxForwards;
041: protected ContentTypeHeader ticontentType;
042: protected List tivia;
043: protected CSeqHeader ticSeq;
044: protected ExtensionHeader tiextensionHeader;
045:
046: protected javax.sip.address.URI riRequestURI;
047: protected CallIdHeader ricallId;
048: protected FromHeader rifrom;
049: protected ToHeader rito;
050: protected MaxForwardsHeader rimaxForwards;
051: protected ContentTypeHeader ricontentType;
052: protected List rivia;
053: protected CSeqHeader ricSeq;
054: protected ExtensionHeader riextensionHeader;
055:
056: protected byte[] contentBytes;
057: protected Object contentObject;
058: protected int statusCode;
059:
060: public MessageFactoryTest() {
061: super ("MessageFactoryTest");
062: }
063:
064: private void cloneTest(Request request) {
065: try {
066: Request newRequest = (Request) request.clone();
067: assertEquals(newRequest, request);
068: newRequest.setMethod("FOOBAR");
069: assertFalse(newRequest.equals(request));
070: newRequest = (Request) request.clone();
071: // Add the extension header.
072: Header extensionHeader = tiHeaderFactory.createHeader(
073: "My-Header", "my header value");
074: request.addHeader(extensionHeader);
075: assertFalse(newRequest.equals(request));
076: request.removeHeader("My-Header");
077: assertEquals(newRequest, request);
078: } catch (Exception ex) {
079: ex.printStackTrace();
080: fail(ex.getMessage());
081: } finally {
082: logTestCompleted("cloneTest(request)");
083: }
084: }
085:
086: private void cloneTest(Response response) {
087: try {
088: Response newResponse = (Response) response.clone();
089: assertEquals(newResponse, response);
090: assertNotSame(newResponse, response);
091: newResponse = (Response) response.clone();
092: // Add the extension header.
093: Header extensionHeader = tiHeaderFactory.createHeader(
094: "My-Header", "my header value");
095: newResponse.addHeader(extensionHeader);
096: assertFalse(newResponse.equals(response));
097: newResponse.removeHeader("My-Header");
098: assertEquals(newResponse, response);
099: } catch (ParseException ex) {
100: fail(ex.getMessage());
101: } finally {
102: logTestCompleted("cloneTest(response)");
103: }
104: }
105:
106: /**
107: * Tests whether the TI is compliant with the RI for a created message
108: * 'Compliant' means that the TI message must at least contain all headers
109: * that the RI message contains, and each such header must be equal
110: * (according to the RI definition of equals())
111: *
112: * Note that the ~order~ in which the headers appear is arbitrary, and that the
113: * TI may contain additional headers (e.g. User-Agent)
114: *
115: * @author JvB
116: *
117: * @param tiMsg
118: * @param riMsg
119: */
120: private void testAgainstRIMsg(Message tiMsg, Message riMsg) {
121:
122: // Test equality using RI definition of equals
123: assertEquals(riMsg.getHeader(FromHeader.NAME), tiMsg
124: .getHeader(FromHeader.NAME));
125: assertEquals(riMsg.getHeader(ToHeader.NAME), tiMsg
126: .getHeader(ToHeader.NAME));
127: assertEquals(riMsg.getHeader(ViaHeader.NAME), tiMsg
128: .getHeader(ViaHeader.NAME));
129: assertEquals(riMsg.getHeader(CallIdHeader.NAME), tiMsg
130: .getHeader(CallIdHeader.NAME));
131: assertEquals(riMsg.getHeader(CSeqHeader.NAME), tiMsg
132: .getHeader(CSeqHeader.NAME));
133: }
134:
135: private void testAgainstRIMsgContent(Message tiMsg, Message riMsg) {
136:
137: // Test equality using RI definition of equals
138: assertEquals(riMsg.getHeader(ContentLengthHeader.NAME), tiMsg
139: .getHeader(ContentLengthHeader.NAME));
140: assertEquals(riMsg.getHeader(ContentTypeHeader.NAME), tiMsg
141: .getHeader(ContentTypeHeader.NAME));
142: assertEquals(riMsg.getContent(), tiMsg.getContent());
143: }
144:
145: private void testAgainstRI(Response tiResponse, Response riResponse) {
146: try {
147: assertEquals(riResponse.getStatusCode(), tiResponse
148: .getStatusCode());
149: testAgainstRIMsg(tiResponse, riResponse);
150: } catch (Throwable ex) {
151: ex.printStackTrace();
152: fail(ex.getMessage());
153: } finally {
154: logTestCompleted("testAgainstRI(testResponse)");
155: }
156: }
157:
158: private void testAgainstRI(Request tiRequest, Request riRequest) {
159: try {
160: assertEquals(riRequest.getMethod(), tiRequest.getMethod());
161: assertEquals(riRequest.getRequestURI(), tiRequest
162: .getRequestURI());
163: assertEquals(riRequest.getHeader(MaxForwardsHeader.NAME),
164: tiRequest.getHeader(MaxForwardsHeader.NAME));
165: testAgainstRIMsg(tiRequest, riRequest);
166: } catch (Throwable ex) {
167: ex.printStackTrace();
168: fail(ex.getMessage());
169: } finally {
170: logTestCompleted("testAgainstRI(testRequest)");
171: }
172: }
173:
174: public void testCreateRequest() {
175: try {
176: Request tiRequest = tiMessageFactory.createRequest(
177: tiRequestURI, method, ticallId, ticSeq, tifrom,
178: tito, tivia, timaxForwards, ticontentType,
179: contentObject);
180: cloneTest(tiRequest);
181:
182: Request riRequest = riMessageFactory.createRequest(
183: riRequestURI, method, ricallId, ricSeq, rifrom,
184: rito, rivia, rimaxForwards, ricontentType,
185: contentObject);
186:
187: testAgainstRI(tiRequest, riRequest);
188: testAgainstRIMsgContent(tiRequest, riRequest);
189:
190: tiRequest = tiMessageFactory.createRequest(tiRequestURI,
191: method, ticallId, ticSeq, tifrom, tito, tivia,
192: timaxForwards, ticontentType, contentBytes);
193: cloneTest(tiRequest);
194: riRequest = riMessageFactory.createRequest(riRequestURI,
195: method, ricallId, ricSeq, rifrom, rito, rivia,
196: rimaxForwards, ricontentType, contentBytes);
197: cloneTest(tiRequest);
198: testAgainstRI(tiRequest, riRequest);
199: testAgainstRIMsgContent(tiRequest, riRequest);
200:
201: Response tiResponse = tiMessageFactory.createResponse(
202: statusCode, ticallId, ticSeq, tifrom, tito, tivia,
203: timaxForwards, ticontentType, contentObject);
204:
205: cloneTest(tiResponse);
206: Response riResponse = riMessageFactory.createResponse(
207: statusCode, ricallId, ricSeq, rifrom, rito, rivia,
208: rimaxForwards, ricontentType, contentObject);
209: testAgainstRI(tiResponse, riResponse);
210: testAgainstRIMsgContent(tiResponse, riResponse);
211:
212: tiResponse = tiMessageFactory.createResponse(statusCode,
213: ticallId, ticSeq, tifrom, tito, tivia,
214: timaxForwards, ticontentType, contentObject);
215: cloneTest(tiResponse);
216: riResponse = riMessageFactory.createResponse(statusCode,
217: ricallId, ricSeq, rifrom, rito, rivia,
218: rimaxForwards, ricontentType, contentObject);
219: testAgainstRI(tiResponse, riResponse);
220: testAgainstRIMsgContent(tiResponse, riResponse);
221:
222: tiResponse = tiMessageFactory.createResponse(statusCode,
223: ticallId, ticSeq, tifrom, tito, tivia,
224: timaxForwards);
225: cloneTest(tiResponse);
226: riResponse = riMessageFactory.createResponse(statusCode,
227: ricallId, ricSeq, rifrom, rito, rivia,
228: rimaxForwards);
229:
230: testAgainstRI(tiResponse, riResponse);
231:
232: tiResponse = tiMessageFactory.createResponse(statusCode,
233: tiRequest, ticontentType, contentBytes);
234: cloneTest(tiResponse);
235: riResponse = riMessageFactory.createResponse(statusCode,
236: riRequest, ricontentType, contentBytes);
237: testAgainstRI(tiResponse, riResponse);
238: testAgainstRIMsgContent(tiResponse, riResponse);
239:
240: tiResponse = tiMessageFactory.createResponse(statusCode,
241: tiRequest, ticontentType, contentObject);
242: cloneTest(tiResponse);
243: riResponse = riMessageFactory.createResponse(statusCode,
244: riRequest, ricontentType, contentObject);
245: testAgainstRI(tiResponse, riResponse);
246: testAgainstRIMsgContent(tiResponse, riResponse);
247:
248: tiResponse = tiMessageFactory.createResponse(statusCode,
249: tiRequest);
250: cloneTest(tiResponse);
251: riResponse = riMessageFactory.createResponse(statusCode,
252: riRequest);
253: testAgainstRI(tiResponse, riResponse);
254: } catch (Throwable ex) {
255: ex.printStackTrace();
256: fail(ex.getMessage());
257: } finally {
258: logTestCompleted("testCreateRequest()");
259: }
260:
261: }
262:
263: public void testCreateRequest1() {
264: try {
265: Request request = tiMessageFactory.createRequest(
266: tiRequestURI, method, ticallId, ticSeq, tifrom,
267: tito, tivia, timaxForwards);
268: String msgString = request.toString();
269: assertEquals(request, tiMessageFactory
270: .createRequest(msgString));
271: } catch (Exception ex) {
272: ex.printStackTrace();
273: fail(ex.getMessage());
274: } finally {
275: logTestCompleted("testCreateRequest1()");
276: }
277: }
278:
279: private void testGetMethods(Request refRequest,
280: Request requestToTest) throws IllegalAccessException,
281: InvocationTargetException {
282: try {
283: Class implementationClass;
284:
285: implementationClass = refRequest.getClass();
286:
287: Class[] implementedInterfaces = implementationClass
288: .getInterfaces();
289: int j = 0;
290:
291: // Do a TCK consistency check.
292: for (j = 0; j < implementedInterfaces.length; j++) {
293: if (javax.sip.message.Request.class
294: .isAssignableFrom(implementedInterfaces[j]))
295: break;
296: }
297: if (j == implementedInterfaces.length) {
298: System.out.println("Hmm... could not find it"
299: + refRequest.getClass());
300: throw new TckInternalError("Request not implemented");
301: }
302:
303: String jainClassName = implementedInterfaces[j].getName();
304:
305: // Make sure that all the methods of the interface are implemented
306: checkImplementsInterface(requestToTest.getClass(),
307: Request.class);
308:
309: // Test the get methods of the interface.
310: Method methods[] = implementedInterfaces[j]
311: .getDeclaredMethods();
312: for (int i = 0; i < methods.length; i++) {
313: String methodName = methods[i].getName();
314: if (!methodName.startsWith("get"))
315: continue;
316: // Testing only null argument gets
317: if (methods[i].getParameterTypes().length != 0)
318: continue;
319: Class returnType = methods[i].getReturnType();
320: Object refType = null;
321: try {
322: refType = methods[i].invoke(refRequest,
323: (Object[]) null);
324: } catch (Exception ex) {
325: throw new TckInternalError("Invocation failure "
326: + methodName);
327: }
328: String ftype = returnType.toString();
329: if (returnType.isPrimitive()) {
330: Object testValue = methods[i].invoke(requestToTest,
331: (Object[]) null);
332: assertEquals(refType, testValue);
333: } else {
334: // Non primitive.
335: Object testValue = methods[i].invoke(requestToTest,
336: (Object[]) null);
337: if (refType != null) {
338: assertTrue(testValue != null);
339: // Find the jain type implemented by the interface.
340: Class fclass = refType.getClass();
341: Class[] fInterfaces = fclass.getInterfaces();
342: // Find what JAIN interface this is implementing.
343: int k = 0;
344: for (k = 0; k < fInterfaces.length; k++) {
345: if (javax.sip.header.Header.class
346: .isAssignableFrom(fInterfaces[k]))
347: break;
348: }
349: // If this implements a header interface
350: // check that the same header is returned in both
351: // ti and ri
352: if (k < fInterfaces.length) {
353: // Make sure that the return type matches.
354: assertTrue(fInterfaces[k]
355: .isAssignableFrom(testValue
356: .getClass()));
357: String refhdrString = refType.toString();
358: String testhdrString = testValue.toString();
359: // Use the factory to test for equivalence
360: Header riHeader = createRiHeaderFromString(refhdrString);
361: if (riHeader == null)
362: throw new TckInternalError(
363: "could not parse "
364: + refhdrString);
365:
366: // Create a RI header from the string to test
367: // for equivalence. Note that we cannot compare
368: // ti header to RI header otherwise.
369: Header tiHeader = createRiHeaderFromString(testhdrString);
370: assertNotNull(tiHeader);
371: assertEquals(
372: "Retrieved header did not match RI",
373: riHeader, tiHeader);
374: }
375: } else if (refType == null) {
376: assertTrue(testValue == null);
377: }
378: }
379:
380: }
381: } catch (Exception ex) {
382: throw new TiUnexpectedError(ex.getMessage());
383: }
384:
385: }
386:
387: public void testMessageGetMethods() {
388: try {
389: Request tiRequest = tiMessageFactory
390: .createRequest(msgString);
391: Request riRequest = riMessageFactory
392: .createRequest(msgString);
393:
394: testGetMethods(riRequest, tiRequest);
395:
396: } catch (Exception ex) {
397: assertTrue(false);
398: } finally {
399: logTestCompleted("testMessageGetMethods()");
400: }
401: }
402:
403: public void testGetHeaderNames() {
404: // BUG report by Ben Evans (opencloud)
405: // This test assumed implementations will store header names
406: // using mixed case, eg. "Content-Type" not "content-type".
407: // Header names are not case sensitive in RFC3261 so this is not
408: // a real requirement.
409: try {
410: Request request = tiMessageFactory.createRequest(
411: tiRequestURI, method, ticallId, ticSeq, tifrom,
412: tito, tivia, timaxForwards, ticontentType,
413: contentObject);
414: ListIterator li = request.getHeaderNames();
415: // Use a tree set with case insensitive ordering & comparison
416: TreeSet set = new TreeSet(String.CASE_INSENSITIVE_ORDER);
417: while (li.hasNext()) {
418: String hdrName = (String) li.next();
419: set.add(hdrName);
420: }
421: assertTrue(set.contains(CSeqHeader.NAME));
422: assertTrue(set.contains(FromHeader.NAME));
423: assertTrue(set.contains(ToHeader.NAME));
424: assertTrue(set.contains(ViaHeader.NAME));
425: assertTrue(set.contains(MaxForwardsHeader.NAME));
426: assertTrue(set.contains(ContentTypeHeader.NAME));
427: assertTrue(set.contains(CallIdHeader.NAME));
428: Response response = tiMessageFactory.createResponse(
429: statusCode, ticallId, ticSeq, tifrom, tito, tivia,
430: timaxForwards, ticontentType, contentObject);
431: li = request.getHeaderNames();
432: set.clear();
433: while (li.hasNext()) {
434: String hdrName = (String) li.next();
435: set.add(hdrName);
436: }
437:
438: //
439: // JvB: Headers may use short names too
440: //
441: assertTrue(set.contains(CSeqHeader.NAME));
442: assertTrue(set.contains(FromHeader.NAME)
443: || set.contains("f"));
444: assertTrue(set.contains(ToHeader.NAME) || set.contains("t"));
445: assertTrue(set.contains(ViaHeader.NAME)
446: || set.contains("v"));
447: assertTrue(set.contains(MaxForwardsHeader.NAME));
448: assertTrue(set.contains(ContentTypeHeader.NAME)
449: || set.contains("c"));
450: assertTrue(set.contains(CallIdHeader.NAME)
451: || set.contains("i"));
452:
453: } catch (Exception ex) {
454: ex.printStackTrace();
455: fail(ex.getMessage());
456: } finally {
457: logTestCompleted("testGetHeaderNames()");
458: }
459:
460: }
461:
462: public void testAddRemoveHeader() {
463: try {
464: Request request = tiMessageFactory.createRequest(
465: tiRequestURI, method, ticallId, ticSeq, tifrom,
466: tito, tivia, timaxForwards, ticontentType,
467: contentObject);
468: request.addHeader(tiextensionHeader);
469: ListIterator viaHeaders = request
470: .getHeaders(ViaHeader.NAME);
471: ViaHeader viaHeader = (ViaHeader) viaHeaders.next();
472: assertTrue(viaHeader.equals(tivia.iterator().next()));
473: Header header = request.getHeader("My-Header");
474: assertTrue(header != null
475: && header.equals(tiextensionHeader));
476: request.removeHeader("My-Header");
477: assertNull(request.getHeader("My-Header"));
478: Response response = tiMessageFactory.createResponse(
479: statusCode, ticallId, ticSeq, tifrom, tito, tivia,
480: timaxForwards, ticontentType, contentObject);
481: response.addHeader(tiextensionHeader);
482: viaHeaders = request.getHeaders(ViaHeader.NAME);
483: viaHeader = (ViaHeader) viaHeaders.next();
484: assertEquals(viaHeader, tivia.iterator().next());
485: header = response.getHeader("My-Header");
486: assertEquals(header, tiextensionHeader);
487: response.removeHeader("My-Header");
488: assertNull(response.getHeader("My-Header"));
489: ContentLengthHeader cl = response.getContentLength();
490: assertNotNull(cl);
491: } catch (Exception ex) {
492: ex.printStackTrace();
493: fail(ex.getMessage());
494: } finally {
495: logTestCompleted("testAddRemoveHeader()");
496: }
497: }
498:
499: public void setUp() {
500: try {
501: String fromName = "BigGuy";
502: String fromSipAddress = "here.com";
503: String fromDisplayName = "The Master Blaster";
504:
505: String toSipAddress = "there.com";
506: String toUser = "LittleGuy";
507: String toDisplayName = "The Little Blister";
508:
509: // create >From Header
510: SipURI tifromAddress = tiAddressFactory.createSipURI(
511: fromName, fromSipAddress);
512: SipURI rifromAddress = riAddressFactory.createSipURI(
513: fromName, fromSipAddress);
514:
515: Address tifromNameAddress = tiAddressFactory
516: .createAddress(tifromAddress);
517: Address rifromNameAddress = riAddressFactory
518: .createAddress(rifromAddress);
519:
520: tifromNameAddress.setDisplayName(fromDisplayName);
521: rifromNameAddress.setDisplayName(fromDisplayName);
522:
523: tifrom = tiHeaderFactory.createFromHeader(
524: tifromNameAddress, "12345");
525: rifrom = riHeaderFactory.createFromHeader(
526: rifromNameAddress, "12345");
527:
528: // create To Header
529: SipURI titoAddress = tiAddressFactory.createSipURI(toUser,
530: toSipAddress);
531: SipURI ritoAddress = riAddressFactory.createSipURI(toUser,
532: toSipAddress);
533:
534: Address titoNameAddress = tiAddressFactory
535: .createAddress(titoAddress);
536: Address ritoNameAddress = riAddressFactory
537: .createAddress(ritoAddress);
538:
539: titoNameAddress.setDisplayName(toDisplayName);
540: ritoNameAddress.setDisplayName(toDisplayName);
541:
542: tito = tiHeaderFactory
543: .createToHeader(titoNameAddress, null);
544: rito = riHeaderFactory
545: .createToHeader(ritoNameAddress, null);
546:
547: // create Request URIs
548: tiRequestURI = tiAddressFactory.createSipURI(toUser,
549: toSipAddress);
550: riRequestURI = riAddressFactory.createSipURI(toUser,
551: toSipAddress);
552:
553: timaxForwards = tiHeaderFactory.createMaxForwardsHeader(70);
554: rimaxForwards = riHeaderFactory.createMaxForwardsHeader(70);
555:
556: ticontentType = tiHeaderFactory.createContentTypeHeader(
557: "application", "sdp");
558: ricontentType = riHeaderFactory.createContentTypeHeader(
559: "application", "sdp");
560:
561: tivia = new LinkedList();
562: rivia = new LinkedList();
563:
564: ViaHeader tiviaHeader = tiHeaderFactory.createViaHeader(
565: "127.0.0.1", 5060, "udp", null);
566: tivia.add(tiviaHeader);
567:
568: ViaHeader riviaHeader = riHeaderFactory.createViaHeader(
569: "127.0.0.1", 5060, "udp", null);
570: rivia.add(riviaHeader);
571:
572: ticallId = tiHeaderFactory
573: .createCallIdHeader("12345@127.0.0.1");
574: ricallId = riHeaderFactory
575: .createCallIdHeader("12345@127.0.0.1");
576:
577: contentObject = "v=0\r\n"
578: + "o=4855 13760799956958020 13760799956958020"
579: + " IN IP4 129.6.55.78\r\n"
580: + "s=mysession session\r\n"
581: + "p=+46 8 52018010\r\n"
582: + "c=IN IP4 129.6.55.78\r\n" + "t=0 0\r\n"
583: + "m=audio 6022 RTP/AVP 0 4 18\r\n"
584: + "a=rtpmap:0 PCMU/8000\r\n"
585: + "a=rtpmap:4 G723/8000\r\n"
586: + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n";
587: contentBytes = ((String) contentObject).getBytes();
588:
589: method = Request.INVITE;
590:
591: ticSeq = tiHeaderFactory.createCSeqHeader(1L, method);
592: ricSeq = riHeaderFactory.createCSeqHeader(1L, method);
593:
594: statusCode = 200;
595:
596: tiextensionHeader = (ExtensionHeader) tiHeaderFactory
597: .createHeader("My-Header", "My Header Value");
598:
599: riextensionHeader = (ExtensionHeader) riHeaderFactory
600: .createHeader("My-Header", "My Header Value");
601:
602: } catch (Throwable ex) {
603: ex.printStackTrace();
604: fail(ex.getMessage());
605: } // finally { assertTrue(true); }
606:
607: }
608:
609: public void tearDown() {
610: riFactory.resetFactory();
611: tiFactory.resetFactory();
612: }
613:
614: public static Test suite() {
615: return new TestSuite(MessageFactoryTest.class);
616: }
617:
618: public static void main(String[] args) {
619: junit.textui.TestRunner.run(MessageFactoryTest.class);
620: }
621:
622: }
|