1 17 18 package org.apache.james.test; 19 20 import junit.framework.TestCase; 21 22 import java.io.*; 23 import java.util.*; 24 import java.net.Socket ; 25 26 35 public abstract class AbstractProtocolTest extends TestCase 36 { 37 private Socket _socket; 38 private PrintWriter _out; 39 private BufferedReader _in; 40 protected String _host = "127.0.0.1"; 41 42 protected int _port; 43 protected int _timeout = 0; 44 45 protected List _preElements = new ArrayList(); 46 protected List _testElements = new ArrayList(); 47 protected List _postElements = new ArrayList(); 48 49 public AbstractProtocolTest( String s ) 50 { 51 super( s ); 52 } 53 54 public void setUp() throws Exception 56 { 57 super.setUp(); 58 _testElements.clear(); 59 60 _socket = new Socket ( _host, _port ); 61 _socket.setSoTimeout( _timeout ); 62 _out = new PrintWriter( _socket.getOutputStream(), true ); 63 _in = new BufferedReader( new InputStreamReader( _socket.getInputStream() ) ); 64 } 65 66 protected void tearDown() throws Exception 68 { 69 _out.close(); 70 _in.close(); 71 _socket.close(); 72 super.tearDown(); 73 } 74 75 protected void executeTests() throws Exception 77 { 78 executeTest( _preElements ); 79 executeTest( _testElements ); 80 executeTest( _postElements ); 81 } 82 83 90 protected void executeTest( List protocolLines ) throws Exception 91 { 92 for ( Iterator iter = protocolLines.iterator(); iter.hasNext(); ) { 93 Object obj = iter.next(); 94 if ( obj instanceof ProtocolLine ) { 95 ProtocolLine test = (ProtocolLine) obj; 96 test.testProtocol( _out, _in ); 97 } else if ( obj instanceof List ) { 98 List testlist = (List) obj; 100 for (int k = 0; k < testlist.size(); k++) { 101 ProtocolLine test = (ProtocolLine) testlist.get(k); 102 test.testProtocolBlock( _out, _in, testlist); 103 } 104 } 105 } 106 } 107 108 111 protected void CL( String clientLine ) 112 { 113 _testElements.add( new ClientRequest( clientLine ) ); 114 } 115 116 119 protected void SL( String serverLine ) 120 { 121 _testElements.add( new ServerResponse( serverLine ) ); 122 } 123 124 128 protected class ClientRequest implements ProtocolLine 129 { 130 private String _msg; 131 132 public ClientRequest( String msg ) 133 { 134 _msg = msg; 135 } 136 137 140 public void testProtocol( PrintWriter out, BufferedReader in ) throws Exception 141 { 142 out.println( _msg ); 143 } 144 145 149 public void testProtocolBlock( PrintWriter out, BufferedReader in, List list) 150 throws Exception { 151 throw new RuntimeException ("Syntax error in test case, CL is not "+ 153 "able to be used in a SUB: block"); 154 } 155 } 156 157 161 protected class ServerResponse implements ProtocolLine 162 { 163 private String _msg; 164 private List _elementTests; 165 private boolean _ignoreExtraCharacters = false; 166 private String _location; 167 168 175 public ServerResponse( String msg, 176 String location, 177 boolean ignoreExtraCharacters) 178 { 179 _msg = msg; 180 _elementTests = buildElementTests( getMessageTokens( _msg ) ); 181 if ( ! ignoreExtraCharacters ) { 182 _elementTests.add( new EndOfLineTest() ); 183 } 184 185 _location = location; 186 } 187 188 195 public ServerResponse( String msg, 196 String location ) 197 { 198 this( msg, location, false ); 199 } 200 201 207 public ServerResponse( String msg, boolean ignoreExtraCharacters ) 208 { 209 this( msg, null, ignoreExtraCharacters ); 210 } 211 212 217 public ServerResponse( String msg ) 218 { 219 this( msg, null, false ); 220 } 221 222 231 public void testProtocolBlock( PrintWriter out, BufferedReader in, 232 List testslist) throws Exception { 233 String testLine = readLine( in ); 235 if ( _ignoreExtraCharacters 236 && ( testLine.length() > _msg.length() ) ) { 237 testLine = testLine.substring( 0, _msg.length() ); 238 } 239 240 ListIterator testTokens = getMessageTokens( testLine ).listIterator(); 241 Iterator theblock = testslist.iterator(); 242 boolean assertval = false; 243 while (theblock.hasNext()) { 244 assertval = testProtocolInBlock( out, in, testTokens, testLine); 245 if (assertval = true) { 246 break; 247 } 248 } 249 if (assertval == false) { 250 System.err.println("returning failure in block"); 251 } 252 assertTrue("Someting in block matched (false)", assertval); 253 254 } 255 256 265 public boolean testProtocolInBlock( PrintWriter out, BufferedReader in, ListIterator testTokens, String testLine) throws Exception 266 { 267 boolean retval = false; 268 Iterator tests = _elementTests.iterator(); 269 while ( tests.hasNext() ) { 270 ElementTest test = (ElementTest)tests.next(); 271 if ( _location != null ) { 272 test.setLocation( _location ); 273 } 274 retval = test.softTest( testTokens, testLine ); 276 if (retval == false) { 277 break; 278 } 279 } 280 return retval; 281 } 282 283 289 public void testProtocol( PrintWriter out, BufferedReader in ) throws Exception 290 { 291 String testLine = readLine( in ); 292 if ( _ignoreExtraCharacters 293 && ( testLine.length() > _msg.length() ) ) { 294 testLine = testLine.substring( 0, _msg.length() ); 295 } 296 297 ListIterator testTokens = getMessageTokens( testLine ).listIterator(); 298 Iterator tests = _elementTests.iterator(); 299 while ( tests.hasNext() ) { 300 ElementTest test = (ElementTest)tests.next(); 301 if ( _location != null ) { 302 test.setLocation( _location ); 303 } 304 test.test( testTokens, testLine ); 305 } 306 } 307 308 314 private String readLine( BufferedReader in ) throws Exception 315 { 316 try { 317 return in.readLine(); 318 } 319 catch ( InterruptedIOException e ) { 320 String errMsg = "\nLocation: " + _location + 321 "\nExpected: " + _msg + 322 "\nReason: Server Timeout."; 323 fail( errMsg ); 324 return ""; 325 } 326 } 327 328 private List getMessageTokens( String message ) 329 { 330 List tokenList = new ArrayList(); 331 StringTokenizer tokens = new StringTokenizer( message, " \t\n\r\f\"\'{}()[];$", true ); 332 while ( tokens.hasMoreTokens() ) { 333 tokenList.add( tokens.nextToken() ); 334 } 335 return tokenList; 336 } 337 338 private List buildElementTests( List tokenList ) 339 { 340 List elementTests = new ArrayList(); 341 for ( int i = 0; i < tokenList.size(); i++ ) { 342 if ( ( i < ( tokenList.size() - 3 ) ) 343 && tokenList.get( i ).equals( "$" ) 344 && tokenList.get( i+1 ).equals( "{" ) 345 && tokenList.get( i+3 ).equals( "}" ) ) { 346 String special = (String ) tokenList.get( i+2 ); 348 elementTests.add( buildSpecialTest( special ) ); 349 i += 3; 350 } 351 else { 352 elementTests.add( new StringElementTest( (String )tokenList.get( i ) ) ); 353 } 354 } 355 return elementTests; 356 } 357 358 361 private abstract class ElementTest 362 { 363 protected String _description; 364 365 void setLocation( String location ) { 366 _description = "\nLocation: " + location; 367 } 368 369 void test( ListIterator testElements, String fullTestLine ) throws Exception 370 { 371 _description += "\nActual : " + fullTestLine + 372 "\nExpected: " + _msg + 373 "\nReason: "; 374 doTest( testElements ); 375 } 376 377 void test( ListIterator testElements ) throws Exception 378 { 379 _description += "Reason: "; 380 doTest( testElements ); 381 } 382 383 boolean softTest( ListIterator testElements, String line) throws Exception { 384 return doNonAssertingTest(testElements); 385 } 386 387 abstract void doTest( ListIterator testElements ) throws Exception ; 388 389 395 abstract boolean doNonAssertingTest( ListIterator testElements) 396 throws Exception ; 397 } 398 399 402 403 406 private class StringElementTest extends ElementTest 407 { 408 private String _elementValue; 409 410 public StringElementTest( String elementValue ) 411 { 412 _elementValue = elementValue; 413 } 414 415 public boolean doNonAssertingTest( ListIterator testElements ) 417 throws Exception { 418 String next; 419 if ( testElements.hasNext() ) { 420 next = (String ) testElements.next(); 421 } 422 else { 423 next = "No more elements"; 424 } 425 if ( !_elementValue.equals(next) ) { 426 return false; 430 } 431 return true; 435 } 436 437 public void doTest( ListIterator testElements ) throws Exception 438 { 439 String next; 440 if ( testElements.hasNext() ) { 441 next = (String ) testElements.next(); 442 } 443 else { 444 next = "No more elements"; 445 } 446 assertEquals( _description, _elementValue, next ); 447 } 448 } 449 450 private ElementTest buildSpecialTest( String testName ) 451 { 452 if ( testName.startsWith("ignore") ) { 453 return new ConsumeElementTest( testName ); 454 } 455 if ( testName.startsWith("rfcDate") ) { 456 return new RfcDateElementTest( testName ); 457 } 458 else { 459 return new StringElementTest( "${" + testName + "}" ); 460 } 461 } 462 463 464 468 private class ConsumeElementTest extends ElementTest 469 { 470 private int _elementsToConsume; 471 ConsumeElementTest( String token ) 472 { 473 if ( token.equals("ignore") ) { 474 _elementsToConsume = 1; 475 } 476 else if ( token.startsWith( "ignore-") ) { 477 _elementsToConsume = Integer.parseInt( token.substring( "ignore-".length() ) ); 478 } 479 else { 480 _elementsToConsume = Integer.parseInt( token ); 481 } 482 } 483 484 ConsumeElementTest(int number) 485 { 486 _elementsToConsume = number; 487 } 488 489 public void doTest( ListIterator testElements ) throws Exception 490 { 491 for ( int i = 0; i < _elementsToConsume; i++ ) 492 { 493 if ( ! testElements.hasNext() ) { 494 fail( _description + "Not enough elements to ignore." ); 495 } 496 String ignored = (String )testElements.next(); 497 } 498 } 499 public boolean doNonAssertingTest( ListIterator testElements ) throws Exception 500 { 501 for ( int i = 0; i < _elementsToConsume; i++ ) 502 { 503 if ( ! testElements.hasNext() ) { 504 return false; 505 } 506 String ignored = (String )testElements.next(); 507 } 508 return true; 509 } 510 } 511 512 515 private class RfcDateElementTest extends ConsumeElementTest 516 { 517 public RfcDateElementTest( String token ) 518 { 519 super( 11 ); 520 } 521 } 522 523 526 private class EndOfLineTest extends ElementTest 527 { 528 public void doTest( ListIterator testElements ) throws Exception 529 { 530 if ( testElements.hasNext() ) { 531 String nextElement = (String )testElements.next(); 532 fail( _description + "End of line expected, found '" + nextElement + "'" ); 533 } 534 } 535 536 public boolean doNonAssertingTest( ListIterator testElements ) 537 throws Exception 538 { 539 if ( testElements.hasNext() ) { 540 String nextElement = (String )testElements.next(); 541 return false; 542 } 543 return true; 544 } 545 } 546 } 547 548 protected interface ProtocolLine 549 { 550 void testProtocol( PrintWriter out, BufferedReader in ) throws Exception ; 551 void testProtocolBlock(PrintWriter out, BufferedReader in, List list) 552 throws Exception ; 553 } 554 555 protected void addTestFile( String fileName ) throws Exception 556 { 557 addTestFile( fileName, _testElements ); 558 } 559 560 protected void addTestFile( String fileName, List protocolLines ) throws Exception 561 { 562 InputStream is = this.getClass().getResourceAsStream( fileName ); 564 if ( is == null ) { 565 throw new Exception ("Test Resource '" + fileName + "' not found." ); 566 } 567 568 addProtocolLinesFromStream( is, protocolLines, fileName ); 569 } 570 571 private void addProtocolLinesFromStream( InputStream is, List protocolLines, String fileName ) throws Exception 572 { 573 BufferedReader reader = new BufferedReader( new InputStreamReader( is ) ); 574 String next; 575 int lineNumber = 1; 576 while ( ( next = reader.readLine() ) != null ) { 577 String location = fileName + ":" + lineNumber; 578 if ( next.startsWith( "C: " ) ) { 579 String clientMsg = next.substring( 3 ); 580 protocolLines.add( new ClientRequest( clientMsg ) ); 581 } 582 else if ( next.startsWith( "S: " ) ) { 583 String serverMsg = next.substring( 3 ); 584 if ( serverMsg.endsWith("//") ) { 585 serverMsg = serverMsg.substring( 0, serverMsg.length() - 2 ); 586 protocolLines.add( new ServerResponse( serverMsg, location, true ) ); 587 } 588 else { 589 protocolLines.add( new ServerResponse( serverMsg, location, false ) ); 590 } 591 592 } else if ( next.startsWith("SUB: ") ) { 593 List unorderedBlock = new ArrayList(5); 595 next = reader.readLine(); 596 String serverMsg = next.substring( 3 ); 598 while ( !next.startsWith("SUB:") ) { 599 unorderedBlock.add( 600 new ServerResponse( serverMsg, location, false ) 601 ); 602 next = reader.readLine(); 603 serverMsg = next.substring( 3 ); 604 lineNumber++; 605 } 607 protocolLines.add(unorderedBlock); 608 } else if ( next.startsWith( "//" ) 609 || next.trim().length() == 0 ) { 610 } 612 else { 613 String prefix = next; 614 if ( next.length() > 3 ) { 615 prefix = next.substring( 0, 3 ); 616 } 617 throw new Exception ( "Invalid line prefix: " + prefix ); 618 } 619 lineNumber++; 620 } 621 622 } 623 } 624 | Popular Tags |