/******************************************************************************* * Copyright (c) 2012, 2014 IBM Corporation GK Software AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * 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; } } }