001    package edu.rice.cs.cunit.threadCheck.tests;
002    
003    import edu.rice.cs.cunit.FileInstrumentor;
004    import edu.rice.cs.cunit.classFile.ClassFile;
005    import edu.rice.cs.cunit.classFile.MethodInfo;
006    import edu.rice.cs.cunit.instrumentors.threadCheck.AddThreadCheckStrategy;
007    import edu.rice.cs.cunit.instrumentors.threadCheck.CompoundThreadCheckStrategy;
008    import edu.rice.cs.cunit.util.Debug;
009    import edu.rice.cs.cunit.util.ExecJVM;
010    import edu.rice.cs.cunit.util.FileOps;
011    import edu.rice.cs.cunit.util.StreamRedirectThread;
012    import edu.rice.cs.cunit.util.NullStream;
013    import junit.framework.TestCase;
014    
015    import java.io.*;
016    import java.util.ArrayList;
017    import java.util.List;
018    
019    /**
020     * Unit test for thread checker annotations and the AddPredicateThreadCheckStrategy.
021     * @author Mathias Ricken
022     */
023    public class ThreadPredicateCheckTest extends TestCase {
024        File _tempDir;
025        final String LS = System.getProperty("line.separator");
026        final String FS = System.getProperty("file.separator");
027        final String PS = System.getProperty("path.separator");
028    
029        public void setUp() throws Exception {
030            super.setUp();
031            _tempDir = FileOps.createTempDirectory("Predicate");
032            // _tempDir = new File(".", "tempDir"+FS+"Predicate");
033            _tempDir.mkdirs();
034            FileOps.copyFile(new File("classes"),_tempDir);
035        }
036    
037    
038        /**
039         * Tears down the fixture, for example, close a network connection. This method is called after a test is executed.
040         */
041        protected void tearDown() throws Exception {
042            FileOps.deleteDirectory(_tempDir);
043            FileOps.deleteDirectoryOnExit(_tempDir);
044            super.tearDown();
045        }
046    
047        public void testTCSample5() throws IOException {
048            File base = new File(_tempDir, "sample"+FS+"threadCheck"+FS+"predicate");
049            assertTrue(base.exists() && base.isDirectory());
050            //List<File> files = FileOps.enumFiles(base);
051            List<File> files = new ArrayList<File>();
052            File cfile = new File(base, "TCSample5.class");
053            assertTrue(cfile.exists() && cfile.isFile());
054            files.add(cfile);
055    
056            ArrayList<String> args = new ArrayList<String>();
057            args.add("-i");
058            args.add(CompoundThreadCheckStrategy.class.getName());
059            args.add("-X");
060    
061            StringBuilder sb = new StringBuilder();
062            sb.append(AddThreadCheckStrategy.CLASS_PATH_PARAM_PREFIX);
063            sb.append(_tempDir.getAbsolutePath());
064            sb.append(PS);
065            sb.append(System.getProperty("java.class.path"));
066            sb.append(PS);
067            sb.append(FileInstrumentor.getDefaultSourceRtJarName());
068            args.add(sb.toString());
069    
070            ArrayList<String> classPath = new ArrayList<String>();
071            for(String p: sb.toString().split(PS)) {
072                classPath.add(p);
073            }
074    
075            for(File f: files) {
076                args.add(f.getAbsolutePath());
077            }
078    
079    //        System.out.println("Parameters:");
080    //        for(String a: args) {
081    //            System.out.println("\t"+a);
082    //        }
083    
084            ByteArrayOutputStream baos = new ByteArrayOutputStream();
085            Debug.out.setOutput(new PrintStream(baos));
086            FileInstrumentor.main(args.toArray(new String[0]));
087            String output = baos.toString();
088    //        System.out.println(output);
089    
090            // check no IOExceptions
091            int ioExcIndex = output.indexOf("IOExceptions: 0");
092            if (ioExcIndex<0) {
093                ioExcIndex = output.indexOf("IOExceptions: ");
094                int newLineIndex = output.indexOf(System.getProperty("line.separator"), ioExcIndex);
095                fail(output.substring(ioExcIndex,newLineIndex));
096            }
097    
098            // check scanner results
099            String strScannerRes = "Scanner results: " + LS;
100            int sResultsIndex = output.indexOf(strScannerRes);
101            if (sResultsIndex<0) {
102                sResultsIndex = output.indexOf(strScannerRes);
103                fail(output.substring(sResultsIndex,ioExcIndex));
104            }
105            int nextLineIndex = output.indexOf(strScannerRes, sResultsIndex) + strScannerRes.length();
106            int nextLineEndIndex = output.indexOf(LS, nextLineIndex + 1);
107            String nextLine = output.substring(nextLineIndex, nextLineEndIndex);
108            if (!nextLine.equals("\tThreadChecker Bad Predicate Annotation Warning: Annotation "+
109                                 "sample.threadCheck.predicate.TCSample5$WrongAnnotation has meta-annotation "+
110                                 "@PredicateLink, but contains a member that is an annotation or an array of annotations: value"+
111                                 " (processing sample.threadCheck.predicate.TCSample5)")) {
112                fail("Expected 'Bad Predicate Annotation Warning' about WrongAnnotation, was '"+nextLine+"'");
113            }
114            if (!output.substring(nextLineEndIndex).startsWith(LS)) {
115                fail("Line separator expected after 'Bad Predicate Annotation Warning' about WrongAnnotation");
116            }
117            String remainderStr = output.substring(nextLineEndIndex+LS.length());
118            nextLineEndIndex = remainderStr.indexOf(LS);
119            nextLine = remainderStr.substring(0, nextLineEndIndex);
120            if (!nextLine.startsWith("\tThreadChecker Cache Info")) {
121                fail("Expected 'ThreadChecker Cache Info', was '"+nextLine+"'");
122            }
123            remainderStr = remainderStr.substring(nextLineEndIndex);
124            if (!remainderStr.startsWith(LS+LS+LS+"IOExceptions: 0"+LS)) {
125                fail("Expected '\n\n\nIOExceptions: 0\n', was '"+remainderStr+"'");
126            }
127    
128            File cfile_old = new File(base, "TCSample5.class~");
129            assertTrue(cfile.exists() && cfile.isFile());
130            assertTrue(cfile_old.exists() && cfile_old.isFile());
131    
132            FileInputStream fis = new FileInputStream(cfile);
133            ClassFile cf = new ClassFile(fis);
134            fis.close();
135            boolean foundInit = false, foundRun = false, foundError = false, foundRunObj = false;
136            boolean foundRunObj2 = false, foundRunIntString = false, foundMain = false;
137            for(MethodInfo mi: cf.getMethods()) {
138                if ((mi.getName().toString().equals("<init>")) &&
139                    (mi.getDescriptor().toString().equals("()V"))) {
140                    foundInit = true;
141    //                int[] found = new int[2];
142    //                InstructionList il = new InstructionList(mi.getCodeAttributeInfo().getCode());
143    //                int startIndex = getCtorStartIndex(il, cf, classPath);
144    //                ++found[1+checkNotRunByGroup(il, startIndex, cf, ".*ai.*", 1)];
145    //                assertEquals("Should not have had any misses", 0, found[0]);
146    //                for (int i=1; i<found.length; ++i) {
147    //                    assertEquals("Should have found segment "+i+" once", 1, found[i]);
148    //                }
149    //                il.setIndex(startIndex+found.length*2-1);
150    //                AInstruction instr = il.getInstr();
151    //                if (Opcode.INVOKESTATIC==instr.getOpcode()) {
152    //                    ReferenceInstruction refInstr = (ReferenceInstruction)instr;
153    //                    MethodPoolInfo mipi = (MethodPoolInfo)cf.getConstantPoolItem(refInstr.getReference());
154    //                    if (("edu/rice/cs/cunit/threadCheck/ThreadCheck".equals(mipi.getClassInfo().toString())) &&
155    //                        (mipi.getNameAndType().getName().toString().startsWith("checkCurrent")) &&
156    //                        (("(J)V".equals(mipi.getNameAndType().getDescriptor().toString())) ||
157    //                         ("(Ljava/lang/String;)V".equals(mipi.getNameAndType().getDescriptor().toString())))) {
158    //                        fail("Found more checks than expected");
159    //                    }
160    //                }
161    //                boolean res = il.advanceIndex();
162    //                assertTrue(res);
163                }
164                else if ((mi.getName().toString().equals("main")) &&
165                    (mi.getDescriptor().toString().equals("([Ljava/lang/String;)V"))) {
166                    foundMain = true;
167    //                int[] found = new int[4];
168    //                InstructionList il = new InstructionList(mi.getCodeAttributeInfo().getCode());
169    //                ++found[1+checkNotRunByName(il, cf, "fum", 3)];
170    //                ++found[1+checkNotRunByName(il, cf, "main", 3)];
171    //                ++found[1+checkNotRunByName(il, cf, "foo", 3)];
172    //                assertEquals("Should not have had any misses", 0, found[0]);
173    //                for (int i=1; i<found.length; ++i) {
174    //                    assertEquals("Should have found segment "+i+" once", 1, found[i]);
175    //                }
176    //                il.setIndex(found.length*2-1);
177    //                AInstruction instr = il.getInstr();
178    //                if (Opcode.INVOKESTATIC==instr.getOpcode()) {
179    //                    ReferenceInstruction refInstr = (ReferenceInstruction)instr;
180    //                    MethodPoolInfo mipi = (MethodPoolInfo)cf.getConstantPoolItem(refInstr.getReference());
181    //                    if (("edu/rice/cs/cunit/threadCheck/ThreadCheck".equals(mipi.getClassInfo().toString())) &&
182    //                        (mipi.getNameAndType().getName().toString().startsWith("checkCurrent")) &&
183    //                        (("(J)V".equals(mipi.getNameAndType().getDescriptor().toString())) ||
184    //                         ("(Ljava/lang/String;)V".equals(mipi.getNameAndType().getDescriptor().toString())))) {
185    //                        fail("Found more checks than expected");
186    //                    }
187    //                }
188    //                boolean res = il.advanceIndex();
189    //                assertTrue(res);
190                }
191                else if ((mi.getName().toString().equals("error")) &&
192                    (mi.getDescriptor().toString().equals("()V"))) {
193                    foundError = true;
194    //                InstructionList il = new InstructionList(mi.getCodeAttributeInfo().getCode());
195    //                int[] found = new int[4];
196    //                ++found[1+checkNotRunById(il, cf, 1, 3)];
197    //                ++found[1+checkNotRunByName(il, cf, "bar", 3)];
198    //                ++found[1+checkNotRunByName(il, cf, "foo", 3)];
199    //                assertEquals("Should not have had any misses", 0, found[0]);
200    //                for (int i=1; i<found.length; ++i) {
201    //                    assertEquals("Should have found segment "+i+" once", 1, found[i]);
202    //                }
203    //                il.setIndex(found.length*2-1);
204    //                AInstruction instr = il.getInstr();
205    //                if (Opcode.INVOKESTATIC==instr.getOpcode()) {
206    //                    ReferenceInstruction refInstr = (ReferenceInstruction)instr;
207    //                    MethodPoolInfo mipi = (MethodPoolInfo)cf.getConstantPoolItem(refInstr.getReference());
208    //                    if (("edu/rice/cs/cunit/threadCheck/ThreadCheck".equals(mipi.getClassInfo().toString())) &&
209    //                        (mipi.getNameAndType().getName().toString().startsWith("checkCurrent")) &&
210    //                        (("(J)V".equals(mipi.getNameAndType().getDescriptor().toString())) ||
211    //                         ("(Ljava/lang/String;)V".equals(mipi.getNameAndType().getDescriptor().toString())))) {
212    //                        fail("Found more checks than expected");
213    //                    }
214    //                }
215    //                boolean res = il.advanceIndex();
216    //                assertTrue(res);
217                }
218                else if ((mi.getName().toString().equals("run")) &&
219                    (mi.getDescriptor().toString().equals("()V"))) {
220                    foundRun = true;
221    //                InstructionList il = new InstructionList(mi.getCodeAttributeInfo().getCode());
222    //                int[] found = new int[4];
223    //                ++found[1+checkNotRunById(il, cf, 1, 3)];
224    //                ++found[1+checkNotRunByName(il, cf, "bar", 3)];
225    //                ++found[1+checkNotRunByName(il, cf, "foo", 3)];
226    //                assertEquals("Should not have had any misses", 0, found[0]);
227    //                for (int i=1; i<found.length; ++i) {
228    //                    assertEquals("Should have found segment "+i+" once", 1, found[i]);
229    //                }
230    //                il.setIndex(found.length*2-1);
231    //                AInstruction instr = il.getInstr();
232    //                if (Opcode.INVOKESTATIC==instr.getOpcode()) {
233    //                    ReferenceInstruction refInstr = (ReferenceInstruction)instr;
234    //                    MethodPoolInfo mipi = (MethodPoolInfo)cf.getConstantPoolItem(refInstr.getReference());
235    //                    if (("edu/rice/cs/cunit/threadCheck/ThreadCheck".equals(mipi.getClassInfo().toString())) &&
236    //                        (mipi.getNameAndType().getName().toString().startsWith("checkCurrent")) &&
237    //                        (("(J)V".equals(mipi.getNameAndType().getDescriptor().toString())) ||
238    //                         ("(Ljava/lang/String;)V".equals(mipi.getNameAndType().getDescriptor().toString())))) {
239    //                        fail("Found more checks than expected");
240    //                    }
241    //                }
242    //                boolean res = il.advanceIndex();
243    //                assertTrue(res);
244                }
245                else if ((mi.getName().toString().equals("runObj")) &&
246                    (mi.getDescriptor().toString().equals("()V"))) {
247                    foundRunObj = true;
248    //                InstructionList il = new InstructionList(mi.getCodeAttributeInfo().getCode());
249    //                int[] found = new int[4];
250    //                ++found[1+checkNotRunById(il, cf, 1, 3)];
251    //                ++found[1+checkNotRunByName(il, cf, "bar", 3)];
252    //                ++found[1+checkNotRunByName(il, cf, "foo", 3)];
253    //                assertEquals("Should not have had any misses", 0, found[0]);
254    //                for (int i=1; i<found.length; ++i) {
255    //                    assertEquals("Should have found segment "+i+" once", 1, found[i]);
256    //                }
257    //                il.setIndex(found.length*2-1);
258    //                AInstruction instr = il.getInstr();
259    //                if (Opcode.INVOKESTATIC==instr.getOpcode()) {
260    //                    ReferenceInstruction refInstr = (ReferenceInstruction)instr;
261    //                    MethodPoolInfo mipi = (MethodPoolInfo)cf.getConstantPoolItem(refInstr.getReference());
262    //                    if (("edu/rice/cs/cunit/threadCheck/ThreadCheck".equals(mipi.getClassInfo().toString())) &&
263    //                        (mipi.getNameAndType().getName().toString().startsWith("checkCurrent")) &&
264    //                        (("(J)V".equals(mipi.getNameAndType().getDescriptor().toString())) ||
265    //                         ("(Ljava/lang/String;)V".equals(mipi.getNameAndType().getDescriptor().toString())))) {
266    //                        fail("Found more checks than expected");
267    //                    }
268    //                }
269    //                boolean res = il.advanceIndex();
270    //                assertTrue(res);
271                }
272                else if ((mi.getName().toString().equals("runObj2")) &&
273                    (mi.getDescriptor().toString().equals("()V"))) {
274                    foundRunObj2 = true;
275    //                InstructionList il = new InstructionList(mi.getCodeAttributeInfo().getCode());
276    //                int[] found = new int[4];
277    //                ++found[1+checkNotRunById(il, cf, 1, 3)];
278    //                ++found[1+checkNotRunByName(il, cf, "bar", 3)];
279    //                ++found[1+checkNotRunByName(il, cf, "foo", 3)];
280    //                assertEquals("Should not have had any misses", 0, found[0]);
281    //                for (int i=1; i<found.length; ++i) {
282    //                    assertEquals("Should have found segment "+i+" once", 1, found[i]);
283    //                }
284    //                il.setIndex(found.length*2-1);
285    //                AInstruction instr = il.getInstr();
286    //                if (Opcode.INVOKESTATIC==instr.getOpcode()) {
287    //                    ReferenceInstruction refInstr = (ReferenceInstruction)instr;
288    //                    MethodPoolInfo mipi = (MethodPoolInfo)cf.getConstantPoolItem(refInstr.getReference());
289    //                    if (("edu/rice/cs/cunit/threadCheck/ThreadCheck".equals(mipi.getClassInfo().toString())) &&
290    //                        (mipi.getNameAndType().getName().toString().startsWith("checkCurrent")) &&
291    //                        (("(J)V".equals(mipi.getNameAndType().getDescriptor().toString())) ||
292    //                         ("(Ljava/lang/String;)V".equals(mipi.getNameAndType().getDescriptor().toString())))) {
293    //                        fail("Found more checks than expected");
294    //                    }
295    //                }
296    //                boolean res = il.advanceIndex();
297    //                assertTrue(res);
298                }
299                else if ((mi.getName().toString().equals("runIntString")) &&
300                    (mi.getDescriptor().toString().equals("()V"))) {
301                    foundRunIntString = true;
302    //                InstructionList il = new InstructionList(mi.getCodeAttributeInfo().getCode());
303    //                int[] found = new int[4];
304    //                ++found[1+checkNotRunById(il, cf, 1, 3)];
305    //                ++found[1+checkNotRunByName(il, cf, "bar", 3)];
306    //                ++found[1+checkNotRunByName(il, cf, "foo", 3)];
307    //                assertEquals("Should not have had any misses", 0, found[0]);
308    //                for (int i=1; i<found.length; ++i) {
309    //                    assertEquals("Should have found segment "+i+" once", 1, found[i]);
310    //                }
311    //                il.setIndex(found.length*2-1);
312    //                AInstruction instr = il.getInstr();
313    //                if (Opcode.INVOKESTATIC==instr.getOpcode()) {
314    //                    ReferenceInstruction refInstr = (ReferenceInstruction)instr;
315    //                    MethodPoolInfo mipi = (MethodPoolInfo)cf.getConstantPoolItem(refInstr.getReference());
316    //                    if (("edu/rice/cs/cunit/threadCheck/ThreadCheck".equals(mipi.getClassInfo().toString())) &&
317    //                        (mipi.getNameAndType().getName().toString().startsWith("checkCurrent")) &&
318    //                        (("(J)V".equals(mipi.getNameAndType().getDescriptor().toString())) ||
319    //                         ("(Ljava/lang/String;)V".equals(mipi.getNameAndType().getDescriptor().toString())))) {
320    //                        fail("Found more checks than expected");
321    //                    }
322    //                }
323    //                boolean res = il.advanceIndex();
324    //                assertTrue(res);
325                }
326            }
327    
328            assertTrue(foundInit);
329            assertTrue(foundRun);
330            assertTrue(foundError);
331            assertTrue(foundRunObj);
332            assertTrue(foundRunObj2);
333            assertTrue(foundRunIntString);
334            assertTrue(foundMain);
335    
336            String className = "sample.threadCheck.predicate.TCSample5";
337            ByteArrayOutputStream stdOutStream = new ByteArrayOutputStream();
338            Process p = runTestClass(className, stdOutStream, NullStream.ONLY);
339            String stdOut = stdOutStream.toString();
340    
341            File tcLog = new File(_tempDir, "threadCheck.log");
342            assertTrue(tcLog.exists() && tcLog.isFile());
343            fis = new FileInputStream(tcLog);
344            StringBuilder tcsb = new StringBuilder();
345            int x;
346            byte b[];
347            String s;
348            while((x = fis.available())>0) {
349                x = fis.available();
350                b = new byte[x];
351                fis.read(b);
352                s = new String(b);
353                tcsb.append(s);
354            }
355            fis.close();
356            String tc = tcsb.toString();
357    //        System.out.println(tc);
358    
359    //        assertTrue(0 <= tc.indexOf("Thread Name Violation: NotRunBy (2 check(s), 1 violation(s))"+LS+"\tCurrent thread 'main', id 1, group 'main'"));
360    //        assertTrue(0 <= tc.indexOf("Thread Group Name Violation: NotRunBy (4 check(s), 2 violation(s))"+LS+"\tCurrent thread 'main', id 1, group 'main'"));
361    //        assertTrue(0 <= tc.indexOf("Thread Id Violation: NotRunBy (5 check(s), 3 violation(s))"+LS+"\tCurrent thread 'main', id 1, group 'main'"));
362    
363            int count = 0, index = 0;
364            while((index=tc.indexOf("Violation:", index))>=0) { ++count; ++index; }
365    //        System.out.println("Violation count = "+count);
366            assertEquals(43, count);
367    
368    //        System.out.println("stdout = ");
369    //        System.out.println(stdOut);
370            
371            int mainPos = stdOut.indexOf("Main!"+LS);
372            assertTrue(0 <= mainPos);
373            int outPos = stdOut.indexOf("thisO = null, value:float = 2.72"+LS);
374            assertTrue(0 <= outPos);
375            assertTrue(mainPos > outPos);
376            outPos = stdOut.indexOf("thisO = null, value:long = 1073741824"+LS);
377            assertTrue(0 <= outPos);
378            assertTrue(mainPos > outPos);
379            outPos = stdOut.indexOf("thisO = null, value:long[] = [1073741824]"+LS);
380            assertTrue(0 <= outPos);
381            assertTrue(mainPos > outPos);
382            outPos = stdOut.indexOf("thisO = null, value:char = a"+LS);
383            assertTrue(0 <= outPos);
384            assertTrue(mainPos > outPos);
385            outPos = stdOut.indexOf("thisO = null, value:byte[] = [123, -128]"+LS);
386            assertTrue(0 <= outPos);
387            assertTrue(mainPos > outPos);
388            outPos = stdOut.indexOf("thisO = null, value:int[] = [42, 100, 200]"+LS);
389            assertTrue(0 <= outPos);
390            assertTrue(mainPos > outPos);
391            outPos = stdOut.indexOf("thisO = null, value:char[] = [a, b, c]"+LS);
392            assertTrue(0 <= outPos);
393            assertTrue(mainPos > outPos);
394            outPos = stdOut.indexOf("thisO = null, value:byte = 123"+LS);
395            assertTrue(0 <= outPos);
396            assertTrue(mainPos > outPos);
397            outPos = stdOut.indexOf("thisO = null, value:int = 42"+LS);
398            assertTrue(0 <= outPos);
399            assertTrue(mainPos > outPos);
400            outPos = stdOut.indexOf("thisO = null, value:double[] = [3.14]"+LS);
401            assertTrue(0 <= outPos);
402            assertTrue(mainPos > outPos);
403            outPos = stdOut.indexOf("thisO = null, value:short[] = [32000, -16000, 0]"+LS);
404            assertTrue(0 <= outPos);
405            assertTrue(mainPos > outPos);
406            outPos = stdOut.indexOf("thisO = null, value:boolean[] = [false, true, false, true, false]"+LS);
407            assertTrue(0 <= outPos);
408            assertTrue(mainPos > outPos);
409            outPos = stdOut.indexOf("thisO = null, value:short = 32000"+LS);
410            assertTrue(0 <= outPos);
411            assertTrue(mainPos > outPos);
412            outPos = stdOut.indexOf("thisO = null, value:double = 3.14"+LS);
413            assertTrue(0 <= outPos);
414            assertTrue(mainPos > outPos);
415            outPos = stdOut.indexOf("thisO = null, value:float[] = [2.72, 1.11, 2.22, 3.33]"+LS);
416            assertTrue(0 <= outPos);
417            assertTrue(mainPos > outPos);
418            outPos = stdOut.indexOf("thisO = null, value:boolean = true"+LS);
419            assertTrue(0 <= outPos);
420            assertTrue(mainPos > outPos);
421            
422            int runPos = stdOut.indexOf("Run!"+LS+"Error!"+LS);
423            assertTrue(runPos > mainPos);
424            String prefix = "thisO = sample.threadCheck.predicate.TCSample5@";
425            int prefixPos = stdOut.indexOf(prefix);
426            assertTrue(0 <= prefixPos);
427            assertTrue(prefixPos > mainPos);
428            assertTrue(prefixPos < runPos);
429            String number = stdOut.substring(prefixPos+prefix.length(), stdOut.indexOf(",", prefixPos));
430    //        System.out.println("Number = '"+number+"'");
431            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:long = 1073741824"+LS);
432            assertTrue(0 <= outPos);
433            assertTrue(runPos > outPos);
434            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:char[] = []"+LS);
435            assertTrue(0 <= outPos);
436            assertTrue(runPos > outPos);
437            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:float[] = []"+LS);
438            assertTrue(0 <= outPos);
439            assertTrue(runPos > outPos);
440            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:double[] = []"+LS);
441            assertTrue(0 <= outPos);
442            assertTrue(runPos > outPos);
443            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:char = a"+LS);
444            assertTrue(0 <= outPos);
445            assertTrue(runPos > outPos);
446            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:int[] = []"+LS);
447            assertTrue(0 <= outPos);
448            assertTrue(runPos > outPos);
449            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:long[] = []"+LS);
450            assertTrue(0 <= outPos);
451            assertTrue(runPos > outPos);
452            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:short[] = []"+LS);
453            assertTrue(0 <= outPos);
454            assertTrue(runPos > outPos);
455            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:byte = 123"+LS);
456            assertTrue(0 <= outPos);
457            assertTrue(runPos > outPos);
458            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:boolean = true"+LS);
459            assertTrue(0 <= outPos);
460            assertTrue(runPos > outPos);
461            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:boolean[] = []"+LS);
462            assertTrue(0 <= outPos);
463            assertTrue(runPos > outPos);
464            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:short = 32000"+LS);
465            assertTrue(0 <= outPos);
466            assertTrue(runPos > outPos);
467            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:float = 2.72"+LS);
468            assertTrue(0 <= outPos);
469            assertTrue(runPos > outPos);
470            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:double = 3.14"+LS);
471            assertTrue(0 <= outPos);
472            assertTrue(runPos > outPos);
473            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:byte[] = []"+LS);
474            assertTrue(0 <= outPos);
475            assertTrue(runPos > outPos);
476            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:int = 42"+LS);
477            assertTrue(0 <= outPos);
478            assertTrue(runPos > outPos);
479                            
480            int runObjPos = stdOut.indexOf("Run Obj!"+LS);
481            assertTrue(0 <=runObjPos);
482            assertTrue(runObjPos > runPos);
483            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:enum[] = []"+LS);
484            assertTrue(0 <= outPos);
485            assertTrue(runObjPos > outPos);
486            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:String = foo"+LS);
487            assertTrue(0 <= outPos);
488            assertTrue(runObjPos > outPos);
489            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:Class = class java.lang.String"+LS);
490            assertTrue(0 <= outPos);
491            assertTrue(runObjPos > outPos);
492            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:enum = NOT"+LS);
493            assertTrue(0 <= outPos);
494            assertTrue(runObjPos > outPos);
495            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:Class[] = [class java.lang.Object, class java.lang.Integer]"+LS);
496            assertTrue(0 <= outPos);
497            assertTrue(runObjPos > outPos);
498            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:String[] = [xxx, yyy, zzz]"+LS);
499            assertTrue(0 <= outPos);
500            assertTrue(runObjPos > outPos);
501            
502            int runObj2Pos = stdOut.indexOf("Run Obj 2!"+LS);
503            assertTrue(0 <= runObj2Pos);
504            assertTrue(runObj2Pos > runObjPos);
505            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:String[] = []"+LS);
506            assertTrue(0 <= outPos);
507            assertTrue(runObj2Pos > outPos);
508            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:enum[] = []"+LS);
509            assertTrue(0 <= outPos);
510            assertTrue(runObj2Pos > outPos);
511            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", value:Class[] = []"+LS);
512            assertTrue(0 <= outPos);
513            assertTrue(runObj2Pos > outPos);
514            
515            int runISPos = stdOut.indexOf("Run Int String!"+LS);
516            assertTrue(0 <= runISPos);
517            assertTrue(runISPos > runObj2Pos);
518            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", i:int = 123, s:String = abc"+LS);
519            assertTrue(0 <= outPos);
520            assertTrue(runISPos > outPos);
521            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample5@"+number+", i:int = 456, s:String = xyz"+LS);
522            assertTrue(0 <= outPos);
523            assertTrue(runISPos > outPos);
524                
525            assertEquals(0, p.exitValue());
526        }
527    
528        public void testTCSample7() throws IOException {
529            File base = new File(_tempDir, "sample"+FS+"threadCheck"+FS+"predicate");
530            assertTrue(base.exists() && base.isDirectory());
531            //List<File> files = FileOps.enumFiles(base);
532            List<File> files = new ArrayList<File>();
533            File cfile = new File(base, "TCSample7.class");
534            assertTrue(cfile.exists() && cfile.isFile());
535            files.add(cfile);
536    
537            ArrayList<String> args = new ArrayList<String>();
538            args.add("-i");
539            args.add(CompoundThreadCheckStrategy.class.getName());
540            args.add("-X");
541    
542            StringBuilder sb = new StringBuilder();
543            sb.append(AddThreadCheckStrategy.CLASS_PATH_PARAM_PREFIX);
544            sb.append(_tempDir.getAbsolutePath());
545            sb.append(PS);
546            sb.append(System.getProperty("java.class.path"));
547            sb.append(PS);
548            sb.append(FileInstrumentor.getDefaultSourceRtJarName());
549            args.add(sb.toString());
550    
551            ArrayList<String> classPath = new ArrayList<String>();
552            for(String p: sb.toString().split(PS)) {
553                classPath.add(p);
554            }
555    
556            for(File f: files) {
557                args.add(f.getAbsolutePath());
558            }
559    
560    //        System.out.println("Parameters:");
561    //        for(String a: args) {
562    //            System.out.println("\t"+a);
563    //        }
564    
565            ByteArrayOutputStream baos = new ByteArrayOutputStream();
566            Debug.out.setOutput(new PrintStream(baos));
567            FileInstrumentor.main(args.toArray(new String[0]));
568            String output = baos.toString();
569    //        System.out.println(output);
570    
571            // check no IOExceptions
572            int ioExcIndex = output.indexOf("IOExceptions: 0");
573            if (ioExcIndex<0) {
574                ioExcIndex = output.indexOf("IOExceptions: ");
575                int newLineIndex = output.indexOf(System.getProperty("line.separator"), ioExcIndex);
576                fail(output.substring(ioExcIndex,newLineIndex));
577            }
578    
579            // check scanner results
580            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$OKPublicStaticPredicate$WrongPublicStaticPrivateStaticPredicate is not accessible from everywhere")>=0);
581            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$OKPublicStaticPredicate$WrongPublicStaticProtectedStaticPredicate is not accessible from everywhere")>=0);
582            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$OKPublicStaticPredicate$WrongPublicStaticStaticPredicate is not accessible from everywhere")>=0);
583            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$WrongPrivateStaticPredicate is not accessible from everywhere")>=0);
584            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$WrongPrivateStaticPredicate$WrongPrivateStaticPrivateStaticPredicate is not accessible from everywhere")>=0);
585            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$WrongPrivateStaticPredicate$WrongPrivateStaticProtectedStaticPredicate is not accessible from everywhere")>=0);
586            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$WrongPrivateStaticPredicate$WrongPrivateStaticPublicStaticPredicate is not accessible from everywhere")>=0);
587            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$WrongPrivateStaticPredicate$WrongPrivateStaticStaticPredicate is not accessible from everywhere")>=0);
588            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$WrongProtectedStaticPredicate is not accessible from everywhere")>=0);
589            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$WrongProtectedStaticPredicate$WrongProtectedStaticPrivateStaticPredicate is not accessible from everywhere")>=0);
590            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$WrongProtectedStaticPredicate$WrongProtectedStaticProtectedStaticPredicate is not accessible from everywhere")>=0);
591            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$WrongProtectedStaticPredicate$WrongProtectedStaticPublicStaticPredicate is not accessible from everywhere")>=0);
592            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$WrongProtectedStaticPredicate$WrongProtectedStaticStaticPredicate is not accessible from everywhere")>=0);
593            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.WrongPackageProtectedPredicate is not accessible from everywhere")>=0);
594            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$OKPublicStaticPredicate$OKPublicStaticPublicStaticAnnotation is not accessible from everywhere")<0);
595            assertTrue(output.indexOf("ThreadChecker Bad Predicate Annotation Warning: Predicate method class sample.threadCheck.predicate.TCSample7$OKPublicStaticPredicate is not accessible from everywhere")<0);
596    
597            String strScannerRes = "Scanner results: " + LS;
598            int sResultsIndex = output.indexOf(strScannerRes);
599            if (sResultsIndex<0) {
600                sResultsIndex = output.indexOf(strScannerRes);
601                fail(output.substring(sResultsIndex,ioExcIndex));
602            }
603            String remainderStr = output.substring(sResultsIndex+strScannerRes.length());
604            int nextLineEndIndex;
605            String nextLine;
606            for(int i=0; i<14; ++i) {
607                nextLineEndIndex = remainderStr.indexOf(LS);
608                nextLine = remainderStr.substring(0,nextLineEndIndex+LS.length());
609                if (!nextLine.startsWith("\tThreadChecker Bad Predicate Annotation Warning:")) {
610                    fail("Expected 'Bad Predicate Annotation Warning', was '"+nextLine+"'");
611                }
612                if (!remainderStr.substring(nextLineEndIndex).startsWith(LS)) {
613                    fail("Line separator expected after 'Bad Predicate Annotation Warning'");
614                }
615                remainderStr = remainderStr.substring(nextLineEndIndex+LS.length());
616            }
617    
618            nextLineEndIndex = remainderStr.indexOf(LS);
619            nextLine = remainderStr.substring(0,nextLineEndIndex+LS.length());
620            if (!nextLine.startsWith("\tThreadChecker Cache Info:")) {
621                fail("Expected 'ThreadChecker Cache Info', was '"+nextLine+"'");
622            }
623            if (!remainderStr.substring(nextLineEndIndex).startsWith(LS)) {
624                fail("Line separator expected after 'ThreadChecker Cache Info'");
625            }
626            remainderStr = remainderStr.substring(nextLineEndIndex+LS.length());
627    
628            if (!remainderStr.startsWith(LS+LS+"IOExceptions: 0"+LS)) {
629                fail("Expected '\n\nIOExceptions: 0\n', was '"+remainderStr+"'");
630            }
631    
632            File cfile_old = new File(base, "TCSample7.class~");
633            assertTrue(cfile.exists() && cfile.isFile());
634            assertTrue(cfile_old.exists() && cfile_old.isFile());
635    
636            FileInputStream fis = new FileInputStream(cfile);
637            ClassFile cf = new ClassFile(fis);
638            fis.close();
639            boolean foundInit = false, foundMain = false;
640            for(MethodInfo mi: cf.getMethods()) {
641                if ((mi.getName().toString().equals("<init>")) &&
642                    (mi.getDescriptor().toString().equals("()V"))) {
643                    foundInit = true;
644    //                int[] found = new int[2];
645    //                InstructionList il = new InstructionList(mi.getCodeAttributeInfo().getCode());
646    //                int startIndex = getCtorStartIndex(il, cf, classPath);
647    //                ++found[1+checkNotRunByGroup(il, startIndex, cf, ".*ai.*", 1)];
648    //                assertEquals("Should not have had any misses", 0, found[0]);
649    //                for (int i=1; i<found.length; ++i) {
650    //                    assertEquals("Should have found segment "+i+" once", 1, found[i]);
651    //                }
652    //                il.setIndex(startIndex+found.length*2-1);
653    //                AInstruction instr = il.getInstr();
654    //                if (Opcode.INVOKESTATIC==instr.getOpcode()) {
655    //                    ReferenceInstruction refInstr = (ReferenceInstruction)instr;
656    //                    MethodPoolInfo mipi = (MethodPoolInfo)cf.getConstantPoolItem(refInstr.getReference());
657    //                    if (("edu/rice/cs/cunit/threadCheck/ThreadCheck".equals(mipi.getClassInfo().toString())) &&
658    //                        (mipi.getNameAndType().getName().toString().startsWith("checkCurrent")) &&
659    //                        (("(J)V".equals(mipi.getNameAndType().getDescriptor().toString())) ||
660    //                         ("(Ljava/lang/String;)V".equals(mipi.getNameAndType().getDescriptor().toString())))) {
661    //                        fail("Found more checks than expected");
662    //                    }
663    //                }
664    //                boolean res = il.advanceIndex();
665    //                assertTrue(res);
666                }
667                else if ((mi.getName().toString().equals("main")) &&
668                    (mi.getDescriptor().toString().equals("([Ljava/lang/String;)V"))) {
669                    foundMain = true;
670    //                int[] found = new int[4];
671    //                InstructionList il = new InstructionList(mi.getCodeAttributeInfo().getCode());
672    //                ++found[1+checkNotRunByName(il, cf, "fum", 3)];
673    //                ++found[1+checkNotRunByName(il, cf, "main", 3)];
674    //                ++found[1+checkNotRunByName(il, cf, "foo", 3)];
675    //                assertEquals("Should not have had any misses", 0, found[0]);
676    //                for (int i=1; i<found.length; ++i) {
677    //                    assertEquals("Should have found segment "+i+" once", 1, found[i]);
678    //                }
679    //                il.setIndex(found.length*2-1);
680    //                AInstruction instr = il.getInstr();
681    //                if (Opcode.INVOKESTATIC==instr.getOpcode()) {
682    //                    ReferenceInstruction refInstr = (ReferenceInstruction)instr;
683    //                    MethodPoolInfo mipi = (MethodPoolInfo)cf.getConstantPoolItem(refInstr.getReference());
684    //                    if (("edu/rice/cs/cunit/threadCheck/ThreadCheck".equals(mipi.getClassInfo().toString())) &&
685    //                        (mipi.getNameAndType().getName().toString().startsWith("checkCurrent")) &&
686    //                        (("(J)V".equals(mipi.getNameAndType().getDescriptor().toString())) ||
687    //                         ("(Ljava/lang/String;)V".equals(mipi.getNameAndType().getDescriptor().toString())))) {
688    //                        fail("Found more checks than expected");
689    //                    }
690    //                }
691    //                boolean res = il.advanceIndex();
692    //                assertTrue(res);
693                }
694            }
695    
696            assertTrue(foundInit);
697            assertTrue(foundMain);
698    
699            String className = "sample.threadCheck.predicate.TCSample7";
700            ByteArrayOutputStream stdOutStream = new ByteArrayOutputStream();
701            Process p = runTestClass(className, stdOutStream, NullStream.ONLY);
702            String stdOut = stdOutStream.toString();
703    
704            File tcLog = new File(_tempDir, "threadCheck.log");
705            assertTrue(tcLog.exists() && tcLog.isFile());
706            fis = new FileInputStream(tcLog);
707            StringBuilder tcsb = new StringBuilder();
708            int x;
709            byte b[];
710            String s;
711            while((x = fis.available())>0) {
712                x = fis.available();
713                b = new byte[x];
714                fis.read(b);
715                s = new String(b);
716                tcsb.append(s);
717            }
718            fis.close();
719            String tc = tcsb.toString();
720    //        System.out.println(tc);
721    
722    //        assertTrue(0 <= tc.indexOf("Thread Name Violation: NotRunBy (2 check(s), 1 violation(s))"+LS+"\tCurrent thread 'main', id 1, group 'main'"));
723    //        assertTrue(0 <= tc.indexOf("Thread Group Name Violation: NotRunBy (4 check(s), 2 violation(s))"+LS+"\tCurrent thread 'main', id 1, group 'main'"));
724    //        assertTrue(0 <= tc.indexOf("Thread Id Violation: NotRunBy (5 check(s), 3 violation(s))"+LS+"\tCurrent thread 'main', id 1, group 'main'"));
725    
726            int count = 0, index = 0;
727            while((index=tc.indexOf("Violation:", index))>=0) { ++count; ++index; }
728    //        System.out.println("Violation count = "+count);
729            assertEquals(16, count);
730    
731    //        System.out.println("stdout = ");
732    //        System.out.println(stdOut);
733    
734            int mainPos = stdOut.indexOf("main!"+LS);
735            assertTrue(0 <= mainPos);
736            int outPos = stdOut.indexOf("WrongPrivateStaticPrivateStaticAnnotation: thisO = null"+LS);
737            assertTrue(0 <= outPos);
738            assertTrue(mainPos > outPos);
739            outPos = stdOut.indexOf("OKPublicStaticPublicStaticAnnotation: thisO = null"+LS);
740            assertTrue(0 <= outPos);
741            assertTrue(mainPos > outPos);
742            outPos = stdOut.indexOf("OKPublicStaticPredicate: thisO = null"+LS);
743            assertTrue(0 <= outPos);
744            assertTrue(mainPos > outPos);
745            outPos = stdOut.indexOf("WrongPrivateStaticProtectedStaticAnnotation: thisO = null"+LS);
746            assertTrue(0 <= outPos);
747            assertTrue(mainPos > outPos);
748            outPos = stdOut.indexOf("WrongPublicStaticStaticAnnotation: thisO = null"+LS);
749            assertTrue(0 <= outPos);
750            assertTrue(mainPos > outPos);
751            outPos = stdOut.indexOf("WrongPackageProtectedPredicate: thisO = null"+LS);
752            assertTrue(0 <= outPos);
753            assertTrue(mainPos > outPos);
754            outPos = stdOut.indexOf("WrongPublicStaticProtectedStaticAnnotation: thisO = null"+LS);
755            assertTrue(0 <= outPos);
756            assertTrue(mainPos > outPos);
757            outPos = stdOut.indexOf("WrongProtectedStaticPredicate: thisO = null"+LS);
758            assertTrue(0 <= outPos);
759            assertTrue(mainPos > outPos);
760            outPos = stdOut.indexOf("WrongPrivateStaticPublicStaticAnnotation: thisO = null"+LS);
761            assertTrue(0 <= outPos);
762            assertTrue(mainPos > outPos);
763            outPos = stdOut.indexOf("WrongProtectedStaticStaticAnnotation: thisO = null"+LS);
764            assertTrue(0 <= outPos);
765            assertTrue(mainPos > outPos);
766            outPos = stdOut.indexOf("WrongPrivateStaticStaticAnnotation: thisO = null"+LS);
767            assertTrue(0 <= outPos);
768            assertTrue(mainPos > outPos);
769            outPos = stdOut.indexOf("WrongPublicStaticPrivateStaticAnnotation: thisO = null"+LS);
770            assertTrue(0 <= outPos);
771            assertTrue(mainPos > outPos);
772            outPos = stdOut.indexOf("WrongProtectedStaticPublicStaticAnnotation: thisO = null"+LS);
773            assertTrue(0 <= outPos);
774            assertTrue(mainPos > outPos);
775            outPos = stdOut.indexOf("WrongProtectedStaticPrivateStaticAnnotation: thisO = null"+LS);
776            assertTrue(0 <= outPos);
777            assertTrue(mainPos > outPos);
778            outPos = stdOut.indexOf("WrongProtectedStaticProtectedStaticAnnotation: thisO = null"+LS);
779            assertTrue(0 <= outPos);
780            assertTrue(mainPos > outPos);
781            outPos = stdOut.indexOf("WrongPrivateStaticPredicate: thisO = null"+LS);
782            assertTrue(0 <= outPos);
783            assertTrue(mainPos > outPos);
784    
785            assertEquals(0, p.exitValue());
786        }
787    
788        public void testTCSample4() throws IOException {
789            File base = new File(_tempDir, "sample"+FS+"threadCheck"+FS+"predicate");
790            assertTrue(base.exists() && base.isDirectory());
791            //List<File> files = FileOps.enumFiles(base);
792            List<File> files = new ArrayList<File>();
793            File cfile = new File(base, "TCSample4.class");
794            assertTrue(cfile.exists() && cfile.isFile());
795            files.add(cfile);
796    
797            ArrayList<String> args = new ArrayList<String>();
798            args.add("-i");
799            args.add(CompoundThreadCheckStrategy.class.getName());
800            args.add("-X");
801    
802            StringBuilder sb = new StringBuilder();
803            sb.append(AddThreadCheckStrategy.CLASS_PATH_PARAM_PREFIX);
804            sb.append(_tempDir.getAbsolutePath());
805            sb.append(PS);
806            sb.append(System.getProperty("java.class.path"));
807            sb.append(PS);
808            sb.append(FileInstrumentor.getDefaultSourceRtJarName());
809            args.add(sb.toString());
810    
811            ArrayList<String> classPath = new ArrayList<String>();
812            for(String p: sb.toString().split(PS)) {
813                classPath.add(p);
814            }
815    
816            for(File f: files) {
817                args.add(f.getAbsolutePath());
818            }
819    
820    //        System.out.println("Parameters:");
821    //        for(String a: args) {
822    //            System.out.println("\t"+a);
823    //        }
824    
825            ByteArrayOutputStream baos = new ByteArrayOutputStream();
826            Debug.out.setOutput(new PrintStream(baos));
827            FileInstrumentor.main(args.toArray(new String[0]));
828            String output = baos.toString();
829            // System.out.println(output);
830    
831            // check no IOExceptions
832            int ioExcIndex = output.indexOf("IOExceptions: 0");
833            if (ioExcIndex<0) {
834                ioExcIndex = output.indexOf("IOExceptions: ");
835                int newLineIndex = output.indexOf(System.getProperty("line.separator"), ioExcIndex);
836                fail(output.substring(ioExcIndex,newLineIndex));
837            }
838    
839            // check scanner results
840            String strScannerRes = "Scanner results: " + LS;
841            int sResultsIndex = output.indexOf(strScannerRes);
842            if (sResultsIndex<0) {
843                sResultsIndex = output.indexOf(strScannerRes);
844                fail(output.substring(sResultsIndex,ioExcIndex));
845            }
846            int nextLineIndex = output.indexOf(strScannerRes, sResultsIndex) + strScannerRes.length();
847            int nextLineEndIndex = output.indexOf(LS, nextLineIndex + 1);
848            String nextLine = output.substring(nextLineIndex, nextLineEndIndex);
849            if (!nextLine.equals("\tThreadChecker Bad Predicate Annotation Warning: Annotation sample.threadCheck."
850                                 + "predicate.ErroneousCombine has meta-annotation @Combine, but contains a member "
851                                 + "that is not a Thread Checker annotation or an array thereof: value "
852                                 + "(processing sample.threadCheck.predicate.TCSample4)")) {
853                fail("Expected 'Bad Predicate Annotation Warning' about ErroneousCombine, was '"+nextLine+"'");
854            }
855            if (!output.substring(nextLineEndIndex).startsWith(LS)) {
856                fail("Line separator expected after 'Bad Predicate Annotation Warning' about ErroneousCombine");
857            }
858            String remainderStr = output.substring(nextLineEndIndex+LS.length());
859            nextLineEndIndex = remainderStr.indexOf(LS);
860            nextLine = remainderStr.substring(0, nextLineEndIndex);
861            if (!nextLine.equals("\tThreadChecker Bad Predicate Annotation Warning: java.lang.String is not an "
862                                 +"annotation  (processing sample.threadCheck.predicate.TCSample4)")) {
863                fail("Expected 'Bad Predicate Annotation Warning' about String, was '"+nextLine+"'");
864            }
865            if (!remainderStr.substring(nextLineEndIndex).startsWith(LS)) {
866                fail("Line separator expected after 'Bad Predicate Annotation Warning' about String");
867            }
868            remainderStr = remainderStr.substring(nextLineEndIndex+LS.length());
869            nextLineEndIndex = remainderStr.indexOf(LS);
870            nextLine = remainderStr.substring(0, nextLineEndIndex);
871            if (!nextLine.startsWith("\tThreadChecker Cache Info")) {
872                fail("Expected 'ThreadChecker Cache Info', was '"+nextLine+"'");
873            }
874            remainderStr = remainderStr.substring(nextLineEndIndex);
875            if (!remainderStr.startsWith(LS+LS+LS+"IOExceptions: 0"+LS)) {
876                fail("Expected '\n\n\nIOExceptions: 0\n', was '"+remainderStr+"'");
877            }
878    
879            File cfile_old = new File(base, "TCSample4.class~");
880            assertTrue(cfile.exists() && cfile.isFile());
881            assertTrue(cfile_old.exists() && cfile_old.isFile());
882    
883            String className = "sample.threadCheck.predicate.TCSample4";
884            ByteArrayOutputStream stdOutStream = new ByteArrayOutputStream();
885            Process p = runTestClass(className, stdOutStream, NullStream.ONLY);
886            String stdOut = stdOutStream.toString();
887            // System.out.println(stdOut);
888    
889            File tcLog = new File(_tempDir, "threadCheck.log");
890            assertTrue(tcLog.exists() && tcLog.isFile());
891            FileInputStream fis = new FileInputStream(tcLog);
892            StringBuilder tcsb = new StringBuilder();
893            int x;
894            byte b[];
895            String s;
896            while((x = fis.available())>0) {
897                x = fis.available();
898                b = new byte[x];
899                fis.read(b);
900                s = new String(b);
901                tcsb.append(s);
902            }
903            fis.close();
904            String tc = tcsb.toString();
905    //        System.out.println(tc);
906    
907            int count = 0, index = 0;
908            while((index=tc.indexOf("Violation:", index))>=0) { ++count; ++index; }
909    //        System.out.println("Violation count = "+count);
910            assertEquals(57, count);
911    
912    //        System.out.println("stdout = ");
913    //        System.out.println(stdOut);
914    
915            int prevPos = stdOut.indexOf("testAnnArrayx_x_x_x!"+LS+
916                                         "testAnnArrayx_x_0_0!"+LS+
917                                         "testAnnArray0_0_x_x!"+LS);
918            assertTrue(0 <= prevPos);
919            String prefix = "thisO = sample.threadCheck.predicate.TCSample4@";
920            int prefixPos = stdOut.indexOf(prefix);
921            assertTrue(0 <= prefixPos);
922            assertTrue(prefixPos > prevPos);
923            String number = stdOut.substring(prefixPos+prefix.length(), stdOut.indexOf(",", prefixPos));
924            int outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_0_0_1a"+LS);
925            assertTrue(0 <= outPos);
926            assertTrue(prevPos < outPos);
927    
928            int newPos = stdOut.indexOf("testAnnArrayx_x_0_1!"+LS);
929            assertTrue(newPos > prevPos);
930            prevPos = newPos;
931            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_1a_0"+LS);
932            assertTrue(0 <= outPos);
933            assertTrue(prevPos < outPos);
934    
935            newPos = stdOut.indexOf("testAnnArrayx_x_1_0!"+LS);
936            assertTrue(newPos > prevPos);
937            prevPos = newPos;
938            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_1_1a"+LS);
939            assertTrue(0 <= outPos);
940            assertTrue(prevPos < outPos);
941            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_1a_1"+LS);
942            assertTrue(0 <= outPos);
943            assertTrue(prevPos < outPos);
944    
945            newPos = stdOut.indexOf("testAnnArrayx_x_1_1!"+LS);
946            assertTrue(newPos > prevPos);
947            prevPos = newPos;
948            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_0_2b"+LS);
949            assertTrue(0 <= outPos);
950            assertTrue(prevPos < outPos);
951            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_0_2a"+LS);
952            assertTrue(0 <= outPos);
953            assertTrue(prevPos < outPos);
954    
955            newPos = stdOut.indexOf("testAnnArrayx_x_0_2!"+LS);
956            assertTrue(newPos > prevPos);
957            prevPos = newPos;
958            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_2b_0"+LS);
959            assertTrue(0 <= outPos);
960            assertTrue(prevPos < outPos);
961            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_2a_0"+LS);
962            assertTrue(0 <= outPos);
963            assertTrue(prevPos < outPos);
964    
965            newPos = stdOut.indexOf("testAnnArrayx_x_2_0!"+LS);
966            assertTrue(newPos > prevPos);
967            prevPos = newPos;
968            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_1_2b"+LS);
969            assertTrue(0 <= outPos);
970            assertTrue(prevPos < outPos);
971            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_1_2a"+LS);
972            assertTrue(0 <= outPos);
973            assertTrue(prevPos < outPos);
974            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_1a_2"+LS);
975            assertTrue(0 <= outPos);
976            assertTrue(prevPos < outPos);
977    
978            newPos = stdOut.indexOf("testAnnArrayx_x_1_2!"+LS);
979            assertTrue(newPos > prevPos);
980            prevPos = newPos;
981            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_2_1a"+LS);
982            assertTrue(0 <= outPos);
983            assertTrue(prevPos < outPos);
984            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_2a_1"+LS);
985            assertTrue(0 <= outPos);
986            assertTrue(prevPos < outPos);
987            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_2b_1"+LS);
988            assertTrue(0 <= outPos);
989            assertTrue(prevPos < outPos);
990    
991            newPos = stdOut.indexOf("testAnnArrayx_x_2_1!"+LS);
992            assertTrue(newPos > prevPos);
993            prevPos = newPos;
994            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_2_2a"+LS);
995            assertTrue(0 <= outPos);
996            assertTrue(prevPos < outPos);
997            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_2_2b"+LS);
998            assertTrue(0 <= outPos);
999            assertTrue(prevPos < outPos);
1000            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_2a_2"+LS);
1001            assertTrue(0 <= outPos);
1002            assertTrue(prevPos < outPos);
1003            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = x_x_2b_2"+LS);
1004            assertTrue(0 <= outPos);
1005            assertTrue(prevPos < outPos);
1006    
1007            newPos = stdOut.indexOf("testAnnArrayx_x_2_2!"+LS);
1008            assertTrue(newPos > prevPos);
1009            prevPos = newPos;
1010            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1a_0_1"+LS);
1011            assertTrue(0 <= outPos);
1012            assertTrue(prevPos < outPos);
1013            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_0_1a"+LS);
1014            assertTrue(0 <= outPos);
1015            assertTrue(prevPos < outPos);
1016    
1017            newPos = stdOut.indexOf("testAnnArray0_1_0_1!"+LS);
1018            assertTrue(newPos > prevPos);
1019            prevPos = newPos;
1020            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1a_1_0"+LS);
1021            assertTrue(0 <= outPos);
1022            assertTrue(prevPos < outPos);
1023            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_1a_0"+LS);
1024            assertTrue(0 <= outPos);
1025            assertTrue(prevPos < outPos);
1026    
1027            newPos = stdOut.indexOf("testAnnArray0_1_1_0!"+LS);
1028            assertTrue(newPos > prevPos);
1029            prevPos = newPos;
1030            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1a_1_1"+LS);
1031            assertTrue(0 <= outPos);
1032            assertTrue(prevPos < outPos);
1033            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_1_1a"+LS);
1034            assertTrue(0 <= outPos);
1035            assertTrue(prevPos < outPos);
1036            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_1a_1"+LS);
1037            assertTrue(0 <= outPos);
1038            assertTrue(prevPos < outPos);
1039    
1040            newPos = stdOut.indexOf("testAnnArray0_1_1_1!"+LS);
1041            assertTrue(newPos > prevPos);
1042            prevPos = newPos;
1043            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1a_0_2"+LS);
1044            assertTrue(0 <= outPos);
1045            assertTrue(prevPos < outPos);
1046            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_0_2a"+LS);
1047            assertTrue(0 <= outPos);
1048            assertTrue(prevPos < outPos);
1049            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_0_2b"+LS);
1050            assertTrue(0 <= outPos);
1051            assertTrue(prevPos < outPos);
1052    
1053            newPos = stdOut.indexOf("testAnnArray0_1_0_2!"+LS);
1054            assertTrue(newPos > prevPos);
1055            prevPos = newPos;
1056            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1a_2_0"+LS);
1057            assertTrue(0 <= outPos);
1058            assertTrue(prevPos < outPos);
1059            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_2a_0"+LS);
1060            assertTrue(0 <= outPos);
1061            assertTrue(prevPos < outPos);
1062            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_2b_0"+LS);
1063            assertTrue(0 <= outPos);
1064            assertTrue(prevPos < outPos);
1065            
1066            newPos = stdOut.indexOf("testAnnArray0_1_2_0!"+LS);
1067            assertTrue(newPos > prevPos);
1068            prevPos = newPos;
1069            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1a_1_2"+LS);
1070            assertTrue(0 <= outPos);
1071            assertTrue(prevPos < outPos);
1072            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_1_2b"+LS);
1073            assertTrue(0 <= outPos);
1074            assertTrue(prevPos < outPos);
1075            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_1_2a"+LS);
1076            assertTrue(0 <= outPos);
1077            assertTrue(prevPos < outPos);
1078            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_1a_2"+LS);
1079            assertTrue(0 <= outPos);
1080            assertTrue(prevPos < outPos);
1081    
1082            newPos = stdOut.indexOf("testAnnArray0_1_1_2!"+LS);
1083            assertTrue(newPos > prevPos);
1084            prevPos = newPos;
1085            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1a_2_1"+LS);
1086            assertTrue(0 <= outPos);
1087            assertTrue(prevPos < outPos);
1088            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_2_1a"+LS);
1089            assertTrue(0 <= outPos);
1090            assertTrue(prevPos < outPos);
1091            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_2a_1"+LS);
1092            assertTrue(0 <= outPos);
1093            assertTrue(prevPos < outPos);
1094            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_2b_1"+LS);
1095            assertTrue(0 <= outPos);
1096            assertTrue(prevPos < outPos);
1097            
1098            newPos = stdOut.indexOf("testAnnArray0_1_2_1!"+LS);
1099            assertTrue(newPos > prevPos);
1100            prevPos = newPos;
1101            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1a_2_2"+LS);
1102            assertTrue(0 <= outPos);
1103            assertTrue(prevPos < outPos);
1104            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_2_2b"+LS);
1105            assertTrue(0 <= outPos);
1106            assertTrue(prevPos < outPos);
1107            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_2_2a"+LS);
1108            assertTrue(0 <= outPos);
1109            assertTrue(prevPos < outPos);
1110            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_2b_2"+LS);
1111            assertTrue(0 <= outPos);
1112            assertTrue(prevPos < outPos);
1113            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 0_1_2a_2"+LS);
1114            assertTrue(0 <= outPos);
1115            assertTrue(prevPos < outPos);
1116    
1117            newPos = stdOut.indexOf("testAnnArray0_1_2_2!"+LS);
1118            assertTrue(newPos > prevPos);
1119            prevPos = newPos;
1120            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_0_0_1"+LS);
1121            assertTrue(0 <= outPos);
1122            assertTrue(prevPos < outPos);
1123            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_0_1a"+LS);
1124            assertTrue(0 <= outPos);
1125            assertTrue(prevPos < outPos);
1126    
1127            newPos = stdOut.indexOf("testAnnArray1_0_0_1!"+LS);
1128            assertTrue(newPos > prevPos);
1129            prevPos = newPos;
1130            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_0_1_0"+LS);
1131            assertTrue(0 <= outPos);
1132            assertTrue(prevPos < outPos);
1133            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_1a_0"+LS);
1134            assertTrue(0 <= outPos);
1135            assertTrue(prevPos < outPos);
1136    
1137            newPos = stdOut.indexOf("testAnnArray1_0_1_0!"+LS);
1138            assertTrue(newPos > prevPos);
1139            prevPos = newPos;
1140            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_0_1_1"+LS);
1141            assertTrue(0 <= outPos);
1142            assertTrue(prevPos < outPos);
1143            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_1_1a"+LS);
1144            assertTrue(0 <= outPos);
1145            assertTrue(prevPos < outPos);
1146            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_1a_1"+LS);
1147            assertTrue(0 <= outPos);
1148            assertTrue(prevPos < outPos);
1149    
1150    
1151            newPos = stdOut.indexOf("testAnnArray1_0_1_1!"+LS);
1152            assertTrue(newPos > prevPos);
1153            prevPos = newPos;
1154            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_0_0_2"+LS);
1155            assertTrue(0 <= outPos);
1156            assertTrue(prevPos < outPos);
1157            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_0_2a"+LS);
1158            assertTrue(0 <= outPos);
1159            assertTrue(prevPos < outPos);
1160            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_0_2b"+LS);
1161            assertTrue(0 <= outPos);
1162            assertTrue(prevPos < outPos);
1163    
1164            newPos = stdOut.indexOf("testAnnArray1_0_0_2!"+LS);
1165            assertTrue(newPos > prevPos);
1166            prevPos = newPos;
1167            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_0_2_0"+LS);
1168            assertTrue(0 <= outPos);
1169            assertTrue(prevPos < outPos);
1170            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_2b_0"+LS);
1171            assertTrue(0 <= outPos);
1172            assertTrue(prevPos < outPos);
1173            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_2a_0"+LS);
1174            assertTrue(0 <= outPos);
1175            assertTrue(prevPos < outPos);
1176    
1177            newPos = stdOut.indexOf("testAnnArray1_0_2_0!"+LS);
1178            assertTrue(newPos > prevPos);
1179            prevPos = newPos;
1180            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_0_1_2"+LS);
1181            assertTrue(0 <= outPos);
1182            assertTrue(prevPos < outPos);
1183            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_1_2b"+LS);
1184            assertTrue(0 <= outPos);
1185            assertTrue(prevPos < outPos);
1186            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_1_2a"+LS);
1187            assertTrue(0 <= outPos);
1188            assertTrue(prevPos < outPos);
1189            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_1a_2"+LS);
1190            assertTrue(0 <= outPos);
1191            assertTrue(prevPos < outPos);
1192    
1193            newPos = stdOut.indexOf("testAnnArray1_0_1_2!"+LS);
1194            assertTrue(newPos > prevPos);
1195            prevPos = newPos;
1196            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_0_2_1"+LS);
1197            assertTrue(0 <= outPos);
1198            assertTrue(prevPos < outPos);
1199            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_2_1a"+LS);
1200            assertTrue(0 <= outPos);
1201            assertTrue(prevPos < outPos);
1202            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_2a_1"+LS);
1203            assertTrue(0 <= outPos);
1204            assertTrue(prevPos < outPos);
1205            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_2b_1"+LS);
1206            assertTrue(0 <= outPos);
1207            assertTrue(prevPos < outPos);
1208    
1209            newPos = stdOut.indexOf("testAnnArray1_0_2_1!"+LS);
1210            assertTrue(newPos > prevPos);
1211            prevPos = newPos;
1212            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_0_2_2"+LS);
1213            assertTrue(0 <= outPos);
1214            assertTrue(prevPos < outPos);
1215            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_2_2b"+LS);
1216            assertTrue(0 <= outPos);
1217            assertTrue(prevPos < outPos);
1218            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_2_2a"+LS);
1219            assertTrue(0 <= outPos);
1220            assertTrue(prevPos < outPos);
1221            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_2a_2"+LS);
1222            assertTrue(0 <= outPos);
1223            assertTrue(prevPos < outPos);
1224            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_0_2b_2"+LS);
1225            assertTrue(0 <= outPos);
1226            assertTrue(prevPos < outPos);
1227    
1228            newPos = stdOut.indexOf("testAnnArray1_0_2_2!"+LS);
1229            assertTrue(newPos > prevPos);
1230            prevPos = newPos;
1231            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1a_0_1"+LS);
1232            assertTrue(0 <= outPos);
1233            assertTrue(prevPos < outPos);
1234            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_1_0_1"+LS);
1235            assertTrue(0 <= outPos);
1236            assertTrue(prevPos < outPos);
1237            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_0_1a"+LS);
1238            assertTrue(0 <= outPos);
1239            assertTrue(prevPos < outPos);
1240    
1241            newPos = stdOut.indexOf("testAnnArray1_1_0_1!"+LS);
1242            assertTrue(newPos > prevPos);
1243            prevPos = newPos;
1244            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1a_1_0"+LS);
1245            assertTrue(0 <= outPos);
1246            assertTrue(prevPos < outPos);
1247            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_1_1_0"+LS);
1248            assertTrue(0 <= outPos);
1249            assertTrue(prevPos < outPos);
1250            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1a_0"+LS);
1251            assertTrue(0 <= outPos);
1252            assertTrue(prevPos < outPos);
1253    
1254            newPos = stdOut.indexOf("testAnnArray1_1_1_0!"+LS);
1255            assertTrue(newPos > prevPos);
1256            prevPos = newPos;
1257            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1a_1_1"+LS);
1258            assertTrue(0 <= outPos);
1259            assertTrue(prevPos < outPos);
1260            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_1_1_1"+LS);
1261            assertTrue(0 <= outPos);
1262            assertTrue(prevPos < outPos);
1263            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1_1a"+LS);
1264            assertTrue(0 <= outPos);
1265            assertTrue(prevPos < outPos);
1266            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1a_1"+LS);
1267            assertTrue(0 <= outPos);
1268            assertTrue(prevPos < outPos);
1269    
1270            newPos = stdOut.indexOf("testAnnArray1_1_1_1!"+LS);
1271            assertTrue(newPos > prevPos);
1272            prevPos = newPos;
1273            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1a_0_2"+LS);
1274            assertTrue(0 <= outPos);
1275            assertTrue(prevPos < outPos);
1276            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_1_0_2"+LS);
1277            assertTrue(0 <= outPos);
1278            assertTrue(prevPos < outPos);
1279            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_0_2a"+LS);
1280            assertTrue(0 <= outPos);
1281            assertTrue(prevPos < outPos);
1282            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_0_2b"+LS);
1283            assertTrue(0 <= outPos);
1284            assertTrue(prevPos < outPos);
1285    
1286            newPos = stdOut.indexOf("testAnnArray1_1_0_2!"+LS);
1287            assertTrue(newPos > prevPos);
1288            prevPos = newPos;
1289            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1a_2_0"+LS);
1290            assertTrue(0 <= outPos);
1291            assertTrue(prevPos < outPos);
1292            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_1_2_0"+LS);
1293            assertTrue(0 <= outPos);
1294            assertTrue(prevPos < outPos);
1295            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_2a_0"+LS);
1296            assertTrue(0 <= outPos);
1297            assertTrue(prevPos < outPos);
1298            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_2b_0"+LS);
1299            assertTrue(0 <= outPos);
1300            assertTrue(prevPos < outPos);
1301    
1302            newPos = stdOut.indexOf("testAnnArray1_1_2_0!"+LS);
1303            assertTrue(0 <= outPos);
1304            assertTrue(prevPos < outPos);
1305            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1a_1_2"+LS);
1306            assertTrue(0 <= outPos);
1307            assertTrue(prevPos < outPos);
1308            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_1_1_2"+LS);
1309            assertTrue(0 <= outPos);
1310            assertTrue(prevPos < outPos);
1311            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1_2b"+LS);
1312            assertTrue(0 <= outPos);
1313            assertTrue(prevPos < outPos);
1314            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1_2a"+LS);
1315            assertTrue(0 <= outPos);
1316            assertTrue(prevPos < outPos);
1317            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1a_2"+LS);
1318            assertTrue(0 <= outPos);
1319            assertTrue(prevPos < outPos);
1320    
1321            newPos = stdOut.indexOf("testAnnArray1_1_1_2!"+LS);
1322            assertTrue(newPos > prevPos);
1323            prevPos = newPos;
1324            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1a_2_1"+LS);
1325            assertTrue(0 <= outPos);
1326            assertTrue(prevPos < outPos);
1327            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_1_2_1"+LS);
1328            assertTrue(0 <= outPos);
1329            assertTrue(prevPos < outPos);
1330            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_2_1a"+LS);
1331            assertTrue(0 <= outPos);
1332            assertTrue(prevPos < outPos);
1333            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_2a_1"+LS);
1334            assertTrue(0 <= outPos);
1335            assertTrue(prevPos < outPos);
1336            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_2b_1"+LS);
1337            assertTrue(0 <= outPos);
1338            assertTrue(prevPos < outPos);
1339    
1340            newPos = stdOut.indexOf("testAnnArray1_1_2_1!"+LS);
1341            assertTrue(newPos > prevPos);
1342            prevPos = newPos;
1343            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1a_2_2"+LS);
1344            assertTrue(0 <= outPos);
1345            assertTrue(prevPos < outPos);
1346            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_1_2_2"+LS);
1347            assertTrue(0 <= outPos);
1348            assertTrue(prevPos < outPos);
1349            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_2_2b"+LS);
1350            assertTrue(0 <= outPos);
1351            assertTrue(prevPos < outPos);
1352            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_2_2a"+LS);
1353            assertTrue(0 <= outPos);
1354            assertTrue(prevPos < outPos);
1355            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_2b_2"+LS);
1356            assertTrue(0 <= outPos);
1357            assertTrue(prevPos < outPos);
1358            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_2a_2"+LS);
1359            assertTrue(0 <= outPos);
1360            assertTrue(prevPos < outPos);
1361    
1362            newPos = stdOut.indexOf("testAnnArray1_1_2_2!"+LS);
1363            assertTrue(newPos > prevPos);
1364            prevPos = newPos;
1365            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1a_1_0_2_2"+LS);
1366            assertTrue(0 <= outPos);
1367            assertTrue(prevPos < outPos);
1368            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1a_1_1_0_2_2"+LS);
1369            assertTrue(0 <= outPos);
1370            assertTrue(prevPos < outPos);
1371            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1a_0_2_2"+LS);
1372            assertTrue(0 <= outPos);
1373            assertTrue(prevPos < outPos);
1374            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1_0_2_2a"+LS);
1375            assertTrue(0 <= outPos);
1376            assertTrue(prevPos < outPos);
1377            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1_0_2_2b"+LS);
1378            assertTrue(0 <= outPos);
1379            assertTrue(prevPos < outPos);
1380            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1_0_2a_2"+LS);
1381            assertTrue(0 <= outPos);
1382            assertTrue(prevPos < outPos);
1383            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = 1_1_1_0_2b_2"+LS);
1384            assertTrue(0 <= outPos);
1385            assertTrue(prevPos < outPos);
1386    
1387            newPos = stdOut.indexOf("testAnnArray1_1_1_0_2_2!"+LS+"testAnnArray0_0!"+LS);
1388            assertTrue(newPos > prevPos);
1389            prevPos = newPos;
1390            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr0_1a"+LS);
1391            assertTrue(0 <= outPos);
1392            assertTrue(prevPos < outPos);
1393    
1394            newPos = stdOut.indexOf("testAnnArray0_1!"+LS);
1395            assertTrue(newPos > prevPos);
1396            prevPos = newPos;
1397            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr1a_0"+LS);
1398            assertTrue(0 <= outPos);
1399            assertTrue(prevPos < outPos);
1400    
1401            newPos = stdOut.indexOf("testAnnArray1_0!"+LS);
1402            assertTrue(newPos > prevPos);
1403            prevPos = newPos;
1404            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr1_1a"+LS);
1405            assertTrue(0 <= outPos);
1406            assertTrue(prevPos < outPos);
1407            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr1a_1"+LS);
1408            assertTrue(0 <= outPos);
1409            assertTrue(prevPos < outPos);
1410    
1411            newPos = stdOut.indexOf("testAnnArray1_1!"+LS);
1412            assertTrue(newPos > prevPos);
1413            prevPos = newPos;
1414            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr1_2b"+LS);
1415            assertTrue(0 <= outPos);
1416            assertTrue(prevPos < outPos);
1417            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr1_2a"+LS);
1418            assertTrue(0 <= outPos);
1419            assertTrue(prevPos < outPos);
1420            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr1a_2"+LS);
1421            assertTrue(0 <= outPos);
1422            assertTrue(prevPos < outPos);
1423    
1424            newPos = stdOut.indexOf("testAnnArray1_2!"+LS);
1425            assertTrue(newPos > prevPos);
1426            prevPos = newPos;
1427            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr2_1a"+LS);
1428            assertTrue(0 <= outPos);
1429            assertTrue(prevPos < outPos);
1430            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr2b_1"+LS);
1431            assertTrue(0 <= outPos);
1432            assertTrue(prevPos < outPos);
1433            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr2a_1"+LS);
1434            assertTrue(0 <= outPos);
1435            assertTrue(prevPos < outPos);
1436    
1437            newPos = stdOut.indexOf("testAnnArray2_1!"+LS);
1438            assertTrue(newPos > prevPos);
1439            prevPos = newPos;
1440            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr2_2b"+LS);
1441            assertTrue(0 <= outPos);
1442            assertTrue(prevPos < outPos);
1443            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr2_2a"+LS);
1444            assertTrue(0 <= outPos);
1445            assertTrue(prevPos < outPos);
1446            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr2b_2"+LS);
1447            assertTrue(0 <= outPos);
1448            assertTrue(prevPos < outPos);
1449            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = arr2a_2"+LS);
1450            assertTrue(0 <= outPos);
1451            assertTrue(prevPos < outPos);
1452    
1453            newPos = stdOut.indexOf("testAnnArray2_2!"+LS);
1454            assertTrue(newPos > prevPos);
1455            prevPos = newPos;
1456            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = test"+LS);
1457            assertTrue(0 <= outPos);
1458            assertTrue(prevPos < outPos);
1459    
1460            newPos = stdOut.indexOf("testString!"+LS);
1461            assertTrue(newPos > prevPos);
1462            prevPos = newPos;
1463            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = defaultString"+LS);
1464            assertTrue(0 <= outPos);
1465            assertTrue(prevPos < outPos);
1466    
1467            newPos = stdOut.indexOf("testAnnArrayDefault!"+LS+"testAnnArray!"+LS);
1468            assertTrue(newPos > prevPos);
1469            prevPos = newPos;
1470            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = default1-1"+LS);
1471            assertTrue(0 <= outPos);
1472            assertTrue(prevPos < outPos);
1473            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = array1-1"+LS);
1474            assertTrue(0 <= outPos);
1475            assertTrue(prevPos < outPos);
1476    
1477            newPos = stdOut.indexOf("testAnnArray1!"+LS);
1478            assertTrue(newPos > prevPos);
1479            prevPos = newPos;
1480            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = default2-1"+LS);
1481            assertTrue(0 <= outPos);
1482            assertTrue(prevPos < outPos);
1483            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = default2-2"+LS);
1484            assertTrue(0 <= outPos);
1485            assertTrue(prevPos < outPos);
1486            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = array2-2"+LS);
1487            assertTrue(0 <= outPos);
1488            assertTrue(prevPos < outPos);
1489            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = array2-1"+LS);
1490            assertTrue(0 <= outPos);
1491            assertTrue(prevPos < outPos);
1492    
1493            newPos = stdOut.indexOf("testAnnArray2!"+LS);
1494            assertTrue(newPos > prevPos);
1495            prevPos = newPos;
1496            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = array3-1"+LS);
1497            assertTrue(0 <= outPos);
1498            assertTrue(prevPos < outPos);
1499            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = array3-3"+LS);
1500            assertTrue(0 <= outPos);
1501            assertTrue(prevPos < outPos);
1502            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = array3-2"+LS);
1503            assertTrue(0 <= outPos);
1504            assertTrue(prevPos < outPos);
1505            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = default3-2"+LS);
1506            assertTrue(0 <= outPos);
1507            assertTrue(prevPos < outPos);
1508            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = default3-1"+LS);
1509            assertTrue(0 <= outPos);
1510            assertTrue(prevPos < outPos);
1511            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = default3-3"+LS);
1512            assertTrue(0 <= outPos);
1513            assertTrue(prevPos < outPos);
1514    
1515            newPos = stdOut.indexOf("testAnnArray3!"+LS);
1516            assertTrue(newPos > prevPos);
1517            prevPos = newPos;
1518            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = orTwo1"+LS);
1519            assertTrue(0 <= outPos);
1520            assertTrue(prevPos < outPos);
1521            outPos = stdOut.indexOf("thisO = sample.threadCheck.predicate.TCSample4@"+number+", value:String = orTwo2"+LS);
1522            assertTrue(0 <= outPos);
1523            assertTrue(prevPos < outPos);
1524    
1525            newPos = stdOut.indexOf("testOrTwo!"+LS);
1526            assertTrue(newPos > prevPos);
1527            prevPos = newPos;
1528    
1529            assertEquals("testOrTwo!", stdOut.substring(prevPos).trim());
1530    
1531            assertEquals(0, p.exitValue());
1532        }
1533    
1534        private Process runTestClass(String className) throws IOException {
1535            return runTestClass(className, NullStream.ONLY, NullStream.ONLY);
1536        }
1537        
1538        private Process runTestClass(String className, OutputStream stdOutStream,
1539                                     OutputStream stdErrStream) throws IOException {
1540            Process p = ExecJVM.runJVM(className,
1541                                       new String[] {},
1542                                       new String[] {_tempDir.getAbsolutePath()},
1543                                       new String[] {},
1544                                       _tempDir);
1545            StreamRedirectThread stdOut = new StreamRedirectThread("stdout", p.getInputStream(), stdOutStream);
1546            StreamRedirectThread stdErr = new StreamRedirectThread("stderr", p.getErrorStream(), stdErrStream);
1547            stdOut.start();
1548            stdErr.start();
1549            boolean stillWaiting = true;
1550            do {
1551                try {
1552                    p.waitFor();
1553                    stdErr.join();
1554                    stdOut.join();
1555                    stillWaiting = false;
1556                }
1557                catch(InterruptedException e) { /* ignore */ }
1558            } while(stillWaiting);
1559            return p;
1560        }
1561    
1562        public void testTCSample18() throws IOException {
1563            File base = new File(_tempDir, "sample"+FS+"threadCheck"+FS+"predicate");
1564            assertTrue(base.exists() && base.isDirectory());
1565            //List<File> files = FileOps.enumFiles(base);
1566            List<File> files = new ArrayList<File>();
1567            File cfile = new File(base, "TCSample18.class");
1568            assertTrue(cfile.exists() && cfile.isFile());
1569            files.add(cfile);
1570    
1571            ArrayList<String> args = new ArrayList<String>();
1572            args.add("-i");
1573            args.add(CompoundThreadCheckStrategy.class.getName());
1574            args.add("-X");
1575    
1576            StringBuilder sb = new StringBuilder();
1577            sb.append(AddThreadCheckStrategy.CLASS_PATH_PARAM_PREFIX);
1578            sb.append(_tempDir.getAbsolutePath());
1579            sb.append(PS);
1580            sb.append(System.getProperty("java.class.path"));
1581            sb.append(PS);
1582            sb.append(FileInstrumentor.getDefaultSourceRtJarName());
1583            args.add(sb.toString());
1584    
1585            ArrayList<String> classPath = new ArrayList<String>();
1586            for(String p: sb.toString().split(PS)) {
1587                classPath.add(p);
1588            }
1589    
1590            for(File f: files) {
1591                args.add(f.getAbsolutePath());
1592            }
1593    
1594    //        System.out.println("Parameters:");
1595    //        for(String a: args) {
1596    //            System.out.println("\t"+a);
1597    //        }
1598    
1599            ByteArrayOutputStream baos = new ByteArrayOutputStream();
1600            Debug.out.setOutput(new PrintStream(baos));
1601            FileInstrumentor.main(args.toArray(new String[0]));
1602            String output = baos.toString();
1603    //        System.out.println(output);
1604    
1605            // check no IOExceptions
1606            int ioExcIndex = output.indexOf("IOExceptions: 0");
1607            if (ioExcIndex<0) {
1608                ioExcIndex = output.indexOf("IOExceptions: ");
1609                int newLineIndex = output.indexOf(System.getProperty("line.separator"), ioExcIndex);
1610                fail(output.substring(ioExcIndex,newLineIndex));
1611            }
1612    
1613            // check scanner results
1614            String strScannerRes = "Scanner results: " + LS;
1615            int sResultsIndex = output.indexOf(strScannerRes);
1616            if (sResultsIndex<0) {
1617                sResultsIndex = output.indexOf(strScannerRes);
1618                fail(output.substring(sResultsIndex,ioExcIndex));
1619            }
1620            int nextLineIndex = sResultsIndex + strScannerRes.length();
1621            String remainderStr = output.substring(nextLineIndex);
1622            int nextLineEndIndex = remainderStr.indexOf(LS);
1623            String nextLine = remainderStr.substring(0, nextLineEndIndex);
1624            if (!nextLine.startsWith("\tThreadChecker Cache Info")) {
1625                fail("Expected 'ThreadChecker Cache Info', was '"+nextLine+"'");
1626            }
1627            remainderStr = remainderStr.substring(nextLineEndIndex);
1628            if (!remainderStr.startsWith(LS+LS+LS+"IOExceptions: 0"+LS)) {
1629                fail("Expected '\n\n\nIOExceptions: 0\n', was '"+remainderStr+"'");
1630            }
1631    
1632            File cfile_old = new File(base, "TCSample18.class~");
1633            assertTrue(cfile.exists() && cfile.isFile());
1634            assertTrue(cfile_old.exists() && cfile_old.isFile());
1635    
1636            String className = "sample.threadCheck.predicate.TCSample18";
1637            ByteArrayOutputStream stdOutStream = new ByteArrayOutputStream();
1638            Process p = runTestClass(className, stdOutStream, NullStream.ONLY);
1639            String stdOut = stdOutStream.toString();
1640            assertEquals("Wrong output", "main!"+LS+"t!"+LS+"ta!"+LS+"t2!"+LS+"ta2!"+LS+"end main!"+LS,stdOut);
1641    //        System.out.println(stdOut);
1642    
1643            File tcLog = new File(_tempDir, "threadCheck.log");
1644            assertTrue(tcLog.exists() && tcLog.isFile());
1645            FileInputStream fis = new FileInputStream(tcLog);
1646            StringBuilder tcsb = new StringBuilder();
1647            int x;
1648            byte b[];
1649            String s;
1650            while((x = fis.available())>0) {
1651                x = fis.available();
1652                b = new byte[x];
1653                fis.read(b);
1654                s = new String(b);
1655                tcsb.append(s);
1656            }
1657            fis.close();
1658            String tc = tcsb.toString();
1659    //        System.out.println(tc);
1660    
1661            int count = 0, index = 0;
1662            while((index=tc.indexOf("Exception in Thread Predicate Violation:", index))>=0) { ++count; ++index; }
1663    //        System.out.println("Violation count = "+count);
1664            assertEquals(4, count);
1665    
1666    //        System.out.println("stdout = ");
1667    //        System.out.println(stdOut);
1668    
1669            assertEquals(0, p.exitValue());
1670        }
1671    
1672        public void testTCSample19() throws IOException {
1673            File base = new File(_tempDir, "sample"+FS+"threadCheck"+FS+"predicate");
1674            assertTrue(base.exists() && base.isDirectory());
1675            //List<File> files = FileOps.enumFiles(base);
1676            List<File> files = new ArrayList<File>();
1677            File cfile = new File(base, "TCSample19.class");
1678            assertTrue(cfile.exists() && cfile.isFile());
1679            files.add(cfile);
1680    
1681            ArrayList<String> args = new ArrayList<String>();
1682            args.add("-i");
1683            args.add(CompoundThreadCheckStrategy.class.getName());
1684            args.add("-X");
1685    
1686            StringBuilder sb = new StringBuilder();
1687            sb.append(AddThreadCheckStrategy.CLASS_PATH_PARAM_PREFIX);
1688            sb.append(_tempDir.getAbsolutePath());
1689            sb.append(PS);
1690            sb.append(System.getProperty("java.class.path"));
1691            sb.append(PS);
1692            sb.append(FileInstrumentor.getDefaultSourceRtJarName());
1693            args.add(sb.toString());
1694    
1695            ArrayList<String> classPath = new ArrayList<String>();
1696            for(String p: sb.toString().split(PS)) {
1697                classPath.add(p);
1698            }
1699    
1700            for(File f: files) {
1701                args.add(f.getAbsolutePath());
1702            }
1703    
1704    //        System.out.println("Parameters:");
1705    //        for(String a: args) {
1706    //            System.out.println("\t"+a);
1707    //        }
1708    
1709            ByteArrayOutputStream baos = new ByteArrayOutputStream();
1710            Debug.out.setOutput(new PrintStream(baos));
1711            FileInstrumentor.main(args.toArray(new String[0]));
1712            String output = baos.toString();
1713    //        System.out.println(output);
1714    
1715            // check no IOExceptions
1716            int ioExcIndex = output.indexOf("IOExceptions: 0");
1717            if (ioExcIndex<0) {
1718                ioExcIndex = output.indexOf("IOExceptions: ");
1719                int newLineIndex = output.indexOf(System.getProperty("line.separator"), ioExcIndex);
1720                fail(output.substring(ioExcIndex,newLineIndex));
1721            }
1722    
1723            // check scanner results
1724            String strScannerRes = "Scanner results: " + LS;
1725            int sResultsIndex = output.indexOf(strScannerRes);
1726            if (sResultsIndex<0) {
1727                sResultsIndex = output.indexOf(strScannerRes);
1728                fail(output.substring(sResultsIndex,ioExcIndex));
1729            }
1730            int nextLineIndex = sResultsIndex + strScannerRes.length();
1731            String remainderStr = output.substring(nextLineIndex);
1732            int nextLineEndIndex = remainderStr.indexOf(LS);
1733            String nextLine = remainderStr.substring(0, nextLineEndIndex);
1734            if (!nextLine.startsWith("\tThreadChecker Cache Info")) {
1735                fail("Expected 'ThreadChecker Cache Info', was '"+nextLine+"'");
1736            }
1737            remainderStr = remainderStr.substring(nextLineEndIndex);
1738            if (!remainderStr.startsWith(LS+LS+LS+"IOExceptions: 0"+LS)) {
1739                fail("Expected '\n\n\nIOExceptions: 0\n', was '"+remainderStr+"'");
1740            }
1741    
1742            File cfile_old = new File(base, "TCSample19.class~");
1743            assertTrue(cfile.exists() && cfile.isFile());
1744            assertTrue(cfile_old.exists() && cfile_old.isFile());
1745    
1746            String className = "sample.threadCheck.predicate.TCSample19";
1747            ByteArrayOutputStream stdOutStream = new ByteArrayOutputStream();
1748            Process p = runTestClass(className, stdOutStream, NullStream.ONLY);
1749            String stdOut = stdOutStream.toString();
1750            // System.out.println(stdOut);
1751            assertEquals("Wrong output", "main!"+LS+"t!"+LS+"f!"+LS+"fXf!"+LS+"fXt!"+LS+
1752                 "tXf!"+LS+"tXt!"+LS+"fXfXf!"+LS+"fXtXf!"+LS+"tXfXf!"+LS+"tXtXf!"+
1753                 LS+"fXfXt!"+LS+"fXtXt!"+LS+"tXfXt!"+LS+"tXtXt!"+LS+"end main!"+LS,
1754                 stdOut);
1755    
1756            File tcLog = new File(_tempDir, "threadCheck.log");
1757            assertTrue(tcLog.exists() && tcLog.isFile());
1758            FileInputStream fis = new FileInputStream(tcLog);
1759            StringBuilder tcsb = new StringBuilder();
1760            int x;
1761            byte b[];
1762            String s;
1763            while((x = fis.available())>0) {
1764                x = fis.available();
1765                b = new byte[x];
1766                fis.read(b);
1767                s = new String(b);
1768                tcsb.append(s);
1769            }
1770            fis.close();
1771            String tc = tcsb.toString();
1772    //        System.out.println(tc);
1773    
1774            int count = 0, index = 0;
1775            while((index=tc.indexOf("Thread Predicate Violation:", index))>=0) { ++count; ++index; }
1776    //        System.out.println("Violation count = "+count);
1777            assertEquals(8, count);
1778    
1779    //        System.out.println("stdout = ");
1780    //        System.out.println(stdOut);
1781    
1782            assertEquals(0, p.exitValue());
1783        }
1784    
1785    
1786        public void testTCSample20() throws IOException {
1787            File base = new File(_tempDir, "sample"+FS+"threadCheck"+FS+"predicate");
1788            assertTrue(base.exists() && base.isDirectory());
1789            //List<File> files = FileOps.enumFiles(base);
1790            List<File> files = new ArrayList<File>();
1791            File cfile = new File(base, "TCSample20.class");
1792            assertTrue(cfile.exists() && cfile.isFile());
1793            files.add(cfile);
1794    
1795            ArrayList<String> args = new ArrayList<String>();
1796            args.add("-i");
1797            args.add(CompoundThreadCheckStrategy.class.getName());
1798            args.add("-X");
1799    
1800            StringBuilder sb = new StringBuilder();
1801            sb.append(AddThreadCheckStrategy.CLASS_PATH_PARAM_PREFIX);
1802            sb.append(_tempDir.getAbsolutePath());
1803            sb.append(PS);
1804            sb.append(System.getProperty("java.class.path"));
1805            sb.append(PS);
1806            sb.append(FileInstrumentor.getDefaultSourceRtJarName());
1807            args.add(sb.toString());
1808    
1809            ArrayList<String> classPath = new ArrayList<String>();
1810            for(String p: sb.toString().split(PS)) {
1811                classPath.add(p);
1812            }
1813    
1814            for(File f: files) {
1815                args.add(f.getAbsolutePath());
1816            }
1817    
1818    //        System.out.println("Parameters:");
1819    //        for(String a: args) {
1820    //            System.out.println("\t"+a);
1821    //        }
1822    
1823            ByteArrayOutputStream baos = new ByteArrayOutputStream();
1824            Debug.out.setOutput(new PrintStream(baos));
1825            FileInstrumentor.main(args.toArray(new String[0]));
1826            String output = baos.toString();
1827    //        System.out.println(output);
1828    
1829            int badImplies = 0;
1830            int index = -1;
1831            do {
1832                index = output.indexOf("BadImpliesAnnotation", index+1);
1833                if (index<0) {
1834                    break;
1835                }
1836                ++badImplies;
1837            } while((index>=0)&&(index<output.length()));
1838    
1839            int badNot = 0;
1840            index = -1;
1841            do {
1842                index = output.indexOf("BadNotAnnotation", index+1);
1843                if (index<0) {
1844                    break;
1845                }
1846                ++badNot;
1847            } while((index>=0)&&(index<output.length()));
1848    
1849            assertEquals("Expected 9 bad IMPLIES @Combines", 8, badImplies);
1850            assertEquals("Expected 9 bad IMPLIES @Combines", 3, badNot);
1851    
1852            // check no IOExceptions
1853            int ioExcIndex = output.indexOf("IOExceptions: 0");
1854            if (ioExcIndex<0) {
1855                ioExcIndex = output.indexOf("IOExceptions: ");
1856                int newLineIndex = output.indexOf(System.getProperty("line.separator"), ioExcIndex);
1857                fail(output.substring(ioExcIndex,newLineIndex));
1858            }
1859    
1860            File cfile_old = new File(base, "TCSample20.class~");
1861            assertTrue(cfile.exists() && cfile.isFile());
1862            assertTrue(cfile_old.exists() && cfile_old.isFile());
1863    
1864            String className = "sample.threadCheck.predicate.TCSample20";
1865            ByteArrayOutputStream stdOutStream = new ByteArrayOutputStream();
1866            Process p = runTestClass(className, stdOutStream, NullStream.ONLY);
1867            String stdOut = stdOutStream.toString();
1868            // System.out.println(stdOut);
1869            assertEquals("Wrong output", "main!"+LS+"impliesTxT!"+LS+"impliesTxF!"+LS+"impliesFxT!"+LS+
1870                    "impliesFxF!"+LS+"end main!"+LS, stdOut);
1871    
1872            File tcLog = new File(_tempDir, "threadCheck.log");
1873            assertTrue(tcLog.exists() && tcLog.isFile());
1874            FileInputStream fis = new FileInputStream(tcLog);
1875            StringBuilder tcsb = new StringBuilder();
1876            int x;
1877            byte b[];
1878            String s;
1879            while((x = fis.available())>0) {
1880                x = fis.available();
1881                b = new byte[x];
1882                fis.read(b);
1883                s = new String(b);
1884                tcsb.append(s);
1885            }
1886            fis.close();
1887            String tc = tcsb.toString();
1888    //        System.out.println(tc);
1889    
1890            int count = 0;
1891            index = 0;
1892            while((index=tc.indexOf("Thread Predicate Violation:", index))>=0) { ++count; ++index; }
1893    //        System.out.println("Violation count = "+count);
1894            assertEquals(1, count);
1895    
1896            // make sure that only the T->F case fails
1897            assertTrue(tc.indexOf("Violated predicate @sample.threadCheck.predicate.TCSample20$ImpliesTxFAnnotation")>=0);
1898    
1899    //        System.out.println("stdout = ");
1900    //        System.out.println(stdOut);
1901    
1902            assertEquals(0, p.exitValue());
1903        }
1904    }