blob: eb58c3752df529e19df49ea682e49a56b9281e30 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Simeon Andreev 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:
* Simeon Andreev - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.core.tests.builder;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.compiler.BuildContext;
import org.eclipse.jdt.core.tests.builder.ParticipantBuildTests.BuildTestParticipant;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.core.builder.AbstractImageBuilder;
import junit.framework.Test;
public class Bug531382Test extends BuilderTests {
private IPath project;
private IPath src;
private IPath srcPackage;
private int previousLimit;
public Bug531382Test(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(Bug531382Test.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
this.project = env.addProject("TestProjectBug531382");
env.addExternalJars(this.project, Util.getJavaClassLibs());
env.removePackageFragmentRoot(this.project, "");
this.src = env.addPackageFragmentRoot(this.project, "src");
this.srcPackage = env.addPackage(this.src, "p");
/*
* We can work with the limit "as is", however that would mean creating a lot of classes.
* To improve test time we set the limit to a small number and then restore it once the test is done.
*
* This improvement can be removed if the field is to be hidden or made final.
*/
this.previousLimit = AbstractImageBuilder.MAX_AT_ONCE;
AbstractImageBuilder.MAX_AT_ONCE = 42;
}
@Override
protected void tearDown() throws Exception {
TestBuilderParticipant.PARTICIPANT = null;
AbstractImageBuilder.MAX_AT_ONCE = this.previousLimit;
env.removeProject(this.project);
super.tearDown();
}
/**
* Test for Bug 531382.
*
* We create {@link AbstractImageBuilder#MAX_AT_ONCE} sources (e.g. 2000 sources).
*
* A build participant generates one more source during the build.
*
* We expect that this generated source is also compiled after the build.
* To check this we generate the source with an error for it, and we check for the error.
*/
public void testBug531382() throws Exception {
IFolder srcPackageFolder = env.getWorkspace().getRoot().getFolder(this.srcPackage);
assertTrue("package in source must exist", srcPackageFolder.exists());
for (int i = 0; i < AbstractImageBuilder.MAX_AT_ONCE; ++i) {
env.addClass(this.src, "p", "X" + i, "package p;\n public class X" + i + " {}");
}
final IFile generatedFile = srcPackageFolder.getFile("Generated.java");
final String contents = "package p;\n public class NameMismatch {}";
class GenerateBrokenSource extends BuildTestParticipant {
public void buildStarting(BuildContext[] files, boolean isBatch) {
if (files.length > 0 && !generatedFile.exists()) {
BuildContext context = files[0];
createFile(generatedFile, contents);
IFile[] generatedFiles = { generatedFile };
context.recordAddedGeneratedFiles(generatedFiles);
}
}
}
// Creating this sets the build participant singleton.
new GenerateBrokenSource();
assertFalse("source to be generated from build participant should not exist before build", generatedFile.exists());
fullBuild(this.project);
assertTrue("expected source to be generated from build participant", generatedFile.exists());
expectCompileProblem("The public type NameMismatch must be defined in its own file");
}
protected void createFile(IFile generatedFile, String contents) {
boolean force = true;
IProgressMonitor monitor = new NullProgressMonitor();
try {
generatedFile.create(new ByteArrayInputStream(contents.getBytes()), force, monitor);
generatedFile.setDerived(true, monitor);
} catch (CoreException e) {
throw new AssertionError("failed to generate file in build participant", e);
}
}
private void expectCompileProblem(String expectedProblemMessage) {
List<String> actualProblemMessages = new ArrayList<>();
Problem[] problems = env.getProblemsFor(this.project, "org.eclipse.jdt.core.tests.compile.problem");
if (problems != null) {
for (Problem problem : problems) {
actualProblemMessages.add(problem.getMessage());
}
}
List<String> expectedProblemMessages = Arrays.asList(expectedProblemMessage);
assertEquals("expected build participant to cause compile problems",
expectedProblemMessages, actualProblemMessages);
}
}