package org.jmlspecs.openjmltest.testcases; import java.util.ArrayList; import java.util.Collection; import org.jmlspecs.openjml.JmlOption; import org.jmlspecs.openjmltest.EscBase; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.ParameterizedWithNames; import org.junit.runners.Parameterized.Parameters; // FIXME - there is nothing checking that these give correct results /** Tests emitting counterexample information and tracing, though the text * of the output is not actually checked - needs visual observation. * @author David Cok * */ @RunWith(ParameterizedWithNames.class) public class escCounterexamples extends EscBase { public escCounterexamples(String options, String solver) { super(options,solver); } @Override public void setUp() throws Exception { //noCollectDiagnostics = true; super.setUp(); main.addOptions("-trace","-counterexample"); main.addOptions("-code-math=java"); } /** Tests an explicit assertion */ @Test public void testCE1() { print = true; helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" //@ requires k > 0;\n" +" public void m1(int k) {\n" +" //@ assert k == 0;\n" +" }\n" +"}" ,"/tt/TestJava.java:5: warning: The prover cannot establish an assertion (Assert) in method m1",9 ); } /** Tests a postcondition */ @Test public void testCE2() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" //@ requires k > 0;\n" +" //@ ensures \\result < 0;\n" +" public int m1(int k) {\n" +" return k;\n" +" }\n" +"}" ,"/tt/TestJava.java:6: warning: The prover cannot establish an assertion (Postcondition) in method m1",5 ,"/tt/TestJava.java:4: warning: Associated declaration",7 ); } /** Tests a called precondition and method and constructor arguments */ @Test public void testCE3() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public TestJava(int i) {}\n" +" public void m1(int k) {\n" +" c1(k,k!=0);\n" +" TestJava j = new TestJava(2+3);\n" +" (k==0?this:j).m1(0);\n" +" }\n" +" //@ requires k == 0;\n" +" public void c1(int k, boolean b) {};\n" +"}" ,"/tt/TestJava.java:5: warning: The prover cannot establish an assertion (Precondition) in method m1",7 ,"/tt/TestJava.java:9: warning: Associated declaration",7 ); } /** Tests assignments */ @Test public void testCE4() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public int j; static public int sj; static public TestJava t;\n" +" public TestJava(int i) {}\n" +" //@ requires t != null; requires \\elemtype(\\typeof(c)) == \\type(Object); \n" +" public void m1(Object[] c) {\n" +" int k; boolean b;\n" +" //@ assume c != null && c.length == 10;\n" +" k = 8;\n" +" k += 8;\n" +" k += (j+=7);\n" +" b = k > 8;\n" +" c[4] = t;\n" +" c[0] = c[3];\n" +" t.j = 9;\n" +" t.sj = 10;\n" +" TestJava.sj = 11;\n" +" //@ assert false;\n" +" }\n" +"}\n" ,"/tt/TestJava.java:18: warning: The prover cannot establish an assertion (Assert) in method m1",9 ); } /** Tests if statements */ @Test public void testCE5() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public int j; static public int sj; static public TestJava t;\n" +" public TestJava(int i) {}\n" +" //@ requires j == 0;\n" +" public void m1(int j) {\n" +" if (j==0) j=1;\n" +" if (j == 2) j=7;\n" +" if (j == 3) j=6;\n" +" else if (j==4) j=7;\n" +" else if (j==1) j=10;\n" +" else j=80;\n" +" //@ assert false;\n" +" }\n" +"}\n" ,"/tt/TestJava.java:13: warning: The prover cannot establish an assertion (Assert) in method m1",9 ); } /** Tests loops */ @Test public void testCE6() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" //@ requires j > 0;\n" +" public void m1(int j) {\n" +" int n = 0;\n" +" //@ loop_invariant 0<=i && i <=j;\n" +" //@ loop_invariant n == i;\n" +" for (int i=0; i<j; i++) {\n" +" n = n+1;\n" +" //@ assert n != 20;\n" +" }\n" +" }\n" +" //@ requires j > 0;\n" +" public void m2(int j) {\n" +" int n = 0;\n" +" //@ loop_invariant 0<=i && i <=j;\n" +" //@ loop_invariant n == i;\n" +" for (int i=0; i<j; i++) {\n" +" n = n+1;\n" +" }\n" +" //@ assert n == -10;\n" +" }\n" +"}\n" ,"/tt/TestJava.java:10: warning: The prover cannot establish an assertion (Assert) in method m1",13 ,"/tt/TestJava.java:21: warning: The prover cannot establish an assertion (Assert) in method m2",9 ); } /** Tests pure methods */ @Test public void testCE7() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void m1() {\n" +" //@ assert c(2) != -2;\n" // ERROR - c(2) can be any negative number +" }\n" +" public void m2() {\n" +" //@ assert cc(2) != -3;\n" // OK - we know cc(2) is -2 +" }\n" +" public void m3() {\n" +" //@ assert b();\n" // ERROR - b() can be anything +" }\n" +" public void m4() {\n" +" //@ assert bb(0);\n" // ERROR - bb(0) ncan be anything - is this any different from m3? +" }\n" +" //@ normal_behavior requires z > 0; ensures \\result < 0;\n" +" /*@ pure */ public int c(int z) {\n" +" return -z;\n" +" }\n" +" //@ public normal_behavior requires z > 0; ensures \\result == -z;\n" +" /*@ pure */ public int cc(int z) {\n" +" return -z;\n" +" }\n" +" //@ normal_behavior requires true; \n" +" /*@ pure */ static public boolean b() {\n" +" return true;\n" +" }\n" +" //@ normal_behavior requires true; \n" +" /*@ pure */ static public boolean bb(int z) {\n" +" return true;\n" +" }\n" +"}\n" ,"/tt/TestJava.java:4: warning: The prover cannot establish an assertion (Assert) in method m1",11 ,"/tt/TestJava.java:10: warning: The prover cannot establish an assertion (Assert) in method m3",11 ,"/tt/TestJava.java:13: warning: The prover cannot establish an assertion (Assert) in method m4",11 ); } /** Tests alternate returns */ @Test public void testCE8() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" //@ requires i>=0; ensures \\result==0;\n" +" public int m1(int i) {\n" +" if (i==0) return 0;\n" +" if (i==1) return i+20;\n" +" if (i==2) return 0;\n" +" if (i==3) return 0;\n" +" return 0;\n" +" }\n" +" static public int k;\n" +" //@ requires i>=0; ensures k == 0;\n" +" public void m2(int i) {\n" +" k = 0;\n" +" if (i==0) return ;\n" +" if (i==1) return ;\n" +" if (i==2) { k = 1; return ;}\n" +" if (i==3) return ;\n" +" return ;\n" +" }\n" +"}\n" ,"/tt/TestJava.java:6: warning: The prover cannot establish an assertion (Postcondition) in method m1",17 ,"/tt/TestJava.java:3: warning: Associated declaration",22 ,"/tt/TestJava.java:17: warning: The prover cannot establish an assertion (Postcondition) in method m2",26 ,"/tt/TestJava.java:12: warning: Associated declaration",22 ); } /** Tests switch statements */ @Test public void testCE9() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" //@ requires i>=0; ensures \\result==0;\n" +" public int m1(int i) {\n" +" int r = 0;\n" +" switch (i+5) {\n" +" case 3: r = 0; break;\n" +" case 5: r = 4; break;\n" +" case 7: r = 0; break;\n" +" }\n" +" return r;\n" +" }\n" +" //@ requires i>=0; ensures \\result==0;\n" +" public int m2(int i) {\n" +" int r = 0;\n" +" switch (i+5) {\n" +" case 3: r = 0; break;\n" +" case 5: r = 4; break;\n" +" case 7: r = 0; break;\n" +" default: r = 0; break;\n" +" }\n" +" return r;\n" +" }\n" +"}\n" ,"/tt/TestJava.java:11: warning: The prover cannot establish an assertion (Postcondition) in method m1",7 ,"/tt/TestJava.java:3: warning: Associated declaration",22 ,"/tt/TestJava.java:22: warning: The prover cannot establish an assertion (Postcondition) in method m2",7 ,"/tt/TestJava.java:13: warning: Associated declaration",22 ); } /** Tests called method return */ @Test public void testCE10() { main.addOptions(JmlOption.ESC_MAX_WARNINGS.optionName() + "=1"); helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" //@ public normal_behavior requires i>=0; ensures k==0;\n" +" public void m1(int i) {\n" +" cc(i);\n" +" }\n" +" //@ requires i>=0; ensures k==1;\n" +" public void m2(int i) {\n" +" cc(i);\n" +" }\n" +" public int k;\n" +" //@ requires i>0; \n" +" //@ ensures k==0;\n" +" //@ signals (Exception e) false;\n" +" //@ also requires i==0; \n" +" //@ ensures false;\n" +" //@ signals (RuntimeException e) k==1;\n" +" //@ signals_only RuntimeException;\n" +" public void cc(int i) throws RuntimeException {\n" +" k=1; if (i==0) throw new RuntimeException();\n" +" k=0; return ;\n" +" }\n" +"}\n" ,"/tt/TestJava.java:5: warning: The prover cannot establish an assertion (ExceptionalPostcondition) in method m1",9 ,"/tt/TestJava.java:3: warning: Associated declaration",14 ,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Postcondition) in method m2",15 ,"/tt/TestJava.java:7: warning: Associated declaration",22 ); } /** Tests method calls in expressions */ @Test public void testCE11() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void m1(int i) {\n" +" int k = c(i) + c(i-15);\n" +" //@ assert k != 9;\n" +" }\n" +" //@ signals (Exception) false;\n" +" public void m2(int i) {\n" +" int k = c(i);\n" +" //@ assert true;\n" +" }\n" +" //@ ensures \\result == i+10;\n" +" public int c(int i) throws RuntimeException {\n" +" return i+10;\n" +" }\n" +"}\n" ,"/tt/TestJava.java:5: warning: The prover cannot establish an assertion (Assert) in method m1",11 ,"/tt/TestJava.java:9: warning: The prover cannot establish an assertion (ExceptionalPostcondition) in method m2",16 ,"/tt/TestJava.java:7: warning: Associated declaration",7 ); } // FIXME - synchronized is not translated or reported in tracing /** Tests misc statements: synchronized, block */ @Test public void testCE12() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void m1(int i) {\n" +" int k= 0;\n" +" synchronized (this) {k=1;}\n" +" { k = 2; k = 3+k;}\n" +" //@ assert false;\n" +" }\n" +"}\n" ,"/tt/TestJava.java:7: warning: The prover cannot establish an assertion (Assert) in method m1",11 ); } /** Tests initializations */ @Test public void testCE13() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void m1(int i) {\n" +" int k = 0;\n" +" int[] a = {1,2,3,4};\n" +" int[][] b = new int[2][3];\n" +" int[][] c = new int[2][];\n" +" int[][] d = new int[][]{{1},{2,3}};\n" +" //@ assert false;\n" +" }\n" +"}\n" ,"/tt/TestJava.java:9: warning: The prover cannot establish an assertion (Assert) in method m1",11 ); } /** Tests JML statements */ @Test public void testCE14() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" int k = 98; public Object o; \n" +" public void m1(int i) {\n" +" //@ assume k == 98; \n" +" //@ ghost int kk = 0;\n" +" //@ set kk = 5;\n" +" //@ debug kk = 7;\n" +" k = 65;\n" +" //@ set kk = \\old(k) - k;\n" +" //@ assume (k==k) && (\\lblpos X (k == 65));\n" +" //@ assume o!= null && \\typeof(o) <: \\type(Object);\n" +" //@ unreachable;\n" +" }\n" +" public TestJava() { o = new Object(); }\n" +"}\n" ,"/tt/TestJava.java:11: warning: Label X has value true",37 ,"/tt/TestJava.java:13: warning: The prover cannot establish an assertion (Unreachable) in method m1",11 ); } /** Tests try/catch/finally */ @Test public void testCE15() { main.addOptions(JmlOption.ESC_MAX_WARNINGS.optionName()+"=1"); helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" //@ ensures false; \n" +" public void m1(int i) {\n" +" int k = 9 - 9;\n" +" try {\n" +" k = 1 + 2 + 3 - 1;\n" +" try {\n" +" k = 7;\n" +" return;\n" +" } finally {\n" +" k = 9;\n" +" }\n" +" } finally {\n" +" k = 13;\n" +" return;\n" +" }\n" +" }\n" +" //@ requires i != 0; ensures false; \n" //Line 19 +" public void m2(int i) throws Exception {\n" +" int k = 0;\n" +" try {\n" +" k = 5;\n" +" try {\n" +" k = 7;\n" +" if (i==0) throw new RuntimeException();\n" +" return;\n" +" } catch (Exception e) {\n" +" k = 25;\n" +" throw e;\n" +" } finally {\n" +" k = 9;\n" +" }\n" +" } catch (RuntimeException e) {\n" +" k = 27;\n" +" } finally {\n" +" k = 13;\n" +" }\n" +" }\n" +" //@ requires i == 0; ensures false; \n" // Line 40 +" public void m3(int i) throws Exception {\n" +" int k = 0;\n" +" try {\n" +" k = 5;\n" +" try {\n" +" k = 7;\n" +" if (i==0) throw new RuntimeException();\n" +" return;\n" +" } catch (Exception e) {\n" +" k = 25;\n" +" throw e;\n" +" } finally {\n" +" k = 9;\n" +" }\n" +" } catch (RuntimeException e) {\n" +" k = 27;\n" +" } finally {\n" +" k = 13;\n" +" }\n" +" }\n" +"}\n" ,"/tt/TestJava.java:16: warning: The prover cannot establish an assertion (Postcondition) in method m1",8 ,"/tt/TestJava.java:3: warning: Associated declaration",7 ,"/tt/TestJava.java:27: warning: The prover cannot establish an assertion (Postcondition) in method m2",10 ,"/tt/TestJava.java:19: warning: Associated declaration",24 ,"/tt/TestJava.java:51: warning: The prover cannot establish an assertion (Postcondition) in method m3",10 ,"/tt/TestJava.java:40: warning: Associated declaration",24 ); } /** Tests try/catch/finally */ @Test public void testCE16() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" //@ ensures \\result != 10; \n" +" public int m1(int i) {\n" +" int k = i + 2 - 1;\n" +" return k + 5;\n" +" }\n" +" }\n" ,"/tt/TestJava.java:6: warning: The prover cannot establish an assertion (Postcondition) in method m1",5 ,"/tt/TestJava.java:3: warning: Associated declaration",7 ); } }