blob: 53c2dda8f06f7acfed97082754717898689511a5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corporation 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:
* IBM Corporation - initial API and implementation
* Alexander Kurtakov <akurtako@redhat.com> - Bug 459343
*******************************************************************************/
package org.eclipse.core.tests.internal.builders;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.tests.harness.TestBarrier;
import org.eclipse.core.tests.harness.TestJob;
/**
* This class tests public API related to building and to build specifications.
* Specifically, the following methods are tested:
*
* IWorkspace#build IProject#build IProjectDescription#getBuildSpec
* IProjectDescription#setBuildSpec
*/
public class BuilderTest extends AbstractBuilderTest {
public static Test suite() {
return new TestSuite(BuilderTest.class);
// TestSuite suite = new TestSuite();
// suite.addTest(new BuilderTest("testInterruptAutobuild"));
// return suite;
}
public BuilderTest() {
super(null);
}
/**
* BuilderTest constructor comment.
*
* @param name
* java.lang.String
*/
public BuilderTest(String name) {
super(name);
}
/**
* Tears down the fixture, for example, close a network connection. This
* method is called after a test is executed.
*/
@Override
protected void tearDown() throws Exception {
super.tearDown();
getWorkspace().getRoot().delete(true, null);
TestBuilder builder = SortBuilder.getInstance();
if (builder != null) {
builder.reset();
}
builder = DeltaVerifierBuilder.getInstance();
if (builder != null) {
builder.reset();
}
}
/**
* Make sure this test runs first, before any other test
* has a chance to mess with the build order.
*/
public void testAardvarkBuildOrder() {
IWorkspace workspace = getWorkspace();
//builder order should initially be null
assertEquals("1.0", null, workspace.getDescription().getBuildOrder());
}
/**
* Tests the lifecycle of a builder.
*
* @see SortBuilder
*/
public void testAutoBuildPR() {
//REF: 1FUQUJ4
// Create some resource handles
IWorkspace workspace = getWorkspace();
IProject project1 = workspace.getRoot().getProject("PROJECT" + 1);
IFolder folder = project1.getFolder("FOLDER");
IFolder sub = folder.getFolder("sub");
IFile fileA = folder.getFile("A");
IFile fileB = sub.getFile("B");
// Create some resources
try {
// Turn auto-building on
setAutoBuilding(true);
project1.create(getMonitor());
project1.open(getMonitor());
// Set build spec
IProjectDescription desc = project1.getDescription();
ICommand command = desc.newCommand();
command.setBuilderName(SortBuilder.BUILDER_NAME);
command.getArguments().put(TestBuilder.BUILD_ID, "Project1Build1");
desc.setBuildSpec(new ICommand[] {command});
project1.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("1.99", e);
}
// Create folders and files
try {
folder.create(true, true, getMonitor());
fileA.create(getRandomContents(), true, getMonitor());
sub.create(true, true, getMonitor());
fileB.create(getRandomContents(), true, getMonitor());
} catch (CoreException e) {
fail("1.99", e);
}
}
/**
* Tests installing and running a builder that always fails during
* instantation.
*/
public void testBrokenBuilder() {
// Create some resource handles
IProject project = getWorkspace().getRoot().getProject("PROJECT");
try {
setAutoBuilding(false);
// Create and open a project
project.create(getMonitor());
project.open(getMonitor());
} catch (CoreException e) {
fail("1.0", e);
}
// Create and set a build spec for the project
try {
IProjectDescription desc = project.getDescription();
ICommand command1 = desc.newCommand();
command1.setBuilderName(BrokenBuilder.BUILDER_NAME);
ICommand command2 = desc.newCommand();
command2.setBuilderName(SortBuilder.BUILDER_NAME);
desc.setBuildSpec(new ICommand[] {command1, command2});
project.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.0", e);
}
//do an incremental build -- build should fail, but second builder
// should run
try {
getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
fail("3.0");
} catch (CoreException e) {
//expected
}
TestBuilder verifier = SortBuilder.getInstance();
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent(TestBuilder.DEFAULT_BUILD_ID);
verifier.assertLifecycleEvents("3.1");
//build again -- it should succeed this time
try {
getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
} catch (CoreException e) {
fail("4.0", e);
}
}
public void testBuildClean() {
// Create some resource handles
IProject project = getWorkspace().getRoot().getProject("PROJECT");
try {
// Turn auto-building off
setAutoBuilding(false);
// Create and open a project
project.create(getMonitor());
project.open(getMonitor());
} catch (CoreException e) {
fail("1.0", e);
}
// Create and set a build spec for the project
try {
IProjectDescription desc = project.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, DeltaVerifierBuilder.BUILDER_NAME, "Project2Build2")});
project.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.0", e);
}
//start with a clean build
try {
getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, getMonitor());
} catch (CoreException e) {
fail("3.1", e);
}
DeltaVerifierBuilder verifier = DeltaVerifierBuilder.getInstance();
assertTrue("3.2", verifier.wasCleanBuild());
// Now do an incremental build - since delta was null it should appear as a clean build
try {
getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
} catch (CoreException e) {
fail("3.3", e);
}
assertTrue("3.4", verifier.wasFullBuild());
// next time it will appear as an incremental build
try {
project.touch(getMonitor());
getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
} catch (CoreException e) {
fail("3.5", e);
}
assertTrue("3.6", verifier.wasIncrementalBuild());
//do another clean
try {
getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, getMonitor());
} catch (CoreException e) {
fail("3.7", e);
}
assertTrue("3.8", verifier.wasCleanBuild());
//doing a full build should still look like a full build
try {
getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
} catch (CoreException e) {
fail("3.9", e);
}
assertTrue("3.10", verifier.wasFullBuild());
}
/**
* Tests the lifecycle of a builder.
*
* @see SortBuilder
*/
public void testBuildCommands() {
// Create some resource handles
IWorkspace workspace = getWorkspace();
IProject project1 = workspace.getRoot().getProject("PROJECT" + 1);
IProject project2 = workspace.getRoot().getProject("PROJECT" + 2);
IFile file1 = project1.getFile("FILE1");
IFile file2 = project2.getFile("FILE2");
//set the build order
try {
IWorkspaceDescription workspaceDesc = workspace.getDescription();
workspaceDesc.setBuildOrder(new String[] {project1.getName(), project2.getName()});
workspace.setDescription(workspaceDesc);
} catch (CoreException e) {
fail("0.0", e);
}
TestBuilder verifier = null;
try {
// Turn auto-building off
setAutoBuilding(false);
// Create some resources
project1.create(getMonitor());
project1.open(getMonitor());
project2.create(getMonitor());
project2.open(getMonitor());
file1.create(getRandomContents(), true, getMonitor());
file2.create(getRandomContents(), true, getMonitor());
// Do an initial build to get the builder instance
IProjectDescription desc = project1.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Project1Build1")});
project1.setDescription(desc, getMonitor());
project1.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier = SortBuilder.getInstance();
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Project1Build1");
verifier.assertLifecycleEvents("1.0");
} catch (CoreException e) {
fail("1.99", e);
}
// Build spec with no commands
try {
IProjectDescription desc = project1.getDescription();
desc.setBuildSpec(new ICommand[] {});
project1.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.99", e);
}
// Build the project -- should do nothing
try {
verifier.reset();
dirty(file1);
project1.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.assertLifecycleEvents("3.1");
} catch (CoreException e) {
fail("3.99", e);
}
// Build command with no arguments -- will use default build ID
try {
IProjectDescription desc = project1.getDescription();
ICommand command = desc.newCommand();
command.setBuilderName(SortBuilder.BUILDER_NAME);
desc.setBuildSpec(new ICommand[] {command});
project1.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("4.99", e);
}
// Build the project
// Note that since the arguments have changed, the identity of the build
// command is different so a new builder will be instantiated
try {
dirty(file1);
project1.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent(TestBuilder.DEFAULT_BUILD_ID);
verifier.assertLifecycleEvents("5.2");
} catch (CoreException e) {
fail("5.99", e);
}
// Create and set a build specs for project one
try {
IProjectDescription desc = project1.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Project1Build1")});
project1.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("6.99", e);
}
// Create and set a build spec for project two
try {
IProjectDescription desc = project2.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, SortBuilder.BUILDER_NAME, "Project2Build1"), createCommand(desc, DeltaVerifierBuilder.BUILDER_NAME, "Project2Build2")});
project2.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("7.99", e);
}
// Build
try {
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Project1Build1");
//second builder is touched for the first time
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Project2Build1");
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Project2Build2");
dirty(file1);
dirty(file2);
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.assertLifecycleEvents("8.0");
verifier.addExpectedLifecycleEvent("Project1Build1");
dirty(file1);
project1.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
verifier.assertLifecycleEvents("8.2");
dirty(file2);
project2.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent("Project2Build1");
verifier.addExpectedLifecycleEvent("Project2Build2");
verifier.assertLifecycleEvents("8.3");
} catch (CoreException e) {
fail("8.99", e);
}
// Change order of build commands
try {
IProjectDescription desc = project2.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, DeltaVerifierBuilder.BUILDER_NAME, "Project2Build2"), createCommand(desc, SortBuilder.BUILDER_NAME, "Project2Build1")});
project2.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("10.99", e);
}
// Build
try {
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent("Project1Build1");
verifier.addExpectedLifecycleEvent("Project2Build2");
verifier.addExpectedLifecycleEvent("Project2Build1");
verifier.assertLifecycleEvents("11.0");
dirty(file1);
dirty(file2);
project1.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent("Project1Build1");
verifier.assertLifecycleEvents("11.2");
dirty(file1);
dirty(file2);
project2.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent("Project2Build2");
verifier.addExpectedLifecycleEvent("Project2Build1");
verifier.assertLifecycleEvents("11.3 ");
} catch (CoreException e) {
fail("11.99", e);
}
}
/**
* Tests that a pre_build listener is not called if there have been no changes
* since the last build of any kind occurred. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=154880.
*/
public void testPreBuildEvent() {
IWorkspace workspace = getWorkspace();
// Create some resource handles
final boolean[] notified = new boolean[] {false};
IProject proj1 = workspace.getRoot().getProject("PROJECT" + 1);
final IResourceChangeListener listener = event -> notified[0] = true;
workspace.addResourceChangeListener(listener, IResourceChangeEvent.PRE_BUILD);
try {
// Turn auto-building off
setAutoBuilding(false);
// Create some resources
proj1.create(getMonitor());
proj1.open(getMonitor());
// Create and set a build spec for project one
IProjectDescription desc = proj1.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build0")});
proj1.setDescription(desc, getMonitor());
proj1.build(IncrementalProjectBuilder.FULL_BUILD, SortBuilder.BUILDER_NAME, new HashMap<String, String>(), null);
notified[0] = false;
//now turn on autobuild and see if the listener is notified again
setAutoBuilding(true);
waitForBuild();
assertTrue("1.0", !notified[0]);
} catch (CoreException e) {
fail("2.99", e);
} finally {
workspace.removeResourceChangeListener(listener);
}
}
/**
* Tests the lifecycle of a builder.
*
* @see SortBuilder
*/
public void testBuildOrder() {
IWorkspace workspace = getWorkspace();
// Create some resource handles
IProject proj1 = workspace.getRoot().getProject("PROJECT" + 1);
IProject proj2 = workspace.getRoot().getProject("PROJECT" + 2);
try {
// Turn auto-building off
setAutoBuilding(false);
// Create some resources
proj1.create(getMonitor());
proj1.open(getMonitor());
proj2.create(getMonitor());
proj2.open(getMonitor());
//set the build order
setBuildOrder(proj1, proj2);
} catch (CoreException e) {
fail("1.99", e);
}
// Create and set a build specs for project one
try {
IProjectDescription desc = proj1.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build0")});
proj1.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.99", e);
}
// Create and set a build spec for project two
try {
IProjectDescription desc = proj2.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build1"), createCommand(desc, "Build2")});
proj2.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("3.99", e);
}
// Set up a plug-in lifecycle verifier for testing purposes
TestBuilder verifier = null;
// Build the workspace
try {
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier = SortBuilder.getInstance();
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Build0");
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Build1");
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Build2");
verifier.assertLifecycleEvents("4.0 ");
} catch (CoreException e) {
fail("4.99", e);
}
//build in reverse order
try {
setBuildOrder(proj2, proj1);
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent("Build1");
verifier.addExpectedLifecycleEvent("Build2");
verifier.addExpectedLifecycleEvent("Build0");
verifier.assertLifecycleEvents("5.0");
} catch (CoreException e) {
fail("5.99");
}
//only specify build order for project1
try {
setBuildOrder(proj1);
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent("Build0");
verifier.addExpectedLifecycleEvent("Build1");
verifier.addExpectedLifecycleEvent("Build2");
verifier.assertLifecycleEvents("6.0");
} catch (CoreException e) {
fail("6.99");
}
//only specify build order for project2
try {
setBuildOrder(proj2, proj1);
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent("Build1");
verifier.addExpectedLifecycleEvent("Build2");
verifier.addExpectedLifecycleEvent("Build0");
verifier.assertLifecycleEvents("7.0");
} catch (CoreException e) {
fail("7.99");
}
}
/**
* Tests that changing the dynamic build order will induce an autobuild on a project.
* This is a regression test for bug 60653.
*/
public void testChangeDynamicBuildOrder() {
IWorkspace workspace = getWorkspace();
// Create some resource handles
final IProject proj1 = workspace.getRoot().getProject("PROJECT" + 1);
final IProject proj2 = workspace.getRoot().getProject("PROJECT" + 2);
try {
// Turn auto-building on and make sure there is no explicit build order
setAutoBuilding(true);
IWorkspaceDescription wsDescription = getWorkspace().getDescription();
wsDescription.setBuildOrder(null);
getWorkspace().setDescription(wsDescription);
// Create and set a build spec for project two
getWorkspace().run((IWorkspaceRunnable) monitor -> {
proj2.create(getMonitor());
proj2.open(getMonitor());
IProjectDescription desc = proj2.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build1")});
proj2.setDescription(desc, getMonitor());
}, getMonitor());
waitForBuild();
} catch (CoreException e) {
fail("1.99", e);
}
// Set up a plug-in lifecycle verifier for testing purposes
TestBuilder verifier = SortBuilder.getInstance();
verifier.reset();
//create project two and establish a build order by adding a dynamic
//reference from proj2->proj1 in the same operation
try {
getWorkspace().run((IWorkspaceRunnable) monitor -> {
// Create and set a build specs for project one
proj1.create(getMonitor());
proj1.open(getMonitor());
IProjectDescription desc = proj1.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build0")});
proj1.setDescription(desc, getMonitor());
//add the dynamic reference to project two
IProjectDescription description = proj2.getDescription();
description.setDynamicReferences(new IProject[] {proj1});
proj2.setDescription(description, IResource.NONE, null);
}, getMonitor());
} catch (CoreException e1) {
fail("2.99", e1);
}
waitForBuild();
//ensure the build happened in the correct order, and that both projects were built
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Build0");
verifier.addExpectedLifecycleEvent("Build1");
verifier.assertLifecycleEvents("3.0");
}
/**
* Tests that changing the dynamic build order during a pre-build notification causes projects
* to be built in the correct order.
* This is a regression test for bug 330194.
*/
public void testChangeDynamicBuildOrderDuringPreBuild() throws Exception {
IWorkspace workspace = getWorkspace();
// Create some resource handles
final IProject proj1 = workspace.getRoot().getProject("bug_330194_referencer");
final IProject proj2 = workspace.getRoot().getProject("bug_330194_referencee");
// Disable workspace auto-build
setAutoBuilding(false);
ensureExistsInWorkspace(proj1, false);
ensureExistsInWorkspace(proj2, false);
IProjectDescription desc = proj1.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build0")});
proj1.setDescription(desc, getMonitor());
desc = proj2.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build1")});
proj2.setDescription(desc, getMonitor());
// Ensure the builder is instantiated
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
// Add pre-build listener that swap around the dependencies
IResourceChangeListener buildListener = event -> {
try {
IProjectDescription desc1 = proj1.getDescription();
IProjectDescription desc2 = proj2.getDescription();
// Swap around the references
if (desc1.getDynamicReferences().length == 0) {
desc1.setDynamicReferences(new IProject[] {proj2});
desc2.setDynamicReferences(new IProject[0]);
} else {
desc1.setDynamicReferences(new IProject[0]);
desc2.setDynamicReferences(new IProject[] {proj1});
}
proj1.setDescription(desc1, getMonitor());
proj2.setDescription(desc2, getMonitor());
} catch (CoreException e) {
fail();
}
};
try {
getWorkspace().addResourceChangeListener(buildListener, IResourceChangeEvent.PRE_BUILD);
// Set up a plug-in lifecycle verifier for testing purposes
TestBuilder verifier = SortBuilder.getInstance();
verifier.reset();
// FULL_BUILD 1
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent("Build1");
verifier.addExpectedLifecycleEvent("Build0");
verifier.assertLifecycleEvents("1.0");
verifier.reset();
// FULL_BUILD 2
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent("Build0");
verifier.addExpectedLifecycleEvent("Build1");
verifier.assertLifecycleEvents("2.0");
verifier.reset();
// AUTO_BUILD
setAutoBuilding(true);
proj1.touch(getMonitor());
waitForBuild();
verifier.addExpectedLifecycleEvent("Build1");
verifier.addExpectedLifecycleEvent("Build0");
verifier.assertLifecycleEvents("3.0");
verifier.reset();
// AUTO_BUILD 2
proj1.touch(getMonitor());
waitForBuild();
verifier.addExpectedLifecycleEvent("Build0");
verifier.addExpectedLifecycleEvent("Build1");
verifier.assertLifecycleEvents("4.0");
verifier.reset();
} finally {
getWorkspace().removeResourceChangeListener(buildListener);
}
}
/**
* Ensure that build order is preserved when project is closed/opened.
*/
public void testCloseOpenProject() {
IWorkspace workspace = getWorkspace();
IProject project = workspace.getRoot().getProject("PROJECT" + 1);
try {
// Create some resources
project.create(getMonitor());
project.open(getMonitor());
} catch (CoreException e) {
fail("1.99", e);
}
// Create and set a build spec
try {
IProjectDescription desc = project.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build1"), createCommand(desc, "Build2")});
project.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.99", e);
}
try {
project.close(getMonitor());
project.open(getMonitor());
} catch (CoreException e) {
fail("3.99", e);
}
//ensure the build spec hasn't changed
try {
IProjectDescription desc = project.getDescription();
ICommand[] commands = desc.getBuildSpec();
assertEquals("4.0", 2, commands.length);
assertEquals("4.1", commands[0].getBuilderName(), SortBuilder.BUILDER_NAME);
assertEquals("4.2", commands[1].getBuilderName(), SortBuilder.BUILDER_NAME);
Map<String, String> args = commands[0].getArguments();
assertEquals("4.3", "Build1", args.get(TestBuilder.BUILD_ID));
args = commands[1].getArguments();
assertEquals("4.4", "Build2", args.get(TestBuilder.BUILD_ID));
} catch (CoreException e) {
fail("4.99", e);
}
}
/**
* Tests that when a project is copied, the copied project has a full build
* but the source project does not.
*/
public void testCopyProject() {
IWorkspace workspace = getWorkspace();
// Create some resource handles
IProject proj1 = workspace.getRoot().getProject("testCopyProject" + 1);
IProject proj2 = workspace.getRoot().getProject("testCopyProject" + 2);
try {
// Turn auto-building on
setAutoBuilding(true);
// Create some resources
proj1.create(getMonitor());
proj1.open(getMonitor());
ensureDoesNotExistInWorkspace(proj2);
} catch (CoreException e) {
fail("1.99", e);
}
// Create and set a build spec for project one
try {
IProjectDescription desc = proj1.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build0")});
proj1.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.99", e);
}
waitForBuild();
SortBuilder.getInstance().reset();
try {
IProjectDescription desc = proj1.getDescription();
desc.setName(proj2.getName());
proj1.copy(desc, IResource.NONE, getMonitor());
} catch (CoreException e) {
fail("3.99", e);
}
waitForBuild();
SortBuilder builder = SortBuilder.getInstance();
assertEquals("4.0", proj2, builder.getProject());
//builder 2 should have done a full build
builder.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
builder.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
builder.addExpectedLifecycleEvent("Build0");
builder.assertLifecycleEvents("4.4");
assertTrue("4.5", builder.wasFullBuild());
}
/**
* Tests an implicit workspace build order created by setting dynamic
* project references.
*/
public void testDynamicBuildOrder() {
IWorkspace workspace = getWorkspace();
// Create some resource handles
IProject proj1 = workspace.getRoot().getProject("PROJECT" + 1);
IProject proj2 = workspace.getRoot().getProject("PROJECT" + 2);
try {
// Turn auto-building off
setAutoBuilding(false);
// Create some resources
proj1.create(getMonitor());
proj1.open(getMonitor());
proj2.create(getMonitor());
proj2.open(getMonitor());
//establish a build order by adding a dynamic reference from
// proj2->proj1
IProjectDescription description = proj2.getDescription();
description.setDynamicReferences(new IProject[] {proj1});
proj2.setDescription(description, IResource.NONE, null);
IWorkspaceDescription wsDescription = getWorkspace().getDescription();
wsDescription.setBuildOrder(null);
getWorkspace().setDescription(wsDescription);
} catch (CoreException e) {
fail("1.99", e);
}
// Create and set a build specs for project one
try {
IProjectDescription desc = proj1.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build0")});
proj1.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.99", e);
}
// Create and set a build spec for project two
try {
IProjectDescription desc = proj2.getDescription();
desc.setBuildSpec(new ICommand[] {createCommand(desc, "Build1"), createCommand(desc, "Build2")});
proj2.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("3.99", e);
}
// Set up a plug-in lifecycle verifier for testing purposes
TestBuilder verifier = null;
// Build the workspace
try {
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier = SortBuilder.getInstance();
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Build0");
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Build1");
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent("Build2");
verifier.assertLifecycleEvents("4.0 ");
} catch (CoreException e) {
fail("4.99", e);
}
//build in reverse order
try {
//reverse the order by adding a dynamic reference from proj1->proj2
IProjectDescription description = proj2.getDescription();
description.setDynamicReferences(new IProject[0]);
proj2.setDescription(description, IResource.NONE, null);
description = proj1.getDescription();
description.setDynamicReferences(new IProject[] {proj2});
proj1.setDescription(description, IResource.NONE, null);
workspace.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent("Build1");
verifier.addExpectedLifecycleEvent("Build2");
verifier.addExpectedLifecycleEvent("Build0");
verifier.assertLifecycleEvents("5.0");
} catch (CoreException e) {
fail("5.99");
}
}
/**
* Tests that enabling autobuild causes a build to occur.
*/
public void testEnableAutobuild() {
// Create some resource handles
IProject project = getWorkspace().getRoot().getProject("PROJECT");
try {
// Turn auto-building off
setAutoBuilding(false);
// Create and open a project
project.create(getMonitor());
project.open(getMonitor());
} catch (CoreException e) {
fail("1.0", e);
}
// Create and set a build spec for the project
try {
IProjectDescription desc = project.getDescription();
ICommand command = desc.newCommand();
command.setBuilderName(SortBuilder.BUILDER_NAME);
desc.setBuildSpec(new ICommand[] {command});
project.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.0", e);
}
// Set up a plug-in lifecycle verifier for testing purposes
TestBuilder verifier = null;
//Cause a build by enabling autobuild
try {
setAutoBuilding(true);
waitForBuild();
verifier = SortBuilder.getInstance();
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent(TestBuilder.DEFAULT_BUILD_ID);
verifier.assertLifecycleEvents("3.1");
} catch (CoreException e) {
fail("3.2", e);
}
}
/**
* Tests installing and running a builder that always fails in its build method
*/
public void testExceptionBuilder() {
// Create some resource handles
IProject project = getWorkspace().getRoot().getProject("PROJECT");
try {
setAutoBuilding(false);
// Create and open a project
project.create(getMonitor());
project.open(getMonitor());
} catch (CoreException e) {
fail("1.0", e);
}
// Create and set a build spec for the project
try {
IProjectDescription desc = project.getDescription();
ICommand command1 = desc.newCommand();
command1.setBuilderName(ExceptionBuilder.BUILDER_NAME);
desc.setBuildSpec(new ICommand[] {command1});
project.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.0", e);
}
final boolean[] listenerCalled = new boolean[] {false};
IResourceChangeListener listener = event -> listenerCalled[0] = true;
getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_BUILD);
//do an incremental build -- build should fail, but POST_BUILD should still occur
try {
getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
fail("3.0");
} catch (CoreException e) {
//see discussion in bug 273147 about build exception severity
assertEquals("3.1", IStatus.ERROR, e.getStatus().getSeverity());
//expected
} finally {
getWorkspace().removeResourceChangeListener(listener);
}
assertTrue("1.0", listenerCalled[0]);
}
/**
* Tests the method IncrementProjectBuilder.forgetLastBuiltState
*/
public void testForgetLastBuiltState() {
// Create some resource handles
IProject project = getWorkspace().getRoot().getProject("PROJECT");
try {
// Turn auto-building off
setAutoBuilding(false);
// Create and open a project
project.create(getMonitor());
project.open(getMonitor());
} catch (CoreException e) {
fail("1.0", e);
}
// Create and set a build spec for the project
try {
IProjectDescription desc = project.getDescription();
ICommand command = desc.newCommand();
command.setBuilderName(SortBuilder.BUILDER_NAME);
desc.setBuildSpec(new ICommand[] {command});
project.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.0", e);
}
// Set up a plug-in lifecycle verifier for testing purposes
SortBuilder verifier = null;
//do an initial build
try {
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, SortBuilder.BUILDER_NAME, null, getMonitor());
verifier = SortBuilder.getInstance();
} catch (CoreException e) {
fail("3.2", e);
}
//forget last built state
verifier.forgetLastBuiltState();
// Now do another incremental build. Delta should be null
try {
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, SortBuilder.BUILDER_NAME, null, getMonitor());
assertTrue("4.0", verifier.wasDeltaNull());
} catch (CoreException e) {
fail("4.99", e);
}
// Do another incremental build, requesting a null build state. Delta
// should not be null
verifier.requestForgetLastBuildState();
try {
project.touch(getMonitor());
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, SortBuilder.BUILDER_NAME, null, getMonitor());
assertTrue("5.0", !verifier.wasDeltaNull());
} catch (CoreException e) {
fail("5.99", e);
}
//try a snapshot when a builder has a null tree
try {
getWorkspace().save(false, getMonitor());
} catch (CoreException e) {
fail("6.99");
}
// Do another incremental build. Delta should be null
try {
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, SortBuilder.BUILDER_NAME, null, getMonitor());
assertTrue("7.0", verifier.wasDeltaNull());
} catch (CoreException e) {
fail("7.99", e);
}
// Delete the project
try {
project.delete(false, getMonitor());
} catch (CoreException e) {
fail("99.99", e);
}
}
/**
* Tests that a client invoking a manual incremental build before autobuild has had
* a chance to run will block until the build completes. See bug 275879.
*/
public void testIncrementalBuildBeforeAutobuild() {
// Create some resource handles
final IProject project = getWorkspace().getRoot().getProject("PROJECT");
final IFile input = project.getFolder(SortBuilder.DEFAULT_UNSORTED_FOLDER).getFile("File.txt");
final IFile output = project.getFolder(SortBuilder.DEFAULT_SORTED_FOLDER).getFile("File.txt");
try {
setAutoBuilding(true);
// Create and open a project
project.create(getMonitor());
project.open(getMonitor());
IProjectDescription desc = project.getDescription();
ICommand command = desc.newCommand();
command.setBuilderName(SortBuilder.BUILDER_NAME);
desc.setBuildSpec(new ICommand[] {command});
project.setDescription(desc, getMonitor());
ensureExistsInWorkspace(input, getRandomContents());
} catch (CoreException e) {
fail("0.99", e);
}
waitForBuild();
assertTrue("1.0", output.exists());
//change the file and then immediately perform build
final ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
getWorkspace().run((IWorkspaceRunnable) monitor -> {
input.setContents(new ByteArrayInputStream(new byte[] {5, 4, 3, 2, 1}), IResource.NONE, getMonitor());
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
transferStreams(output.getContents(), out, null, null);
}, getMonitor());
} catch (CoreException e) {
fail("1.99", e);
}
byte[] result = out.toByteArray();
byte[] expected = new byte[] {1, 2, 3, 4, 5};
assertEquals("2.0", expected.length, result.length);
for (int i = 0; i < expected.length; i++) {
assertEquals("2.1." + i, expected[i], result[i]);
}
}
/**
* Tests that autobuild is interrupted by a background scheduled job, but eventually completes.
*/
public void testInterruptAutobuild() {
// Create some resource handles
IProject project = getWorkspace().getRoot().getProject("PROJECT");
final IFile file = project.getFile("File.txt");
try {
setAutoBuilding(true);
// Create and open a project
project.create(getMonitor());
project.open(getMonitor());
IProjectDescription desc = project.getDescription();
ICommand command = desc.newCommand();
command.setBuilderName(SortBuilder.BUILDER_NAME);
desc.setBuildSpec(new ICommand[] {command});
project.setDescription(desc, getMonitor());
file.create(getRandomContents(), IResource.NONE, getMonitor());
} catch (CoreException e) {
fail("1.0", e);
}
waitForBuild();
// Set up a plug-in lifecycle verifier for testing purposes
TestBuilder verifier = SortBuilder.getInstance();
verifier.reset();
final TestJob blockedJob = new TestJob("Interrupt build", 3, 1000);
blockedJob.setRule(getWorkspace().getRoot());
//use a barrier to ensure the blocking job starts
final TestBarrier barrier = new TestBarrier();
barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_START);
//install a listener that will cause autobuild to be interrupted
IResourceChangeListener listener = event -> {
blockedJob.schedule();
//wait for autobuild to become blocking
while (!Job.getJobManager().currentJob().isBlocking()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
//ignore
}
}
//allow the test main method to continue
barrier.setStatus(TestBarrier.STATUS_RUNNING);
};
try {
getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.PRE_BUILD);
// Now change a file. The build should not complete until the job triggered by the listener completes
file.setContents(getRandomContents(), IResource.NONE, getMonitor());
//wait for job to be scheduled
barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
//wait for test job to complete
try {
blockedJob.join();
} catch (InterruptedException e) {
fail("1.99", e);
}
//autobuild should now run after the blocking job is finished
waitForBuild();
verifier.addExpectedLifecycleEvent(TestBuilder.DEFAULT_BUILD_ID);
verifier.assertLifecycleEvents("2.0");
} catch (CoreException e) {
fail("2.99", e);
} finally {
getWorkspace().removeResourceChangeListener(listener);
}
}
/**
* Tests the lifecycle of a builder.
*/
public void testLifecycleEvents() {
// Create some resource handles
IProject project = getWorkspace().getRoot().getProject("PROJECT");
try {
// Turn auto-building off
setAutoBuilding(false);
// Create and open a project
project.create(getMonitor());
project.open(getMonitor());
} catch (CoreException e) {
fail("1.0", e);
}
// Create and set a build spec for the project
try {
IProjectDescription desc = project.getDescription();
ICommand command = desc.newCommand();
command.setBuilderName(SortBuilder.BUILDER_NAME);
desc.setBuildSpec(new ICommand[] {command});
project.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.0", e);
}
// Set up a plug-in lifecycle verifier for testing purposes
TestBuilder verifier = null;
//try to do an incremental build when there has never
//been a batch build
try {
getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
verifier = SortBuilder.getInstance();
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent(TestBuilder.DEFAULT_BUILD_ID);
verifier.assertLifecycleEvents("3.1");
} catch (CoreException e) {
fail("3.2", e);
}
// Now do another incremental build. Since we just did one, nothing
// should happen in this one.
try {
getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
verifier.assertLifecycleEvents("3.4");
} catch (CoreException e) {
fail("3.5", e);
}
// Now do a batch build
try {
getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
verifier.addExpectedLifecycleEvent(TestBuilder.DEFAULT_BUILD_ID);
verifier.assertLifecycleEvents("3.6");
} catch (CoreException e) {
fail("3.8", e);
}
// Close the project
try {
project.close(getMonitor());
} catch (CoreException e) {
fail("4.1", e);
}
// Open the project, build it, and delete it
try {
project.open(getMonitor());
getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
project.delete(false, getMonitor());
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent(TestBuilder.DEFAULT_BUILD_ID);
verifier.assertLifecycleEvents("5.0");
} catch (CoreException e) {
fail("5.1", e);
}
}
/**
* Tests the lifecycle of a builder.
*
* @see SortBuilder
*/
public void testMoveProject() {
// Create some resource handles
IWorkspace workspace = getWorkspace();
IProject proj1 = workspace.getRoot().getProject("PROJECT" + 1);
IProject proj2 = workspace.getRoot().getProject("Destination");
try {
// Turn auto-building off
setAutoBuilding(false);
// Create some resources
proj1.create(getMonitor());
proj1.open(getMonitor());
} catch (CoreException e) {
fail("1.0", e);
}
// Create and set a build specs for project one
try {
IProjectDescription desc = proj1.getDescription();
ICommand command = desc.newCommand();
command.setBuilderName(SortBuilder.BUILDER_NAME);
command.getArguments().put(TestBuilder.BUILD_ID, "Build0");
desc.setBuildSpec(new ICommand[] {command});
proj1.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.0", e);
}
// build project1
try {
proj1.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor());
} catch (CoreException e) {
fail("3.0", e);
}
// move proj1 to proj2
try {
proj1.move(proj2.getFullPath(), false, getMonitor());
} catch (CoreException e) {
fail("4.0", e);
}
// build proj2
try {
proj2.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
} catch (CoreException e) {
fail("5.0", e);
}
}
/**
* Tests that turning autobuild on will invoke a build in the next
* operation.
*/
public void testTurnOnAutobuild() throws CoreException {
// Create some resource handles
IProject project = getWorkspace().getRoot().getProject("PROJECT");
final IFile file = project.getFile("File.txt");
try {
// Turn auto-building off
setAutoBuilding(false);
// Create and open a project
project.create(getMonitor());
project.open(getMonitor());
file.create(getRandomContents(), IResource.NONE, getMonitor());
} catch (CoreException e) {
fail("1.0", e);
}
// Create and set a build spec for the project
try {
IProjectDescription desc = project.getDescription();
ICommand command = desc.newCommand();
command.setBuilderName(SortBuilder.BUILDER_NAME);
desc.setBuildSpec(new ICommand[] {command});
project.setDescription(desc, getMonitor());
} catch (CoreException e) {
fail("2.0", e);
}
// Set up a plug-in lifecycle verifier for testing purposes
TestBuilder verifier = null;
//try to do an incremental build when there has never
//been a batch build
try {
getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, getMonitor());
verifier = SortBuilder.getInstance();
verifier.addExpectedLifecycleEvent(TestBuilder.SET_INITIALIZATION_DATA);
verifier.addExpectedLifecycleEvent(TestBuilder.STARTUP_ON_INITIALIZE);
verifier.addExpectedLifecycleEvent(TestBuilder.DEFAULT_BUILD_ID);
verifier.assertLifecycleEvents("3.1");
} catch (CoreException e) {
fail("3.2", e);
}
// Now make a change and then turn autobuild on. Turning it on should
// cause a build.
IWorkspaceRunnable r = monitor -> {
file.setContents(getRandomContents(), IResource.NONE, getMonitor());
IWorkspaceDescription desc = getWorkspace().getDescription();
desc.setAutoBuilding(true);
getWorkspace().setDescription(desc);
};
waitForBuild();
getWorkspace().run(r, getMonitor());
waitForBuild();
verifier.addExpectedLifecycleEvent(TestBuilder.DEFAULT_BUILD_ID);
verifier.assertLifecycleEvents("4.0");
}
}