2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package gov.nasa.jpf.util.test;
20 import gov.nasa.jpf.Config;
21 import gov.nasa.jpf.Error;
22 import gov.nasa.jpf.JPF;
23 import gov.nasa.jpf.JPFShell;
24 import gov.nasa.jpf.Property;
25 import gov.nasa.jpf.annotation.FilterField;
26 import gov.nasa.jpf.tool.RunTest;
27 import gov.nasa.jpf.util.DevNullPrintStream;
28 import gov.nasa.jpf.util.TypeRef;
29 import gov.nasa.jpf.util.JPFSiteUtils;
30 import gov.nasa.jpf.util.Reflection;
31 import gov.nasa.jpf.vm.ExceptionInfo;
32 import gov.nasa.jpf.vm.NoUncaughtExceptionsProperty;
33 import gov.nasa.jpf.vm.NotDeadlockedProperty;
35 import java.io.PrintStream;
36 import java.io.PrintWriter;
37 import java.lang.annotation.Annotation;
38 import java.lang.reflect.InvocationTargetException;
39 import java.lang.reflect.Method;
40 import java.lang.reflect.Modifier;
41 import java.util.ArrayList;
42 import java.util.List;
45 * base class for JPF unit tests. TestJPF mostly includes JPF invocations
46 * that check for occurrence or absence of certain execution results
48 * This class can be used in two modes:
51 * <li> wrapping a number of related tests for different SuTs into one class
52 * (suite) that calls the various JPF runners with complete argument lists
53 * (as in JPF.main(String[]args)) </li>
55 * <li> derive a class from TestJPF that uses the "..This" methods, which in
56 * turn use reflection to automatically append the test class and method to the
57 * JPF.main argument list (based on the calling class / method names). Note that
58 * you have to obey naming conventions for this to work:
60 * <li> the SuT class has to be the same as the test class without "Test", e.g.
61 * "CastTest" -> "Cast" </li>
63 * <li> the SuT method has to have the same name as the @Test method that
64 * invokes JPF, e.g. "CastTest {.. @Test void testArrayCast() ..}" ->
65 * "Cast {.. void testArrayCast()..} </li>
68 public abstract class TestJPF implements JPFShell {
69 static PrintStream out = System.out;
71 public static final String UNNAMED_PACKAGE = "";
72 public static final String SAME_PACKAGE = null;
74 //--- those are only used outside of JPF execution
75 @FilterField protected static boolean globalRunDirectly, globalShowConfig;
77 @FilterField protected static boolean runDirectly; // don't run test methods through JPF, invoke it directly
78 @FilterField protected static boolean stopOnFailure; // stop as soon as we encounter a failed test or error
79 @FilterField protected static boolean showConfig; // for debugging purposes
80 @FilterField protected static boolean showConfigSources; // for debugging purposes
81 @FilterField protected static boolean hideSummary;
83 @FilterField protected static boolean quiet; // don't show test output
85 @FilterField protected String sutClassName;
87 static class GlobalArg {
91 GlobalArg (String k, String v){
97 // it seems wrong to pull globalArgs here instead of setting it from
98 // RunTest, but RunTest has to make sure TestJPF is loaded through the
99 // JPFClassLoader, i.e. cannot directly reference this class.
101 @FilterField static ArrayList<GlobalArg> globalArgs;
103 protected static ArrayList<GlobalArg> getGlobalArgs() {
104 // NOTE - this is only set if we execute tests from build.xml
105 Config globalConf = RunTest.getConfig();
106 if (globalConf != null){
107 ArrayList<GlobalArg> list = new ArrayList<GlobalArg>();
109 //--- the "test.<key>" specs
110 String[] testKeys = globalConf.getKeysStartingWith("test.");
111 if (testKeys.length > 0){
112 for (String key : testKeys){
113 String val = globalConf.getString(key);
114 // <2do> this is a hack to avoid the problem of not being able to store
115 // empty/nil/null values in the global config (they are removed during global config init)
116 if (val.equals("REMOVE")){
120 key = key.substring(5);
122 list.add(new GlobalArg(key,val));
134 globalArgs = getGlobalArgs();
138 //--- internal methods
140 public static void fail (String msg, String[] args, String cause){
141 StringBuilder sb = new StringBuilder();
145 for (String s : args){
159 public static void fail (){
160 throw new AssertionError();
163 public static void fail (String msg){
164 throw new AssertionError(msg);
167 public void report (String[] args) {
169 out.print(" running jpf with args:");
171 for (int i = 0; i < args.length; i++) {
181 * compute the SuT class name for a given JUnit test class: remove
182 * optionally ending "..Test", and replace package (if specified)
184 * @param testClassName the JUnit test class
185 * @param sutPackage optional SuT package name (without ending '.', null
186 * os SAME_PACKAGE means same package, "" or UNNAMED_PACKAGE means unnamed package)
187 * @return main class name of system under test
189 protected static String getSutClassName (String testClassName, String sutPackage){
191 String sutClassName = testClassName;
193 int i = sutClassName.lastIndexOf('.');
194 if (i >= 0){ // testclass has a package
196 if (sutPackage == null){ // use same package
198 } else if (sutPackage.length() > 0) { // explicit sut package
199 sutClassName = sutPackage + sutClassName.substring(i);
201 } else { // unnamed sut package
202 sutClassName = sutClassName.substring(i+1);
205 } else { // test class has no package
206 if (sutPackage == null || sutPackage.length() == 0){ // use same package
208 } else { // explicit sut package
209 sutClassName = sutPackage + '.' + sutClassName;
213 if (sutClassName.endsWith("JPF")) {
214 sutClassName = sutClassName.substring(0, sutClassName.length() - 3);
220 // we can't set the sutClassName only from main() called methods (like
221 // runTestsOfThisClass()) since main() doesn't get called if this is executed
222 // by Ant (via <junit> task)
223 // the default ctor is always executed
225 sutClassName = getSutClassName(getClass().getName(), SAME_PACKAGE);
230 //------ the API to be used by subclasses
233 * to be used from default ctor of derived class if the SuT is in a different
235 * @param sutClassName the qualified SuT class name to be checked by JPF
237 protected TestJPF (String sutClassName){
238 this.sutClassName = sutClassName;
241 public static boolean isJPFRun () {
245 public static boolean isJUnitRun() {
246 // intercepted by native peer if this runs under JPF
247 Throwable t = new Throwable();
248 t.fillInStackTrace();
250 for (StackTraceElement se : t.getStackTrace()){
251 if (se.getClassName().startsWith("org.junit.")){
259 public static boolean isRunTestRun() {
260 // intercepted by native peer if this runs under JPF
261 Throwable t = new Throwable();
262 t.fillInStackTrace();
264 for (StackTraceElement se : t.getStackTrace()){
265 if (se.getClassName().equals("gov.nasa.jpf.tool.RunTest")){
274 protected static void getOptions (String[] args){
275 runDirectly = globalRunDirectly;
276 showConfig = globalShowConfig;
278 // hideSummary and stopOnFailure only make sense as global options anyways
281 for (int i=0; i<args.length; i++){
285 if (a.charAt(0) == '-'){
290 } else if (a.equals("s") || a.equals("show")){
292 } else if (a.equals("l") || a.equals("log")){
293 showConfigSources = true;
294 } else if (a.equals("q") || a.equals("quiet")){
296 } else if (a.equals("x")){
297 stopOnFailure = true;
298 } else if (a.equals("h")){
301 args[i] = null; // set it consumed
304 break; // done, this is a test method
312 protected static boolean hasExplicitTestMethods(String[] args){
313 for (String a : args){
322 protected static List<Method> getMatchingMethods(Class<? extends TestJPF> testCls,
323 int setModifiers, int unsetModifiers, String[] annotationNames){
324 List<Method> list = new ArrayList<Method>();
326 for (Method m : testCls.getMethods()){
327 if (isMatchingMethod(m, setModifiers, unsetModifiers, annotationNames)){
335 protected static boolean isMatchingMethod(Method m, int setModifiers, int unsetModifiers, String[] annotationNames) {
336 int mod = m.getModifiers();
337 if (((mod & setModifiers) != 0) && ((mod & unsetModifiers) == 0)) {
338 if (m.getParameterTypes().length == 0) {
339 if (annotationNames != null){
340 Annotation[] annotations = m.getAnnotations();
341 for (int i = 0; i < annotations.length; i++) {
342 String annotType = annotations[i].annotationType().getName();
343 for (int j = 0; j < annotationNames.length; j++) {
344 if (annotType.equals(annotationNames[j])) {
358 protected static List<Method> getContextMethods(Class<? extends TestJPF> testCls,
359 int setModifiers, int unsetModifiers, String annotation){
360 String[] annotations = {annotation};
362 List<Method> list = new ArrayList<Method>();
363 for (Method m : testCls.getMethods()){
364 if (isMatchingMethod(m, setModifiers, unsetModifiers, annotations)){
371 protected static List<Method> getBeforeMethods(Class<? extends TestJPF> testCls){
372 return getContextMethods(testCls, Modifier.PUBLIC, Modifier.STATIC, "org.junit.Before");
375 protected static List<Method> getAfterMethods(Class<? extends TestJPF> testCls){
376 return getContextMethods(testCls, Modifier.PUBLIC, Modifier.STATIC, "org.junit.After");
379 protected static List<Method> getBeforeClassMethods(Class<? extends TestJPF> testCls){
380 return getContextMethods(testCls, Modifier.PUBLIC | Modifier.STATIC, 0, "org.junit.BeforeClass");
383 protected static List<Method> getAfterClassMethods(Class<? extends TestJPF> testCls){
384 return getContextMethods(testCls, Modifier.PUBLIC | Modifier.STATIC, 0, "org.junit.AfterClass");
387 protected static boolean haveTestMethodSpecs( String[] args){
388 if (args != null && args.length > 0){
389 for (int i=0; i<args.length; i++){
390 if (args[i] != null){
399 protected static List<Method> getTestMethods(Class<? extends TestJPF> testCls, String[] args){
400 String[] testAnnotations = {"org.junit.Test", "org.testng.annotations.Test"};
402 if (haveTestMethodSpecs( args)){ // test methods specified as arguments
403 List<Method> list = new ArrayList<Method>();
405 for (String test : args){
409 Method m = testCls.getMethod(test);
411 if (isMatchingMethod(m, Modifier.PUBLIC, Modifier.STATIC, null /*testAnnotations*/ )){
414 throw new RuntimeException("test method must be @Test annotated public instance method without arguments: " + test);
417 } catch (NoSuchMethodException x) {
418 throw new RuntimeException("method: " + test
419 + "() not in test class: " + testCls.getName(), x);
426 } else { // no explicit test method specification, get all matches
427 return getMatchingMethods(testCls, Modifier.PUBLIC, Modifier.STATIC, testAnnotations);
432 protected static void reportTestStart(String mthName){
434 System.out.println();
435 System.out.print("......................................... testing ");
436 System.out.print(mthName);
437 System.out.println("()");
441 protected static void reportTestInitialization(String mthName){
443 System.out.print(".... running test initialization: ");
444 System.out.print(mthName);
445 System.out.println("()");
449 protected static void reportTestCleanup(String mthName){
451 System.out.print(".... running test cleanup: ");
452 System.out.print(mthName);
453 System.out.println("()");
457 protected static void reportTestFinished(String msg){
459 System.out.print("......................................... ");
460 System.out.println(msg);
464 protected static void reportResults(String clsName, int nTests, int nFailures, int nErrors, List<String> results){
465 System.out.println();
466 System.out.print("......................................... execution of testsuite: " + clsName);
467 if (nFailures > 0 || nErrors > 0){
468 System.out.println(" FAILED");
469 } else if (nTests > 0) {
470 System.out.println(" SUCCEEDED");
472 System.out.println(" OBSOLETE");
476 if (results != null) {
478 for (String result : results) {
479 System.out.print(".... [" + ++i + "] ");
480 System.out.println(result);
485 System.out.print(".........................................");
486 System.out.println(" tests: " + nTests + ", failures: " + nFailures + ", errors: " + nErrors);
490 static void invoke (Method m, Object testObject) throws IllegalAccessException, InvocationTargetException {
491 PrintStream sysOut = null;
496 System.setOut( new DevNullPrintStream());
499 m.invoke( testObject);
503 System.setOut( sysOut);
509 * this is the main test loop if this TestJPF instance is executed directly
510 * or called from RunTest. It is *not* called if this is executed from JUnit
512 public static void runTests (Class<? extends TestJPF> testCls, String... args){
516 String testMethodName = null;
517 List<String> results = null;
520 globalRunDirectly = runDirectly;
521 globalShowConfig = showConfig;
522 boolean globalStopOnFailure = stopOnFailure;
525 List<Method> testMethods = getTestMethods(testCls, args);
526 results = new ArrayList<String>(testMethods.size());
528 // check if we have JUnit style housekeeping methods (initialization and
529 // cleanup should use the same mechanisms as JUnit)
531 List<Method> beforeClassMethods = getBeforeClassMethods(testCls);
532 List<Method> afterClassMethods = getAfterClassMethods(testCls);
534 List<Method> beforeMethods = getBeforeMethods(testCls);
535 List<Method> afterMethods = getAfterMethods(testCls);
537 for (Method initMethod : beforeClassMethods) {
538 reportTestInitialization(initMethod.getName());
539 initMethod.invoke(null);
542 for (Method testMethod : testMethods) {
543 testMethodName = testMethod.getName();
544 String result = testMethodName;
546 Object testObject = testCls.newInstance();
549 reportTestStart( testMethodName);
551 // run per test initialization methods
552 for (Method initMethod : beforeMethods){
553 reportTestInitialization( initMethod.getName());
554 invoke( initMethod, testObject);
557 // now run the test method itself
558 invoke( testMethod, testObject);
561 // run per test initialization methods
562 for (Method cleanupMethod : afterMethods){
563 reportTestCleanup( cleanupMethod.getName());
564 invoke( cleanupMethod, testObject);
567 } catch (InvocationTargetException x) {
568 Throwable cause = x.getCause();
569 cause.printStackTrace();
570 if (cause instanceof AssertionError) {
572 reportTestFinished("test method failed with: " + cause.getMessage());
573 result += ": Failed";
576 reportTestFinished("unexpected error while executing test method: " + cause.getMessage());
580 if (globalStopOnFailure){
586 reportTestFinished(result);
589 for (Method cleanupMethod : afterClassMethods) {
590 reportTestCleanup( cleanupMethod.getName());
591 cleanupMethod.invoke(null);
595 //--- those exceptions are unexpected and represent unrecoverable test harness errors
596 } catch (InvocationTargetException x) {
597 Throwable cause = x.getCause();
598 cause.printStackTrace();
600 reportTestFinished("TEST ERROR: @BeforeClass,@AfterClass method failed: " + x.getMessage());
602 } catch (InstantiationException x) {
604 reportTestFinished("TEST ERROR: cannot instantiate test class: " + x.getMessage());
605 } catch (IllegalAccessException x) { // can't happen if getTestMethods() worked
607 reportTestFinished("TEST ERROR: default constructor or test method not public: " + testMethodName);
608 } catch (IllegalArgumentException x) { // can't happen if getTestMethods() worked
610 reportTestFinished("TEST ERROR: illegal argument for test method: " + testMethodName);
611 } catch (RuntimeException rx) {
613 reportTestFinished("TEST ERROR: " + rx.toString());
617 reportResults(testCls.getName(), nTests, nFailures, nErrors, results);
620 if (nErrors > 0 || nFailures > 0){
622 // we need to reportTestFinished this test has failed
623 throw new RunTest.Failed();
628 static String getProperty(String key){
629 // intercepted by peer
634 * this is the JPF entry method in case there is no main() in the test class
636 * <2do> we should support test method arguments here
638 static void runTestMethod(String args[]) throws Throwable {
639 String testClsName = getProperty("target");
640 String testMthName = getProperty("target.test_method");
642 Class<?> testCls = Class.forName(testClsName);
643 Object target = testCls.newInstance();
645 Method method = testCls.getMethod(testMthName);
648 method.invoke(target);
649 } catch (InvocationTargetException e) {
655 * NOTE: this needs to be called from the concrete test class, typically from
656 * its main() method, otherwise we don't know the name of the class we have
659 protected static void runTestsOfThisClass (String[] testMethods){
660 // needs to be at the same stack level, so we can't delegate
661 Class<? extends TestJPF> testClass = Reflection.getCallerClass(TestJPF.class);
662 runTests(testClass, testMethods);
666 * needs to be broken up into two methods for cases that do additional
667 * JPF initialization (jpf-inspector)
669 * this is called from the various verifyX() methods (i.e. host VM) to
670 * start JPF, it is never executed under JPF
672 protected JPF createAndRunJPF (StackTraceElement testMethod, String[] args) {
673 JPF jpf = createJPF( testMethod, args);
681 * this is never executed under JPF
683 protected JPF createJPF (StackTraceElement testMethod, String[] args) {
686 Config conf = new Config(args);
688 // --- add global args (if we run under RunTest)
689 if (globalArgs != null) {
690 for (GlobalArg ga : globalArgs) {
701 setTestTargetKeys(conf, testMethod);
703 // --- initialize the classpath from <projectId>.test_classpath
704 String projectId = JPFSiteUtils.getCurrentProjectId();
705 if (projectId != null) {
706 String testCp = conf.getString(projectId + ".test_classpath");
707 if (testCp != null) {
708 conf.append("classpath", testCp, ",");
712 // --- if we have any specific test property overrides, do so
713 conf.promotePropertyCategory("test.");
717 if (showConfig || showConfigSources) {
718 PrintWriter pw = new PrintWriter(System.out, true);
719 if (showConfigSources) {
720 conf.printSources(pw);
734 protected void setTestTargetKeys(Config conf, StackTraceElement testMethod) {
735 conf.put("target.entry", "runTestMethod([Ljava/lang/String;)V");
736 conf.put("target", testMethod.getClassName());
737 conf.put("target.test_method", testMethod.getMethodName());
740 //--- the JPFShell interface
742 public void start(String[] testMethods){
743 Class<? extends TestJPF> testClass = getClass(); // this is an instance method
744 runTests(testClass, testMethods);
747 protected StackTraceElement getCaller(){
748 StackTraceElement[] st = (new Throwable()).getStackTrace();
752 protected StackTraceElement setTestMethod (String clsName, String mthName){
753 return new StackTraceElement( clsName, mthName, null, -1);
756 protected StackTraceElement setTestMethod (String mthName){
757 return new StackTraceElement( getClass().getName(), mthName, null, -1);
761 //--- the JPF run test methods
764 * run JPF expecting a AssertionError in the SuT
765 * @param args JPF main() arguments
767 protected JPF assertionError (StackTraceElement testMethod, String... args){
768 return unhandledException( testMethod, "java.lang.AssertionError", null, args );
770 protected JPF assertionError (String... args) {
771 return unhandledException( getCaller(), "java.lang.AssertionError", null, args );
774 protected JPF assertionErrorDetails (StackTraceElement testMethod, String details, String... args) {
775 return unhandledException( testMethod, "java.lang.AssertionError", details, args );
777 protected JPF assertionErrorDetails (String details, String... args) {
778 return unhandledException( getCaller(), "java.lang.AssertionError", details, args );
780 protected boolean verifyAssertionErrorDetails (String details, String... args){
784 unhandledException( getCaller(), "java.lang.AssertionError", details, args);
788 protected boolean verifyAssertionError (String... args){
792 unhandledException( getCaller(), "java.lang.AssertionError", null, args);
798 * run JPF expecting no SuT property violations
800 protected JPF noPropertyViolation (StackTraceElement testMethod, String... args) {
806 jpf = createAndRunJPF( testMethod, args);
807 } catch (Throwable t) {
808 // we get as much as one little hickup and we declare it failed
810 fail("JPF internal exception executing: ", args, t.toString());
814 List<Error> errors = jpf.getSearchErrors();
815 if ((errors != null) && (errors.size() > 0)) {
816 fail("JPF found unexpected errors: " + (errors.get(0)).getDescription());
822 protected JPF noPropertyViolation (String... args) {
823 return noPropertyViolation( getCaller(), args);
826 protected boolean verifyNoPropertyViolation (String...args){
830 noPropertyViolation( getCaller(), args);
836 * NOTE: this uses the exception class name because it might be an
837 * exception type that is only known to JPF (i.e. not in the native classpath)
839 * @param xClassName name of the exception base type that is expected
840 * @param details detail message of the expected exception
841 * @param args JPF arguments
843 protected JPF unhandledException (StackTraceElement testMethod, String xClassName, String details, String... args) {
849 jpf = createAndRunJPF(testMethod, args);
850 } catch (Throwable t) {
852 fail("JPF internal exception executing: ", args, t.toString());
856 Error error = jpf.getLastError();
858 Property errorProperty = error.getProperty();
859 if (errorProperty instanceof NoUncaughtExceptionsProperty){
860 ExceptionInfo xi = ((NoUncaughtExceptionsProperty)errorProperty).getUncaughtExceptionInfo();
861 String xn = xi.getExceptionClassname();
862 if (!xn.equals(xClassName)) {
863 fail("JPF caught wrong exception: " + xn + ", expected: " + xClassName);
866 if (details != null) {
867 String gotDetails = xi.getDetails();
868 if (gotDetails == null) {
869 fail("JPF caught the right exception but no details, expected: " + details);
871 if (!gotDetails.endsWith(details)) {
872 fail("JPF caught the right exception but the details were wrong: " + gotDetails + ", expected: " + details);
876 } else { // error not a NoUncaughtExceptionsProperty
877 fail("JPF failed to catch exception executing: ", args, ("expected " + xClassName));
880 fail("JPF failed to catch exception executing: ", args, ("expected " + xClassName));
886 protected JPF unhandledException (String xClassName, String details, String... args) {
887 return unhandledException( getCaller(), xClassName, details, args);
891 protected boolean verifyUnhandledExceptionDetails (String xClassName, String details, String... args){
895 unhandledException( getCaller(), xClassName, details, args);
899 protected boolean verifyUnhandledException (String xClassName, String... args){
903 unhandledException( getCaller(), xClassName, null, args);
910 * run JPF expecting it to throw an exception
911 * NOTE - xClassName needs to be the concrete exception, not a super class
912 * @param args JPF main() arguments
914 protected JPF jpfException (StackTraceElement testMethod, Class<? extends Throwable> xCls, String... args) {
916 Throwable exception = null;
921 jpf = createAndRunJPF( testMethod, args);
922 } catch (JPF.ExitException xx) {
923 exception = xx.getCause();
924 } catch (Throwable x) {
928 if (exception != null){
929 if (!xCls.isAssignableFrom(exception.getClass())){
930 fail("JPF produced wrong exception: " + exception + ", expected: " + xCls.getName());
933 fail("JPF failed to produce exception, expected: " + xCls.getName());
939 protected JPF jpfException (Class<? extends Throwable> xCls, String... args) {
940 return jpfException( getCaller(), xCls, args);
943 protected boolean verifyJPFException (TypeRef xClsSpec, String... args){
949 Class<? extends Throwable> xCls = xClsSpec.asNativeSubclass(Throwable.class);
951 jpfException( getCaller(), xCls, args);
953 } catch (ClassCastException ccx){
954 fail("not a property type: " + xClsSpec);
955 } catch (ClassNotFoundException cnfx){
956 fail("property class not found: " + xClsSpec);
965 * run JPF expecting a property violation of the SuT
966 * @param args JPF main() arguments
968 protected JPF propertyViolation (StackTraceElement testMethod, Class<? extends Property> propertyCls, String... args ){
974 jpf = createAndRunJPF( testMethod, args);
975 } catch (Throwable t) {
977 fail("JPF internal exception executing: ", args, t.toString());
980 List<Error> errors = jpf.getSearchErrors();
981 if (errors != null) {
982 for (Error e : errors) {
983 if (propertyCls == e.getProperty().getClass()) {
984 return jpf; // success, we got the sucker
989 fail("JPF failed to detect error: " + propertyCls.getName());
993 protected JPF propertyViolation (Class<? extends Property> propertyCls, String... args ){
994 return propertyViolation( getCaller(), propertyCls, args);
997 protected boolean verifyPropertyViolation (TypeRef propertyClsSpec, String... args){
1003 Class<? extends Property> propertyCls = propertyClsSpec.asNativeSubclass(Property.class);
1004 propertyViolation( getCaller(), propertyCls, args);
1006 } catch (ClassCastException ccx){
1007 fail("not a property type: " + propertyClsSpec);
1008 } catch (ClassNotFoundException cnfx){
1009 fail("property class not found: " + propertyClsSpec);
1017 * run JPF expecting a deadlock in the SuT
1018 * @param args JPF main() arguments
1020 protected JPF deadlock (String... args) {
1021 return propertyViolation( getCaller(), NotDeadlockedProperty.class, args );
1024 protected boolean verifyDeadlock (String... args){
1028 propertyViolation( getCaller(), NotDeadlockedProperty.class, args);
1033 // these are the org.junit.Assert APIs, but we don't want org.junit to be
1034 // required to run tests
1036 public static void assertEquals(String msg, Object expected, Object actual){
1037 if (expected == null && actual == null) {
1041 if (expected != null && expected.equals(actual)) {
1048 public static void assertEquals(Object expected, Object actual){
1049 assertEquals("", expected, actual);
1052 public static void assertEquals(String msg, int expected, int actual){
1053 if (expected != actual) {
1058 public static void assertEquals(int expected, int actual){
1059 assertEquals("expected != actual : " + expected + " != " + actual, expected, actual);
1062 public static void assertEquals(String msg, long expected, long actual){
1063 if (expected != actual) {
1068 public static void assertEquals(long expected, long actual){
1069 assertEquals("expected != actual : " + expected + " != " + actual,
1073 public static void assertEquals(double expected, double actual){
1074 if (expected != actual){
1075 fail("expected != actual : " + expected + " != " + actual);
1079 public static void assertEquals(String msg, double expected, double actual){
1080 if (expected != actual){
1085 public static void assertEquals(float expected, float actual){
1086 if (expected != actual){
1087 fail("expected != actual : " + expected + " != " + actual);
1091 public static void assertEquals(String msg, float expected, float actual){
1092 if (expected != actual){
1097 public static void assertEquals(String msg, double expected, double actual, double delta){
1098 if (Math.abs(expected - actual) > delta) {
1103 public static void assertEquals(double expected, double actual, double delta){
1104 assertEquals("Math.abs(expected - actual) > delta : " + "Math.abs(" + expected + " - " + actual + ") > " + delta,
1105 expected, actual, delta);
1108 public static void assertEquals(String msg, float expected, float actual, float delta){
1109 if (Math.abs(expected - actual) > delta) {
1114 public static void assertEquals(float expected, float actual, float delta){
1115 assertEquals("Math.abs(expected - actual) > delta : " + "Math.abs(" + expected + " - " + actual + ") > " + delta,
1116 expected, actual, delta);
1119 public static void assertArrayEquals(byte[] expected, byte[] actual){
1120 if (((expected == null) != (actual == null)) ||
1121 (expected.length != actual.length)){
1122 fail("array sizes different");
1125 for (int i=0; i<expected.length; i++){
1126 if (expected[i] != actual[i]){
1127 fail("array element" + i + " different, expected " + expected[i] + ", actual " + actual[i]);
1132 public static void assertNotNull(String msg, Object o) {
1138 public static void assertNotNull(Object o){
1139 assertNotNull("o == null", o);
1142 public static void assertNull(String msg, Object o){
1148 public static void assertNull(Object o){
1149 assertNull("o != null", o);
1152 public static void assertSame(String msg, Object expected, Object actual){
1153 if (expected != actual) {
1158 public static void assertSame(Object expected, Object actual){
1159 assertSame("expected != actual : " + expected + " != " + actual, expected, actual);
1162 public static void assertFalse (String msg, boolean cond){
1168 public static void assertFalse (boolean cond){
1169 assertFalse("", cond);
1172 public static void assertTrue (String msg, boolean cond){
1178 public static void assertTrue (boolean cond){
1179 assertTrue("", cond);