Initial import
[jpf-core.git] / src / tests / gov / nasa / jpf / test / mc / basic / MethodListenerTest.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
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
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
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.
17  */
18
19 package gov.nasa.jpf.test.mc.basic;
20
21 import gov.nasa.jpf.Config;
22 import gov.nasa.jpf.ListenerAdapter;
23 import gov.nasa.jpf.search.Search;
24 import gov.nasa.jpf.util.test.TestJPF;
25 import gov.nasa.jpf.vm.ElementInfo;
26 import gov.nasa.jpf.vm.ThreadInfo;
27 import gov.nasa.jpf.vm.VM;
28 import gov.nasa.jpf.vm.MethodInfo;
29
30 import java.util.ArrayList;
31
32 import org.junit.Test;
33
34 /**
35  * test of the VMListener method notifications
36  */
37 public class MethodListenerTest extends TestJPF {
38
39   // avoid loading JPF classes when running under JPF (specify classnames explicitly)
40   static String CLSNAME = "gov.nasa.jpf.test.mc.basic.MethodListenerTest";
41   static String LISTENER = "+listener=gov.nasa.jpf.test.mc.basic.MethodListenerTest$Listener";
42
43   public static class Listener extends ListenerAdapter {
44     String startMthName;
45
46     boolean traceActive = false;
47     int level;
48
49     public Listener (Config config){
50       startMthName = config.getString("_start");
51     }
52
53     String levelPrefix (int lvl){
54       String prefix = "";
55       for (int i=0; i<lvl; i++){
56         prefix += "  ";
57       }
58       return prefix;
59     }
60
61     @Override
62     public void searchStarted(Search search) {
63       trace.clear();
64     }
65
66     @Override
67     public void methodEntered (VM vm, ThreadInfo ti, MethodInfo mi){
68       assertSame(mi, ThreadInfo.getCurrentThread().getTopFrameMethodInfo());
69
70       if (CLSNAME.equals(mi.getClassName())){
71         String mthName = mi.getName();
72         if (mthName.equals(startMthName)) {
73           traceActive = true;
74           level=0;
75         }
76
77         if (traceActive){
78           String prefix = levelPrefix(level);
79           trace.add(prefix + "> " + mthName);
80
81           System.out.println(prefix + "> " + mthName);
82
83           level++;
84         }
85       }
86     }
87
88     @Override
89     public void methodExited (VM vm, ThreadInfo ti, MethodInfo mi){
90       if (traceActive){
91         assertSame(mi, ThreadInfo.getCurrentThread().getTopFrameMethodInfo());
92         
93         if (CLSNAME.equals(mi.getClassName())){
94           level--;
95
96           String prefix = levelPrefix(level);
97           trace.add(prefix + "< " + mi.getName());
98
99           System.out.println(prefix + "< " + mi.getName());
100
101           if (level == 0){
102             traceActive = false;
103           }
104         }
105
106       }
107     }
108
109     @Override
110     public void exceptionThrown (VM vm, ThreadInfo ti, ElementInfo ei){
111       if (traceActive){
112         String xCls = ei.getClassInfo().getName();
113         trace.add("X " + xCls);
114         System.out.println("X " + xCls);
115       }
116     }
117   }
118
119   static ArrayList<String> trace = new ArrayList<String>();
120
121   static boolean traceEquals(String... expected){
122     if (expected.length != trace.size()){
123       System.err.println("wrong trace size, found: " + trace.size() + ", expected: " + expected.length);
124       return false;
125     }
126
127     int i = 0;
128     for (String s : trace){
129       if (!s.equals(expected[i])){
130         System.err.println("wrong trace entry, found: " + s + ", expected: " + expected[i]);
131         return false;
132       }
133       i++;
134     }
135     return true;
136   }
137
138   //--- internal test stuff
139   void foo(){
140     bar();
141   }
142
143   int bar(){
144     return 24;
145   }
146
147   void baz (){
148     blowUp();
149   }
150
151   void blowUp() {
152     throw new RuntimeException("I blow up");
153   }
154   
155   void time() {
156     System.currentTimeMillis();
157   }
158
159   //--- test methods
160   @Test public void testBasicInvocation() {
161     if (verifyNoPropertyViolation(LISTENER, "+_start=testBasicInvocation")){
162       foo();
163       
164     } else {
165       assertTrue(traceEquals(
166               "> testBasicInvocation",
167               "  > foo",
168               "    > bar",
169               "    < bar",
170               "  < foo",
171               "< testBasicInvocation"));
172     }
173   }
174
175   @Test public void testException() {
176     if (verifyNoPropertyViolation(LISTENER, "+_start=testException")){
177       try {
178         baz();
179
180       } catch (RuntimeException x){
181       }
182
183     } else {
184       assertTrue(traceEquals(
185               "> testException",
186               "  > baz",
187               "    > blowUp",
188               "X java.lang.RuntimeException",
189               "    < blowUp",
190               "  < baz",
191               "< testException"));
192     }
193   }
194 }