KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > quilt > cover > stmt > TestStmtCoverage


1 /* TestStmtCoverage.java */
2 package org.quilt.cover.stmt;
3
4 import java.io.*;
5 import java.lang.Class JavaDoc;
6 import java.lang.reflect.*;
7 import java.net.*;
8
9 // DEBUG
10
import java.lang.reflect.Field JavaDoc;
11 import java.lang.reflect.Method JavaDoc;
12 // END
13

14 import junit.framework.*;
15 import org.apache.bcel.generic.*;
16 import org.quilt.cl.*;
17 import org.quilt.cover.stmt.*;
18
19 /**
20  * This is derived from org.quilt.cl.TestTransformer; it instruments
21  * the test-data classes and the classes synthesized by ClassFactory.
22  * All of the instrumented classes are run and checked to see that
23  * they produce normal output, despite the instrumentation ;-)
24  *
25  * @author <a HREF="jddixon@users.sourceforge.net">Jim Dixon</a>
26  */

27 public class TestStmtCoverage extends TestCase {
28
29     private ControlFlowGraph cfg;
30
31     /** Classpath. */
32     private URL [] cp = null; // this is built up below
33

34     private String JavaDoc[] delegating = {
35         // NOTHING beyond standard defaults
36
};
37     // we want everything to be instrumented
38
private String JavaDoc[] include = {
39         "test.data.",
40         "AnonymousClass", "AnonymousClass2Catches",
41         "BasicLoad", "ComplicatedConstructor",
42         "ExceptionLoad", "ExceptionThrow",
43         "Finally", "Finally2Classes",
44         "InnerClass", "Looper",
45         "NestedTryBlocks", "OddSwitches",
46         "PrivateClass", "StaticInit",
47         "SuperClass", "SwitchLoad",
48         "Wimple"
49     };
50     private String JavaDoc[] exclude = {
51         // NOTHING
52
};
53
54     private GraphXformer spy;
55     private GraphXformer talker, talker2;
56
57     private StmtRegistry stmtReg;
58
59     private QuiltClassLoader qLoader = null;
60
61     public TestStmtCoverage (String JavaDoc name) {
62         super(name);
63     }
64
65     public void setUp () {
66         File sam1 = new File ("target/test-data-classes/");
67         String JavaDoc fullPath1 = sam1.getAbsolutePath() + "/";
68         File sam2 = new File ("target/classes");
69         String JavaDoc fullPath2 = sam2.getAbsolutePath() + "/";
70         File sam3 = new File ("target/test-classes");
71         String JavaDoc fullPath3 = sam3.getAbsolutePath() + "/";
72         try {
73             // Terminating slash is required. Relative paths don't
74
// work.
75
URL [] samples = {
76                 new URL ( "file://" + fullPath1),
77                 new URL ( "file://" + fullPath2),
78                 new URL ( "file://" + fullPath3)
79             };
80             cp = samples;
81         } catch (MalformedURLException e) {
82             e.printStackTrace();
83             fail ("problem creating class path");
84         }
85         ClassLoader JavaDoc parent = ClassLoader.getSystemClassLoader();
86         qLoader = new QuiltClassLoader(
87                         cp,
88                         parent, // parent
89
delegating, // delegated classes
90
include, // being instrumented
91
exclude); // do NOT instrument
92

93         // Graph Xformers /////////////////////////////////
94
spy = new GraphSpy();
95         qLoader.addGraphXformer(spy);
96
97         // dumps graph BEFORE transformation
98
talker = new GraphTalker();
99         qLoader.addGraphXformer(talker);
100
101         // adds xformers for statement coverage to qLoader
102
// EXPERIMENT
103
stmtReg = (StmtRegistry) qLoader.addQuiltRegistry(
104                                     "org.quilt.cover.stmt.StmtRegistry");
105         // old way
106
//stmtReg = new StmtRegistry(qLoader);
107
//qLoader.addQuiltRegistry(stmtReg);
108

109         // dumps graph AFTER transformation
110
talker2 = new GraphTalker();
111         qLoader.addGraphXformer(talker2);
112     }
113
114     // SUPPORT METHODS //////////////////////////////////////////////
115
private RunTest loadAsRunTest (String JavaDoc name) {
116         Class JavaDoc clazz = null;
117         try {
118             clazz = qLoader.loadClass(name);
119 // // DEBUG -- trying to get fields causes an error
120
// Field[] fields = clazz.getFields();
121
// StringBuffer fieldData = new StringBuffer();
122
// for (int k = 0; k < fields.length; k++)
123
// fieldData.append(" ").append(fields[k].toString())
124
// .append("\n");
125

126 // Method[] methods = clazz.getMethods();
127
// StringBuffer methodData = new StringBuffer();
128
// for (int k = 0; k < methods.length; k++)
129
// methodData.append(" ").append(methods[k].toString())
130
// .append("\n");
131
//
132
// System.out.println("TestStmtRegistry: loading class " + name
133
// + "\nFIELDS (" + fields.length + ") :\n"
134
// + fieldData.toString()
135
// + "\nMETHODS (" + methods.length + ") :\n"
136
// + methodData.toString() );
137
// // END
138
} catch (ClassNotFoundException JavaDoc e) {
139             e.printStackTrace();
140             fail ("exception loading " + name + " using loadClass");
141         }
142         RunTest rt = null;
143         try {
144             rt = (RunTest) clazz.newInstance();
145         } catch ( InstantiationException JavaDoc e ) {
146             fail ("InstantiationException instantiating loaded class " + name);
147         } catch ( IllegalAccessException JavaDoc e ) {
148             fail ("IllegalAccessException instantiating loaded class " + name);
149         } catch (ClassCastException JavaDoc e) {
150             fail ("ClassCastException instantiating loaded class " + name);
151         }
152         return rt;
153     }
154     /**
155      * Check that the class has been properly instrumented by
156      * org.quilt.cover.stmt. At the moment this means only that the
157      * hitcount array, public static int[] q$$q is one of the class's
158      * fields. We also check that it has NOT been initialized,
159      * although we will eventually make sure that it has been.
160      */

161     private void checkInstrumentation(Object JavaDoc rt) {
162         String JavaDoc name = rt.getClass().getName();
163         System.out.println("checkInstrumentation for class " + name);
164         try {
165             Field JavaDoc qField = rt.getClass().getField("q$$q");
166             if (qField == null) {
167                 System.out.println(name + " has no hit count array");
168                 fail(name + " has NO hit count array");
169             } else try {
170                 int [] hitCounts = (int[]) qField.get(null);
171                 assertNotNull("q$$q has not been initialized", hitCounts);
172             } catch (IllegalAccessException JavaDoc e) {
173                 e.printStackTrace();
174             }
175             // check version
176
qField = rt.getClass().getField("q$$qVer");
177             if (qField == null) {
178                 System.out.println(name + " has no version field");
179                 fail(name + " has NO version field");
180             } else try {
181                 int version = qField.getInt(qField);
182                 assertEquals("q$$q has wrong version number", 0, version);
183             } catch (IllegalAccessException JavaDoc e) {
184                 e.printStackTrace();
185             }
186             // check StmtRegistry
187

188         } catch (NoSuchFieldException JavaDoc e) {
189             fail (name + " has no q$$q field");
190         }
191     }
192
193     // ACTUAL TESTS /////////////////////////////////////////////////
194
public void testGetReg() {
195         StmtRegistry regInLoader = (StmtRegistry)qLoader.getRegistry(
196                                     "org.quilt.cover.stmt.StmtRegistry");
197         assertNotNull("qLoader StmtRegistry is null", regInLoader);
198         assertSame ("qLoader has different StmtRegistry",
199                                                 stmtReg, regInLoader);
200     }
201     public void testLoader() {
202         Class JavaDoc a1 = null;
203         try {
204             a1 = qLoader.loadClass("AnonymousClass");
205         } catch (ClassNotFoundException JavaDoc e) {
206             e.printStackTrace();
207             fail ("Error loading AnonymousClass using loadClass");
208         }
209         assertNotNull("qLoader returned null", a1);
210     } // END
211

212 // /**
213
// * Test classes from src/test-data. All of these (should) have a
214
// * RunTest interface. They are loaded and then run to see that
215
// * they produce expected values.
216
// *
217
// * By and large the test inputs are primes greater than 2; in earlier
218
// * tests some failed, returned 0, and were judged successful because
219
// * 0 was the expected result.
220
// *
221
// * At the moment these are split into three groups, so that if they
222
// * fail we will see more results.
223
// */
224
public void testInvokeTestData() {
225         RunTest
226         rt = loadAsRunTest("AnonymousClass");
227         checkInstrumentation(rt);
228         // AnonymousClass.runTest(x) returns x
229
assertEquals ("AnonymousClass isn't working", 47, rt.runTest(47));
230
231         rt = loadAsRunTest("BasicLoad");
232         checkInstrumentation(rt);
233         // BasicLoad.runTest(x) returns x*x
234
assertEquals ("BasicLoad isn't working", 49, rt.runTest(7));
235
236         rt = loadAsRunTest("ComplicatedConstructor");
237         checkInstrumentation(rt);
238         assertEquals("ComplicatedConstructor isn't working",
239                                                     61, rt.runTest(3));
240         rt = loadAsRunTest("ExceptionLoad");
241         checkInstrumentation(rt);
242         // ExceptionLoad.runTest(x) also returns x*x
243
assertEquals ("ExceptionLoad isn't working", 121, rt.runTest(11));
244
245         rt = loadAsRunTest("InnerClass");
246         checkInstrumentation(rt);
247         // InnerClass.runTest(x) also returns x*x
248
assertEquals ("InnerClass isn't working", 9, rt.runTest(3));
249
250         rt = loadAsRunTest("Looper");
251         assertEquals("Looper isn't working", 127008000, rt.runTest(5));
252
253 // rt = loadAsRunTest("OddSwitches");
254
// // we like to play
255
// assertEquals( 91, rt.runTest(1001));
256
// assertEquals( 31, rt.runTest(3));
257
// assertEquals( 9, rt.runTest(9));
258
// assertEquals(101, rt.runTest(1005));
259
// assertEquals(-41, rt.runTest(-1));
260
// assertEquals( -3, rt.runTest(-51));
261
// assertEquals( 7, rt.runTest(-2));
262

263         rt = loadAsRunTest("PrivateClass");
264         checkInstrumentation(rt);
265         // returns 4
266
assertEquals ("PrivateClass isn't working", 4, rt.runTest(7));
267
268         rt = loadAsRunTest("SuperClass");
269         checkInstrumentation(rt);
270         // returns 3*x
271
assertEquals ("SuperClass isn't working", 21, rt.runTest(7));
272
273         // This would normally not be here, it would be at a higher
274
// level in the testing process. But we are testing the
275
// registry itself. XXX Collect the string and extract
276
// run results from it.
277
String JavaDoc runResults = stmtReg.getReport();
278         System.out.println("\nQuilt coverage report:\n" + runResults);
279     } // END TESTDATA
280

281     // SYNTHESIZED CLASSES //////////////////////////////////////////
282
// public void testSynth () {
283
// assertEquals ("synthesizing isn't disabled in loader",
284
// false, qLoader.getSynthEnabled() );
285
// qLoader.setSynthEnabled(true);
286
// assertEquals ("enabling synthesizing failed",
287
// true, qLoader.getSynthEnabled() );
288

289 // RunTest
290
// rt = loadAsRunTest("test.data.TestDefault");
291
// checkInstrumentation(rt);
292
// // testDefault.runTest(x) returns 2 whatever the input is
293
// assertEquals ("testDefault isn't working", 2, rt.runTest(47));
294
// assertEquals ("testDefault isn't working", 2, rt.runTest(-7));
295
// String
296
// runResults = stmtReg.getReport(); /// <-----------
297
// System.out.println("\nQuilt coverage report:\n" + runResults);
298

299 // rt = loadAsRunTest("test.data.TestIfThen");
300
// checkInstrumentation(rt);
301
// // testIfThen.runTest(x) returns 3 if x > 0, 5 otherwise
302
// assertEquals ("testIfThen isn't working", 3, rt.runTest(47));
303
// assertEquals ("testIfThen isn't working", 5, rt.runTest(-7));
304

305 // runResults = stmtReg.getReport(); /// <-----------
306
// System.out.println("\nQuilt coverage report:\n" + runResults);
307

308 // rt = loadAsRunTest("test.data.TestNPEWithCatch");
309
// checkInstrumentation(rt);
310
// // testNPEWithCatch.runTest(x) always returns 3
311
// assertEquals ("testNPEWithCatch isn't working", 3, rt.runTest(47));
312
// assertEquals ("testNPEWithCatch isn't working", 3, rt.runTest(-7));
313

314 // rt = loadAsRunTest("test.data.TestNPENoCatch");
315
// checkInstrumentation(rt);
316
// // testNPENoCatch.runTest(x) always throws a NullPointerException
317
// int x;
318
// try {
319
// x = rt.runTest(47);
320
// fail ("testNPENoCatch didn't throw exception");
321
// } catch (NullPointerException e) {
322
// ; // ignore it
323
// }
324
// try {
325
// x = rt.runTest(-7);
326
// fail ("testNPENoCatch didn't throw exception");
327
// } catch (NullPointerException e) {
328
// ; // ignore it
329
// }
330

331 // rt = loadAsRunTest("test.data.TestSelect");
332
// checkInstrumentation(rt);
333
// // testSelect.runTest(x) returns
334
// // 1 if x == 1; 3 if x == 2; 5 if x == 3; 2 otherwise
335
// assertEquals ("testSelect isn't working", 2, rt.runTest(47));
336
// assertEquals ("testSelect isn't working", 2, rt.runTest(-7));
337
// assertEquals ("testSelect isn't working", 1, rt.runTest(1));
338
// assertEquals ("testSelect isn't working", 3, rt.runTest(2));
339
// assertEquals ("testSelect isn't working", 5, rt.runTest(3));
340

341 // rt = loadAsRunTest("test.data.TestWhile");
342
// checkInstrumentation(rt);
343
// // testWhile.runTest(x) returns
344
// // 0 if x >= 0, x otherwise
345
// assertEquals ("testWhile isn't working", 0, rt.runTest(47));
346
// assertEquals ("testWhile isn't working",-7, rt.runTest(-7));
347
// } // END999
348

349 // /////////////////////////////////////////////////////////////////
350
// // BUGS BUGS BUGS BUGS //////////////////////////////////////////
351
// /////////////////////////////////////////////////////////////////
352
//
353
// /////////////////////////////////////////////////////////////////
354
// // LESSER BUGS //////////////////////////////////////////////////
355
// // "edge not in this graph" -- FIXED (a bit crudely)
356
// public void testNestedTryBlocks() {
357
// RunTest
358
// rt = loadAsRunTest("NestedTryBlocks");
359
// checkInstrumentation(rt);
360
// assertEquals ("NestedTryBlocks isn't working", 22, rt.runTest(7));
361
// } // END NESTED
362

363     /////////////////////////////////////////////////////////////////
364
// SERIOUS BUGS /////////////////////////////////////////////////
365

366 // // STATICINIT ///////////////////////////////////////////////////
367
// // XXX BUG java.lang.NullPointerException
368
// // at org.apache.bcel.generic.LineNumberGen
369
// // .getLineNumber(LineNumberGen.java:109)
370
// // at org.apache.bcel.generic.MethodGen
371
// // .getLineNumberTable(MethodGen.java:420)
372
// // at org.apache.bcel.generic.MethodGen.getMethod(MethodGen.java:599)
373
// public void testStaticInit() {
374
// RunTest
375
// rt = loadAsRunTest("StaticInit");
376
// checkInstrumentation(rt);
377
// assertEquals("StaticInit isn't working", 10, rt.runTest(7));
378
// } // END STATIC
379

380 // // TESTFINALLY //////////////////////////////////////////////////
381
// // XXX BUG Invalid start_pc/length in local var table BUG XXX
382
// public void testFinally() {
383
// RunTest
384
// rt = loadAsRunTest("Finally");
385
// checkInstrumentation(rt);
386

387 // // Finally.runTest(x) returns -1
388
// assertEquals ("Finally isn't working", -1, rt.runTest(11));
389
// assertEquals ("Finally isn't working", -1, rt.runTest(1));
390
// } // END FINALLY
391

392 // // TESTFINALLY2CATCHES //////////////////////////////////////////
393
// // XXX BUG Mismatched stack types BUG XXX
394
// public void testFinally2Catches() {
395
// RunTest
396
// rt = loadAsRunTest("Finally2Catches");
397
// checkInstrumentation(rt);
398

399 // // what Finally.runTest(x) returns is a bit complicated ...
400
// assertEquals ("Finally2Catches isn't working", 3600, rt.runTest(11));
401
// } // END
402

403 // // SWITCHLOAD
404
// // XXX BUG Falling off the end of the code BUG XXX
405
// public void testFinally2Catches() {
406
// RunTest
407
// rt = loadAsRunTest("SwitchLoad");
408
// checkInstrumentation(rt);
409
// // returns 42
410
// assertEquals ("SwitchLoad isn't working", 42, rt.runTest(7));
411
// } // END
412

413 // // WIMPLE ///////////////////////////////////////////////////////
414
// // XXX BUG java.lang.NullPointerException
415
// // at org.apache.bcel.generic.LineNumberGen
416
// // .getLineNumber(LineNumberGen.java:109)
417
// // at org.apache.bcel.generic.MethodGen
418
// // .getLineNumberTable(MethodGen.java:420)
419
// // at org.apache.bcel.generic.MethodGen.getMethod(MethodGen.java:599)
420
// public void testWimple() {
421
// RunTest
422
// rt = loadAsRunTest("Wimple");
423
// checkInstrumentation(rt);
424
// // returns ??
425
// assertEquals ("Wimple isn't working", 92, rt.runTest(7));
426
// } // END WIMPLE
427

428 }
429
Popular Tags