1 /******************************************************************************* 2 * Copyright (c) 2012, 2014 IBM Corporation GK Software AG and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Stephan Herrmann - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.core.tests.compiler.regression; 15 16 import java.io.File; 17 import java.io.PrintWriter; 18 import java.util.Map; 19 20 import junit.framework.Test; 21 22 import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable; 23 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 24 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; 25 26 @SuppressWarnings({ "unchecked", "rawtypes" }) 27 public class ConcurrentBatchCompilerTest extends BatchCompilerTest { 28 suite()29 public static Test suite() { 30 return buildUniqueComplianceTestSuite(testClass(), ClassFileConstants.JDK1_6); 31 } testClass()32 public static Class testClass() { 33 return ConcurrentBatchCompilerTest.class; 34 } ConcurrentBatchCompilerTest(String name)35 public ConcurrentBatchCompilerTest(String name) { 36 super(name); 37 } 38 39 Thread runner1; 40 Thread runner2; 41 42 static int COUNT = 100; 43 44 /* Invoke the compiler COUNT times to increase bug probabililty. */ 45 @Override invokeCompiler(PrintWriter out, PrintWriter err, Object extraArguments, TestCompilationProgress compilationProgress)46 protected boolean invokeCompiler(PrintWriter out, PrintWriter err, Object extraArguments, TestCompilationProgress compilationProgress) { 47 boolean success = true; 48 for (int j=0; j<COUNT; j++) { 49 success &= super.invokeCompiler(out, err, extraArguments, compilationProgress); 50 } 51 return success; 52 } 53 54 /* Disambiguate file names for concurrent tests in the same directory. */ 55 @Override testName()56 protected String testName() { 57 Thread current = Thread.currentThread(); 58 String baseName = super.testName(); 59 if (current == this.runner1) 60 return baseName+"-Thread1"; 61 if (current == this.runner2) 62 return baseName+"-Thread2"; 63 return baseName; 64 } 65 testBug372319()66 public void testBug372319() throws Throwable { 67 try { 68 FakedTrackingVariable.TEST_372319 = true; 69 70 // expected error output for runner2 times COUNT: 71 final StringBuffer errorOutput = new StringBuffer(); 72 for (int j=0; j<COUNT; j++) 73 errorOutput.append("----------\n" + 74 "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/test01/X.java (at line 12)\n" + 75 " FileReader reader = getReader(\"somefile\");\n" + 76 " ^^^^^^\n" + 77 "Potential resource leak: \'reader\' may not be closed\n" + 78 "----------\n" + 79 "1 problem (1 error)\n"); 80 81 // collect exceptions indicating a failure: 82 final Throwable[] thrown = new Throwable[2]; 83 84 this.runner1 = new Thread(new Runnable() { 85 @Override 86 public void run() { 87 try { 88 runConformTest(new String[] { 89 "org/eclipse/jdt/internal/launching/CompositeId.java", 90 "/*******************************************************************************\n" + 91 " * Copyright (c) 2000, 2014 IBM Corporation and others.\n" + 92 " * All rights reserved. This program and the accompanying materials\n" + 93 " * are made available under the terms of the Eclipse Public License v1.0\n" + 94 " * which accompanies this distribution, and is available at\n" + 95 " * http://www.eclipse.org/legal/epl-v10.html\n" + 96 " * \n" + 97 " * Contributors:\n" + 98 " * IBM Corporation - initial API and implementation\n" + 99 " *******************************************************************************/\n" + 100 "package org.eclipse.jdt.internal.launching;\n" + 101 "\n" + 102 "import java.util.ArrayList;\n" + 103 "\n" + 104 "/**\n" + 105 " * Utility class for id's made of multiple Strings\n" + 106 " */\n" + 107 "public class CompositeId {\n" + 108 " private String[] fParts;\n" + 109 " \n" + 110 " public CompositeId(String[] parts) {\n" + 111 " fParts= parts;\n" + 112 " }\n" + 113 " \n" + 114 " public static CompositeId fromString(String idString) {\n" + 115 " ArrayList<String> parts= new ArrayList<String>();\n" + 116 " int commaIndex= idString.indexOf(',');\n" + 117 " while (commaIndex > 0) {\n" + 118 " int length= Integer.valueOf(idString.substring(0, commaIndex)).intValue();\n" + 119 " String part= idString.substring(commaIndex+1, commaIndex+1+length);\n" + 120 " parts.add(part);\n" + 121 " idString= idString.substring(commaIndex+1+length);\n" + 122 " commaIndex= idString.indexOf(',');\n" + 123 " }\n" + 124 " String[] result= parts.toArray(new String[parts.size()]);\n" + 125 " return new CompositeId(result);\n" + 126 " }\n" + 127 " \n" + 128 " @Override\n" + 129 " public String toString() {\n" + 130 " StringBuffer buf= new StringBuffer();\n" + 131 " for (int i= 0; i < fParts.length; i++) {\n" + 132 " buf.append(fParts[i].length());\n" + 133 " buf.append(',');\n" + 134 " buf.append(fParts[i]);\n" + 135 " }\n" + 136 " return buf.toString();\n" + 137 " }\n" + 138 " \n" + 139 " public String get(int index) {\n" + 140 " return fParts[index];\n" + 141 " }\n" + 142 " \n" + 143 " public int getPartCount() {\n" + 144 " return fParts.length;\n" + 145 " }\n" + 146 "}\n" + 147 "" 148 }, 149 "\"" + OUTPUT_DIR + File.separator + "org/eclipse/jdt/internal/launching/CompositeId.java\"" 150 + " -1.5 -g -preserveAllLocals" 151 + " -proceedOnError -d \"" + OUTPUT_DIR + "\"", 152 "", 153 "", 154 false); 155 } catch (Throwable t) { 156 thrown[0] = t; 157 } 158 } 159 }); 160 this.runner2 = new Thread(new Runnable() { 161 @Override 162 public void run() { 163 try { 164 // from ResourceLeakTests.test056e(): 165 Map options = getCompilerOptions(); 166 options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); 167 options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); 168 runNegativeTest( 169 new String[] { 170 "test01/X.java", 171 "package test01;\n" + 172 "import java.io.File;\n" + 173 "import java.io.FileReader;\n" + 174 "import java.io.IOException;\n" + 175 "public class X {\n" + 176 " FileReader getReader(String filename) throws IOException {\n" + 177 " File file = new File(\"somefile\");\n" + 178 " FileReader fileReader = new FileReader(file);\n" + 179 " return fileReader;\n" + // don't complain here, pass responsibility to caller 180 " }\n" + 181 " void foo() throws IOException {\n" + 182 " FileReader reader = getReader(\"somefile\");\n" + 183 " char[] in = new char[50];\n" + 184 " reader.read(in);\n" + 185 " }\n" + 186 " public static void main(String[] args) throws IOException {\n" + 187 " new X().foo();\n" + 188 " }\n" + 189 "}\n" 190 }, 191 "\"" + OUTPUT_DIR + File.separator + "test01/X.java\"" 192 + " -1.5 -g -preserveAllLocals -err:+resource" 193 + " -proceedOnError -d \"" + OUTPUT_DIR + "\"", 194 "", 195 errorOutput.toString(), 196 false); 197 } catch (Throwable t) { 198 thrown[1] = t; 199 } 200 } 201 }); 202 203 this.runner2.start(); 204 this.runner1.start(); 205 this.runner1.join(); 206 this.runner2.join(); 207 if (thrown[0] != null) throw thrown[0]; 208 if (thrown[1] != null) throw thrown[1]; 209 } finally { 210 FakedTrackingVariable.TEST_372319 = false; 211 } 212 } 213 } 214