blob: 6cb58d015a68869064cc24e20e9991b4f3c09cc8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2014 IBM Corporation GK Software AG and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Stephan Herrmann - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
import java.io.File;
import java.io.PrintWriter;
import java.util.Map;
import junit.framework.Test;
import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
@SuppressWarnings({ "unchecked", "rawtypes" })
public class ConcurrentBatchCompilerTest extends BatchCompilerTest {
public static Test suite() {
return buildUniqueComplianceTestSuite(testClass(), ClassFileConstants.JDK1_6);
}
public static Class testClass() {
return ConcurrentBatchCompilerTest.class;
}
public ConcurrentBatchCompilerTest(String name) {
super(name);
}
Thread runner1;
Thread runner2;
static int COUNT = 100;
/* Invoke the compiler COUNT times to increase bug probabililty. */
protected boolean invokeCompiler(PrintWriter out, PrintWriter err, Object extraArguments, TestCompilationProgress compilationProgress) {
boolean success = true;
for (int j=0; j<COUNT; j++) {
success &= super.invokeCompiler(out, err, extraArguments, compilationProgress);
}
return success;
}
/* Disambiguate file names for concurrent tests in the same directory. */
protected String testName() {
Thread current = Thread.currentThread();
String baseName = super.testName();
if (current == this.runner1)
return baseName+"-Thread1";
if (current == this.runner2)
return baseName+"-Thread2";
return baseName;
}
public void testBug372319() throws Throwable {
try {
FakedTrackingVariable.TEST_372319 = true;
// expected error output for runner2 times COUNT:
final StringBuffer errorOutput = new StringBuffer();
for (int j=0; j<COUNT; j++)
errorOutput.append("----------\n" +
"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/test01/X.java (at line 12)\n" +
" FileReader reader = getReader(\"somefile\");\n" +
" ^^^^^^\n" +
"Potential resource leak: \'reader\' may not be closed\n" +
"----------\n" +
"1 problem (1 error)\n");
// collect exceptions indicating a failure:
final Throwable[] thrown = new Throwable[2];
this.runner1 = new Thread(new Runnable() {
public void run() {
try {
runConformTest(new String[] {
"org/eclipse/jdt/internal/launching/CompositeId.java",
"/*******************************************************************************\n" +
" * Copyright (c) 2000, 2014 IBM Corporation and others.\n" +
" * All rights reserved. This program and the accompanying materials\n" +
" * are made available under the terms of the Eclipse Public License v1.0\n" +
" * which accompanies this distribution, and is available at\n" +
" * http://www.eclipse.org/legal/epl-v10.html\n" +
" * \n" +
" * Contributors:\n" +
" * IBM Corporation - initial API and implementation\n" +
" *******************************************************************************/\n" +
"package org.eclipse.jdt.internal.launching;\n" +
"\n" +
"import java.util.ArrayList;\n" +
"\n" +
"/**\n" +
" * Utility class for id's made of multiple Strings\n" +
" */\n" +
"public class CompositeId {\n" +
" private String[] fParts;\n" +
" \n" +
" public CompositeId(String[] parts) {\n" +
" fParts= parts;\n" +
" }\n" +
" \n" +
" public static CompositeId fromString(String idString) {\n" +
" ArrayList<String> parts= new ArrayList<String>();\n" +
" int commaIndex= idString.indexOf(',');\n" +
" while (commaIndex > 0) {\n" +
" int length= Integer.valueOf(idString.substring(0, commaIndex)).intValue();\n" +
" String part= idString.substring(commaIndex+1, commaIndex+1+length);\n" +
" parts.add(part);\n" +
" idString= idString.substring(commaIndex+1+length);\n" +
" commaIndex= idString.indexOf(',');\n" +
" }\n" +
" String[] result= parts.toArray(new String[parts.size()]);\n" +
" return new CompositeId(result);\n" +
" }\n" +
" \n" +
" @Override\n" +
" public String toString() {\n" +
" StringBuffer buf= new StringBuffer();\n" +
" for (int i= 0; i < fParts.length; i++) {\n" +
" buf.append(fParts[i].length());\n" +
" buf.append(',');\n" +
" buf.append(fParts[i]);\n" +
" }\n" +
" return buf.toString();\n" +
" }\n" +
" \n" +
" public String get(int index) {\n" +
" return fParts[index];\n" +
" }\n" +
" \n" +
" public int getPartCount() {\n" +
" return fParts.length;\n" +
" }\n" +
"}\n" +
""
},
"\"" + OUTPUT_DIR + File.separator + "org/eclipse/jdt/internal/launching/CompositeId.java\""
+ " -1.5 -g -preserveAllLocals"
+ " -proceedOnError -d \"" + OUTPUT_DIR + "\"",
"",
"",
false);
} catch (Throwable t) {
thrown[0] = t;
}
}
});
this.runner2 = new Thread(new Runnable() {
public void run() {
try {
// from ResourceLeakTests.test056e():
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
runNegativeTest(
new String[] {
"test01/X.java",
"package test01;\n" +
"import java.io.File;\n" +
"import java.io.FileReader;\n" +
"import java.io.IOException;\n" +
"public class X {\n" +
" FileReader getReader(String filename) throws IOException {\n" +
" File file = new File(\"somefile\");\n" +
" FileReader fileReader = new FileReader(file);\n" +
" return fileReader;\n" + // don't complain here, pass responsibility to caller
" }\n" +
" void foo() throws IOException {\n" +
" FileReader reader = getReader(\"somefile\");\n" +
" char[] in = new char[50];\n" +
" reader.read(in);\n" +
" }\n" +
" public static void main(String[] args) throws IOException {\n" +
" new X().foo();\n" +
" }\n" +
"}\n"
},
"\"" + OUTPUT_DIR + File.separator + "test01/X.java\""
+ " -1.5 -g -preserveAllLocals -err:+resource"
+ " -proceedOnError -d \"" + OUTPUT_DIR + "\"",
"",
errorOutput.toString(),
false);
} catch (Throwable t) {
thrown[1] = t;
}
}
});
this.runner2.start();
this.runner1.start();
this.runner1.join();
this.runner2.join();
if (thrown[0] != null) throw thrown[0];
if (thrown[1] != null) throw thrown[1];
} finally {
FakedTrackingVariable.TEST_372319 = false;
}
}
}