1 64 65 70 71 package com.jcorporate.expresso.ext.controller; 72 73 import com.jcorporate.expresso.core.controller.ControllerException; 74 import com.jcorporate.expresso.core.controller.ControllerRequest; 75 import com.jcorporate.expresso.core.controller.ControllerResponse; 76 import com.jcorporate.expresso.core.controller.DBController; 77 import com.jcorporate.expresso.core.controller.Input; 78 import com.jcorporate.expresso.core.controller.NonHandleableException; 79 import com.jcorporate.expresso.core.controller.Output; 80 import com.jcorporate.expresso.core.controller.State; 81 import com.jcorporate.expresso.core.controller.Transition; 82 import com.jcorporate.expresso.core.db.DBException; 83 import com.jcorporate.expresso.core.dbobj.Schema; 84 import com.jcorporate.expresso.core.dbobj.SecuredDBObject; 85 import com.jcorporate.expresso.core.dbobj.ValidValue; 86 import com.jcorporate.expresso.core.misc.ConfigManager; 87 import com.jcorporate.expresso.services.controller.Registration; 88 import com.jcorporate.expresso.services.dbobj.SchemaList; 89 import junit.framework.AssertionFailedError; 90 import junit.framework.Test; 91 import junit.framework.TestFailure; 92 import junit.framework.TestListener; 93 import junit.framework.TestResult; 94 import junit.framework.TestSuite; 95 import junit.runner.ReloadingTestSuiteLoader; 96 import junit.runner.StandardTestSuiteLoader; 97 import junit.runner.TestSuiteLoader; 98 import org.apache.log4j.Logger; 99 100 import java.io.File ; 101 import java.io.FileInputStream ; 102 import java.io.IOException ; 103 import java.io.InputStream ; 104 import java.lang.reflect.Method ; 105 import java.text.NumberFormat ; 106 import java.util.Enumeration ; 107 import java.util.Iterator ; 108 import java.util.Properties ; 109 import java.util.Vector ; 110 111 112 122 public class TestController 123 extends DBController 124 implements TestListener { 125 static final String SUITE_METHODNAME = "suite"; 126 static Properties fPreferences; 127 static int fMaxMessage = 200; 128 protected TestSuiteLoader fTestLoader; 129 private static Logger log = Logger.getLogger(TestController.class); 130 131 134 public TestController() { 135 super(); 136 System.setProperty("junit.argv.configDir", 137 ConfigManager.getConfigDir()); 138 System.setProperty("junit.argv.webAppDir", 139 ConfigManager.getWebAppDir()); 140 fTestLoader = new StandardTestSuiteLoader(); 141 142 State prompt = new State("prompt", "Prompt for Test to Run"); 143 addState(prompt); 144 setInitialState("prompt"); 145 146 State runTests = new State("runTests", "Run Tests"); 147 runTests.addRequiredParameter("testName"); 148 addState(runTests); 149 150 State runAllTests = new State("runAllTests", "Run All Tests"); 151 runAllTests.addRequiredParameter("SchemaClass"); 152 addState(runAllTests); 153 154 addState(new State("transition2FormTest", "test a transition to a state which requires a form")); 155 addState(new State("transitionTest", "test a transition")); 156 addState(new State("promptTest", "prompt for transitionFromFormTest")); 157 addState(new State("transitionFromFormTest", "test a transition from a form")); 158 this.setSchema(com.jcorporate.expresso.core.ExpressoSchema.class); 159 } 160 161 167 public ControllerResponse newState(String newState, 168 ControllerRequest params) 169 throws ControllerException, 170 NonHandleableException { 171 ControllerResponse myResponse = super.newState(newState, params); 172 173 if (newState.equals("runTests")) { 174 runTestsState(myResponse, params); 175 } else if (newState.equals("runAllTests")) { 176 runAllTestsState(myResponse, params); 177 } else if (newState.equals("prompt")) { 178 promptState(myResponse, params); 179 } 180 181 return myResponse; 182 } 183 184 185 189 public synchronized void addError(Test test, Throwable t) { 190 log.info("A test error has occurred"); 191 log.error(t); 192 } 193 194 198 public synchronized void addFailure(Test test, Throwable t) { 199 log.info("A test failure has occurred"); 200 log.error(t); 201 } 202 203 208 protected TestResult createTestResult() { 209 return new TestResult(); 210 } 211 212 217 protected synchronized TestResult doRun(Test suite, boolean wait) { 218 try { 219 TestResult result = createTestResult(); 220 result.addListener(this); 221 222 long startTime = System.currentTimeMillis(); 223 suite.run(result); 224 225 long endTime = System.currentTimeMillis(); 226 long runTime = endTime - startTime; 227 log.info("Time: " + elapsedTimeAsString(runTime)); 228 print(result); 229 230 return result; 231 } catch (Exception ee) { 232 log.error(ee); 233 } 234 235 return null; 236 } 237 238 241 public void endTest(Test test) { 242 } 243 244 247 public void addFailure(Test test, AssertionFailedError t) { 248 log.info("A test failure has occurred"); 249 log.info(t); 250 } 251 252 255 private synchronized void runTestsState(ControllerResponse myResponse, 256 ControllerRequest params) 257 throws ControllerException { 258 long startTime = System.currentTimeMillis(); 259 TestController aTestRunner = new TestController(); 260 261 try { 262 TestResult r = aTestRunner.start(null); 263 264 if (!r.wasSuccessful()) { 265 myResponse.addOutput(new Output("Tests Successful")); 266 } 267 268 myResponse.addOutput(new Output("One or more tests failed")); 269 } catch (Exception e) { 270 log.error(e); 271 throw new ControllerException(e); 272 } 273 274 long endTime = System.currentTimeMillis(); 275 long runTime = endTime - startTime; 276 myResponse.addOutput(new Output("Total Elapsed Time " + runTime + 277 " milliseconds")); 278 } 279 280 281 284 private synchronized void runAllTestsState(ControllerResponse myResponse, 285 ControllerRequest params) 286 throws ControllerException { 287 Schema s = getSchemaObject(params); 288 myResponse.addOutput(new Output("Running all tests in schema " + s.getClass().getName())); 289 290 long startTime = System.currentTimeMillis(); 291 int testCount = 0; 292 int succeedCount = 0; 293 int failedCount = 0; 294 Test t = null; 295 296 for (Enumeration et2 = s.getTests(); et2.hasMoreElements();) { 297 t = (Test) et2.nextElement(); 298 testCount++; 299 300 TestController aTestRunner = new TestController(); 301 302 try { 303 TestResult r = aTestRunner.start(t.getClass().getName()); 304 305 if (r.wasSuccessful()) { 306 myResponse.addOutput(new Output("Test " + t.getClass().getName() + 307 " Successful")); 308 succeedCount++; 309 } else { 310 myResponse.addOutput(new Output("Test " + t.getClass().getName() + 311 " failed - see the log for details")); 312 failedCount++; 313 } 314 } catch (Exception e) { 315 log.error(e); 316 throw new ControllerException(e); 317 } 318 } 319 320 321 long endTime = System.currentTimeMillis(); 322 long runTime = endTime - startTime; 323 myResponse.addOutput(new Output("All Tests Completed")); 324 myResponse.addOutput(new Output("Total Elapsed Time " + runTime + 325 " milliseconds")); 326 myResponse.addOutput(new Output("" + testCount + " tests run, " + 327 succeedCount + " succeeded, " + 328 failedCount + " failed")); 329 } 330 331 332 338 private Schema getSchemaObject(ControllerRequest params) 339 throws ControllerException { 340 Schema mySchema; 341 String className = params.getParameter("SchemaClass"); 342 343 if (className == null) { 344 throw new ControllerException("No parameter 'SchemaClass'," + 345 " can't read current schema"); 346 } 347 try { 348 mySchema = (Schema) Class.forName(params.getParameter("SchemaClass")).newInstance(); 349 } catch (IllegalAccessException ie) { 350 throw new ControllerException("Illegal Access " + 351 "Exception loading Schema class " + 352 params.getParameter("SchemaClass"), 353 ie); 354 } catch (InstantiationException ie) { 355 throw new ControllerException("Can't instantiate " + 356 "Schema class " + 357 params.getParameter("SchemaClass"), 358 ie); 359 } catch (ClassNotFoundException se) { 360 throw new ControllerException("Can't find a Schema " + 361 "class called " + 362 params.getParameter("SchemaClass"), 363 se); 364 } catch (Exception eo) { 365 log.error(eo); 366 throw new ControllerException("Exception loading " + "Schema " + 367 params.getParameter("SchemaClass") + 368 "- see detailed message in server log", 369 eo); 370 } 371 372 return mySchema; 373 } 374 375 376 381 public synchronized void print(TestResult result) { 382 printHeader(result); 383 printErrors(result); 384 printFailures(result); 385 } 386 387 392 public void printErrors(TestResult result) { 393 if (result.errorCount() != 0) { 394 if (result.errorCount() == 1) { 395 log.info("There was " + result.errorCount() + " error:"); 396 } else { 397 log.info("There were " + result.errorCount() + " errors:"); 398 } 399 400 int i = 1; 401 402 for (Enumeration e = result.errors(); e.hasMoreElements(); i++) { 403 TestFailure failure = (TestFailure) e.nextElement(); 404 log.info(i + ") " + failure.failedTest()); 405 log.info(failure.thrownException()); 406 } 407 } 408 } 409 410 415 public void printFailures(TestResult result) { 416 if (result.failureCount() != 0) { 417 if (result.failureCount() == 1) { 418 log.info("There was " + result.failureCount() + " failure:"); 419 } else { 420 log.info("There were " + result.failureCount() + " failures:"); 421 } 422 423 int i = 1; 424 425 for (Enumeration e = result.failures(); e.hasMoreElements(); i++) { 426 TestFailure failure = (TestFailure) e.nextElement(); 427 log.info(i + ") " + failure.failedTest()); 428 429 Throwable t = failure.thrownException(); 430 431 if (t.getMessage() != null) { 432 log.info(" \"" + truncate(t.getMessage()) + "\""); 433 } else { 434 log.info(failure.thrownException()); 435 } 436 } 437 } 438 } 439 440 445 public void printHeader(TestResult result) { 446 if (result.wasSuccessful()) { 447 log.info("OK"); 448 log.info(" (" + result.runCount() + " tests)"); 449 } else { 450 log.info("FAILURES!!!"); 451 log.info("Test Results:"); 452 log.info("Run: " + result.runCount() + " Failures: " + 453 result.failureCount() + " Errors: " + 454 result.errorCount()); 455 } 456 } 457 458 463 static public void run(Class testClass) { 464 run(new TestSuite(testClass)); 465 } 466 467 479 static public void run(Test suite) { 480 TestController aTestRunner = new TestController(); 481 aTestRunner.doRun(suite, false); 482 } 483 484 491 protected synchronized TestResult start(String testName) 492 throws Exception { 493 boolean wait = false; 494 495 try { 496 Test suite = getTest(testName); 497 498 return doRun(suite, wait); 499 } catch (Exception e) { 500 throw new Exception ("Could not create and run test suite: " + e); 501 } 502 } 503 504 505 508 protected void runFailed(String message) { 509 log.info(message); 510 } 511 512 515 public synchronized void startTest(Test test) { 516 log.info("Test Started"); 517 } 518 519 526 public Test getTest(String suiteClassName) { 527 if (suiteClassName.length() <= 0) { 528 clearStatus(); 529 530 return null; 531 } 532 533 Class testClass = null; 534 535 try { 536 testClass = loadSuiteClass(suiteClassName); 537 } catch (NoClassDefFoundError e) { 538 runFailed("Class definition \"" + suiteClassName + "\" not found"); 539 540 return null; 541 } catch (Exception e) { 542 runFailed("Class \"" + suiteClassName + "\" not found"); 543 544 return null; 545 } 546 547 Method suiteMethod = null; 548 549 try { 550 suiteMethod = testClass.getMethod(SUITE_METHODNAME, new Class [0]); 551 } catch (Exception e) { 552 553 clearStatus(); 555 556 return new TestSuite(testClass); 557 } 558 559 Test test = null; 560 561 try { 562 test = (Test) suiteMethod.invoke(null, (Object []) new Class [0]); 564 if (test == null) { 565 return test; 566 } 567 } catch (Exception e) { 568 runFailed("Could not invoke the suite() method"); 569 570 return null; 571 } 572 573 clearStatus(); 574 575 return test; 576 } 577 578 584 public String elapsedTimeAsString(long runTime) { 585 return NumberFormat.getInstance().format((double) runTime / 1000); 586 } 587 588 592 public String extractClassName(String className) { 593 if (className.startsWith("Default package for")) { 594 return className.substring(className.lastIndexOf(".") + 1); 595 } 596 597 return className; 598 } 599 600 606 public static String truncate(String s) { 607 if (s.length() > fMaxMessage) { 608 s = s.substring(0, fMaxMessage) + "..."; 609 } 610 611 return s; 612 } 613 614 620 protected Class loadSuiteClass(String suiteClassName) 621 throws ClassNotFoundException { 622 return fTestLoader.load(suiteClassName); 623 } 624 625 626 629 protected void clearStatus() { } 631 632 637 public static TestSuiteLoader getLoader() { 638 if (getPreference("loading").equals("true") && !inVAJava()) { 639 return new ReloadingTestSuiteLoader(); 640 } 641 642 return new StandardTestSuiteLoader(); 643 } 644 645 648 private static File getPreferencesFile() { 649 String home = System.getProperty("user.home"); 650 651 return new File (home, "junit.properties"); 652 } 653 654 657 private static void readPreferences() { 658 InputStream is = null; 659 660 try { 661 is = new FileInputStream (getPreferencesFile()); 662 fPreferences = new Properties (fPreferences); 663 fPreferences.load(is); 664 } catch (IOException e) { 665 try { 666 if (is != null) { 667 is.close(); 668 } 669 } catch (IOException e1) { 670 } 671 } 672 } 673 674 678 private static String getPreference(String key) { 679 return fPreferences.getProperty(key); 680 } 681 682 687 private static int getPreference(String key, int dflt) { 688 String value = getPreference(key); 689 int intValue = dflt; 690 691 if (value == null) { 692 return intValue; 693 } 694 try { 695 intValue = Integer.parseInt(value); 696 } catch (NumberFormatException ne) { 697 } 698 699 return intValue; 700 } 701 702 705 public static boolean inVAJava() { 706 try { 707 Class.forName("com.ibm.uvm.tools.DebugSupport"); 708 } catch (Exception e) { 709 return false; 710 } 711 712 return true; 713 } 714 715 { 716 fPreferences = new Properties (); 717 fPreferences.setProperty("loading", "true"); 718 readPreferences(); 719 fMaxMessage = getPreference("maxmessage", fMaxMessage); 720 } 721 722 public String getTitle() { 723 return ("Run Unit Tests"); 724 } 725 726 private void promptState(ControllerResponse myResponse, 727 ControllerRequest params) 728 throws ControllerException { 729 try { 730 Input chooseSchema = new Input(); 731 chooseSchema.setLabel("Choose Schema"); 732 chooseSchema.setName("SchemaClass"); 733 734 Vector v2 = new Vector (2); 735 v2.addElement(new ValidValue("com.jcorporate.expresso." + "core.ExpressoSchema", 736 "General")); 737 738 SchemaList sl = new SchemaList(SecuredDBObject.SYSTEM_ACCOUNT); 739 sl.setDataContext(params.getDataContext()); 740 741 SchemaList oneSchema = null; 742 743 for (Iterator e = sl.searchAndRetrieveList("Descrip").iterator(); 744 e.hasNext();) { 745 oneSchema = (SchemaList) e.next(); 746 v2.addElement(new ValidValue(oneSchema.getField("SchemaClass"), 747 oneSchema.getField("Descrip"))); 748 } 749 750 chooseSchema.setValidValues(v2); 751 myResponse.addInput(chooseSchema); 752 753 754 755 762 Transition runAllTests = new Transition("Run All Tests", 763 getClass().getName()); 764 runAllTests.setName("runAllTests"); 765 runAllTests.addParam(STATE_PARAM_KEY, "runAllTests"); 766 myResponse.addTransition(runAllTests); 767 } catch (DBException de) { 768 throw new ControllerException(de); 769 } 770 } 771 772 773 777 protected void runTransition2FormTestState(ControllerRequest request, 778 ControllerResponse response) 779 throws ControllerException, 780 NonHandleableException { 781 Transition trans = new Transition(); 782 trans.setControllerObject(Registration.class); 783 trans.setState("promptSelfRegister"); 784 trans.addParam("dbContext", "default"); 785 trans.transition(request, response); 786 } 787 788 793 protected void runTransitionTestState(ControllerRequest request, 794 ControllerResponse response) 795 throws ControllerException, 796 NonHandleableException { 797 Transition trans = new Transition(); 798 trans.setControllerObject(Download.class); 799 trans.setState("list"); 800 trans.transition(request, response); 801 } 802 803 807 protected void runPromptTestState(ControllerRequest request, 808 ControllerResponse response) 809 throws ControllerException, 810 NonHandleableException { 811 Input input = new Input("demoprompt", "demoprompt"); 812 response.addInput(input); 814 Transition trans = new Transition("transitionFromFormTest", this); 815 response.addTransition(trans); 816 } 817 818 819 823 protected void runTransitionFromFormTestState(ControllerRequest request, 824 ControllerResponse response) 825 throws ControllerException, 826 NonHandleableException { 827 Transition trans = new Transition(); 828 trans.setControllerObject(Download.class); 829 trans.setState("list"); 830 trans.transition(request, response); 831 } 832 833 } 834 | Popular Tags |