/******************************************************************************* * Copyright (c) 2010, 2015 Broadcom 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: * Broadcom Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.core.tests.internal.builders; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.internal.events.BuildContext; import org.eclipse.core.internal.resources.BuildConfiguration; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.CoreException; /** * These tests exercise the build context functionality that tells a builder in what context * it was called. */ public class BuildContextTest extends AbstractBuilderTest { public static Test suite() { return new TestSuite(BuildContextTest.class); } private IProject project0; private IProject project1; private IProject project2; private final String variant0 = "Variant0"; private final String variant1 = "Variant1"; public BuildContextTest(String name) { super(name); } @Override protected void setUp() throws Exception { super.setUp(); // Create resources IWorkspaceRoot root = getWorkspace().getRoot(); project0 = root.getProject("BuildContextTests_p0"); project1 = root.getProject("BuildContextTests_p1"); project2 = root.getProject("BuildContextTests_p2"); IResource[] resources = {project0, project1, project2}; ensureExistsInWorkspace(resources, true); setAutoBuilding(false); setupProject(project0); setupProject(project1); setupProject(project2); } @Override protected void tearDown() throws Exception { super.tearDown(); // Cleanup project0.delete(true, null); project1.delete(true, null); project2.delete(true, null); } /** * Helper method to configure a project with a build command and several buildConfigs. */ private void setupProject(IProject project) throws CoreException { IProjectDescription desc = project.getDescription(); // Add build command ICommand command = createCommand(desc, ContextBuilder.BUILDER_NAME, "Build0"); command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, true); command.setBuilding(IncrementalProjectBuilder.FULL_BUILD, true); command.setBuilding(IncrementalProjectBuilder.INCREMENTAL_BUILD, true); command.setBuilding(IncrementalProjectBuilder.CLEAN_BUILD, true); desc.setBuildSpec(new ICommand[] {command}); // Create buildConfigs desc.setBuildConfigs(new String[] {variant0, variant1}); project.setDescription(desc, getMonitor()); } /** * Change the active build configuration on the project returning the new active build configuration */ private IBuildConfiguration changeActiveBuildConfig(IProject project) throws CoreException { IBuildConfiguration[] configs = project.getBuildConfigs(); IBuildConfiguration active = project.getActiveBuildConfig(); IProjectDescription desc = project.getDescription(); for (IBuildConfiguration config : configs) { if (!config.equals(active)) { desc.setActiveBuildConfig(config.getName()); project.setDescription(desc, getMonitor()); return config; } } assertTrue(false); return null; } /** * p0 --> p1 --> p2 * @throws CoreException */ private void setupSimpleReferences() throws CoreException { setReferences(project0.getActiveBuildConfig(), new IBuildConfiguration[] {project1.getActiveBuildConfig()}); setReferences(project1.getActiveBuildConfig(), new IBuildConfiguration[] {project2.getActiveBuildConfig()}); setReferences(project2.getActiveBuildConfig(), new IBuildConfiguration[] {}); } /** * Helper method to set the references for a project. */ private void setReferences(IBuildConfiguration variant, IBuildConfiguration[] refs) throws CoreException { IProjectDescription desc = variant.getProject().getDescription(); desc.setBuildConfigReferences(variant.getName(), refs); variant.getProject().setDescription(desc, getMonitor()); } /** * Setup a reference graph, then test the build context for for each project involved * in the 'build'. */ public void testBuildContext() { // Create reference graph IBuildConfiguration p0v0 = getWorkspace().newBuildConfig(project0.getName(), variant0); IBuildConfiguration p0v1 = getWorkspace().newBuildConfig(project0.getName(), variant1); IBuildConfiguration p1v0 = getWorkspace().newBuildConfig(project1.getName(), variant0); // Create build order final IBuildConfiguration[] buildOrder = new IBuildConfiguration[] {p0v0, p0v1, p1v0}; IBuildContext context; context = new BuildContext(p0v0, new IBuildConfiguration[] {p0v0, p1v0}, buildOrder); assertEquals("1.0", new IBuildConfiguration[] {}, context.getAllReferencedBuildConfigs()); assertEquals("1.1", new IBuildConfiguration[] {p0v1, p1v0}, context.getAllReferencingBuildConfigs()); assertEquals("1.2", new IBuildConfiguration[] {p0v0, p1v0}, context.getRequestedConfigs()); context = new BuildContext(p0v1, buildOrder, buildOrder); assertEquals("2.0", new IBuildConfiguration[] {p0v0}, context.getAllReferencedBuildConfigs()); assertEquals("2.1", new IBuildConfiguration[] {p1v0}, context.getAllReferencingBuildConfigs()); context = new BuildContext(p1v0, buildOrder, buildOrder); assertEquals("3.0", new IBuildConfiguration[] {p0v0, p0v1}, context.getAllReferencedBuildConfigs()); assertEquals("3.1", new IBuildConfiguration[] {}, context.getAllReferencingBuildConfigs()); // And it works with no build context too context = new BuildContext(p1v0); assertEquals("4.0", new IBuildConfiguration[] {}, context.getAllReferencedBuildConfigs()); assertEquals("4.1", new IBuildConfiguration[] {}, context.getAllReferencingBuildConfigs()); } public void testSingleProjectBuild() throws CoreException { setAutoBuilding(true); setupSimpleReferences(); ContextBuilder.clearStats(); project0.build(IncrementalProjectBuilder.FULL_BUILD, getMonitor()); assertTrue("1.0", ContextBuilder.checkValid()); IBuildContext context = ContextBuilder.getContext(project0.getActiveBuildConfig()); assertEquals("2.0", 0, context.getAllReferencedBuildConfigs().length); assertEquals("2.1", 0, context.getAllReferencingBuildConfigs().length); // Change the active build configuration will cause the project to be rebuilt ContextBuilder.clearStats(); IBuildConfiguration newActive = changeActiveBuildConfig(project0); waitForBuild(); assertTrue("3.0", ContextBuilder.checkValid()); context = ContextBuilder.getContext(newActive); assertEquals("3.1", 0, context.getAllReferencedBuildConfigs().length); } /** * Tests building a single project with and without references * @throws CoreException */ public void testWorkspaceBuildProject() throws CoreException { setupSimpleReferences(); ContextBuilder.clearStats(); // Build project and resolve references getWorkspace().build(new IBuildConfiguration[] {project0.getActiveBuildConfig()}, IncrementalProjectBuilder.FULL_BUILD, true, getMonitor()); assertTrue("1.0", ContextBuilder.checkValid()); IBuildContext context = ContextBuilder.getContext(project0.getActiveBuildConfig()); assertEquals("2.0", new IBuildConfiguration[] {project2.getActiveBuildConfig(), project1.getActiveBuildConfig()}, context.getAllReferencedBuildConfigs()); assertEquals("2.1", 0, context.getAllReferencingBuildConfigs().length); context = ContextBuilder.getBuilder(project1.getActiveBuildConfig()).contextForLastBuild; assertEquals("3.0", new IBuildConfiguration[] {project2.getActiveBuildConfig()}, context.getAllReferencedBuildConfigs()); assertEquals("3.1", new IBuildConfiguration[] {project0.getActiveBuildConfig()}, context.getAllReferencingBuildConfigs()); context = ContextBuilder.getBuilder(project2.getActiveBuildConfig()).contextForLastBuild; assertEquals("4.0", 0, context.getAllReferencedBuildConfigs().length); assertEquals("4.1", new IBuildConfiguration[] {project1.getActiveBuildConfig(), project0.getActiveBuildConfig()}, context.getAllReferencingBuildConfigs()); // Build just project0 ContextBuilder.clearStats(); getWorkspace().build(new IBuildConfiguration[] {project0.getActiveBuildConfig()}, IncrementalProjectBuilder.FULL_BUILD, false, getMonitor()); assertTrue("5.0", ContextBuilder.checkValid()); context = ContextBuilder.getContext(project0.getActiveBuildConfig()); assertTrue("5.1", context.getAllReferencedBuildConfigs().length == 0); assertTrue("5.2", context.getAllReferencingBuildConfigs().length == 0); } /** * Builds a couple configurations, including references * @throws CoreException */ public void testWorkspaceBuildProjects() throws CoreException { setupSimpleReferences(); ContextBuilder.clearStats(); // build project0 & project2 ; project1 will end up being built too. getWorkspace().build(new IBuildConfiguration[] {project0.getActiveBuildConfig(), project2.getActiveBuildConfig()}, IncrementalProjectBuilder.FULL_BUILD, true, getMonitor()); assertTrue("1.0", ContextBuilder.checkValid()); IBuildContext context = ContextBuilder.getContext(project0.getActiveBuildConfig()); assertEquals("2.0", new IBuildConfiguration[] {project2.getActiveBuildConfig(), project1.getActiveBuildConfig()}, context.getAllReferencedBuildConfigs()); assertEquals("2.1", 0, context.getAllReferencingBuildConfigs().length); context = ContextBuilder.getBuilder(project1.getActiveBuildConfig()).contextForLastBuild; assertEquals("3.0", new IBuildConfiguration[] {project2.getActiveBuildConfig()}, context.getAllReferencedBuildConfigs()); assertEquals("3.1", new IBuildConfiguration[] {project0.getActiveBuildConfig()}, context.getAllReferencingBuildConfigs()); context = ContextBuilder.getBuilder(project2.getActiveBuildConfig()).contextForLastBuild; assertEquals("4.0", 0, context.getAllReferencedBuildConfigs().length); assertEquals("4.1", new IBuildConfiguration[] {project1.getActiveBuildConfig(), project0.getActiveBuildConfig()}, context.getAllReferencingBuildConfigs()); } /** * Sets references to the 'active' project build configuration * @throws CoreException */ public void testReferenceActiveVariant() throws CoreException { setReferences(project0.getActiveBuildConfig(), new IBuildConfiguration[] {getWorkspace().newBuildConfig(project1.getName(), null)}); setReferences(project1.getActiveBuildConfig(), new IBuildConfiguration[] {getWorkspace().newBuildConfig(project2.getName(), null)}); setReferences(project2.getActiveBuildConfig(), new IBuildConfiguration[] {}); ContextBuilder.clearStats(); getWorkspace().build(new IBuildConfiguration[] {project0.getActiveBuildConfig()}, IncrementalProjectBuilder.FULL_BUILD, true, getMonitor()); assertTrue("1.0", ContextBuilder.checkValid()); IBuildContext context = ContextBuilder.getContext(project0.getActiveBuildConfig()); assertEquals("2.0", new IBuildConfiguration[] {project2.getActiveBuildConfig(), project1.getActiveBuildConfig()}, context.getAllReferencedBuildConfigs()); assertEquals("2.1", 0, context.getAllReferencingBuildConfigs().length); context = ContextBuilder.getBuilder(project1.getActiveBuildConfig()).contextForLastBuild; assertEquals("3.0", new IBuildConfiguration[] {project2.getActiveBuildConfig()}, context.getAllReferencedBuildConfigs()); assertEquals("3.1", new IBuildConfiguration[] {project0.getActiveBuildConfig()}, context.getAllReferencingBuildConfigs()); context = ContextBuilder.getBuilder(project2.getActiveBuildConfig()).contextForLastBuild; assertEquals("4.0", 0, context.getAllReferencedBuildConfigs().length); assertEquals("4.1", new IBuildConfiguration[] {project1.getActiveBuildConfig(), project0.getActiveBuildConfig()}, context.getAllReferencingBuildConfigs()); } /** * Attempts to build a project that references the active variant of another project, * and the same variant directly. This should only result in one referenced variant being built. */ public void testReferenceVariantTwice() throws CoreException { IBuildConfiguration ref1 = new BuildConfiguration(project1, null); IBuildConfiguration ref2 = new BuildConfiguration(project1, project1.getActiveBuildConfig().getName()); setReferences(project0.getActiveBuildConfig(), new IBuildConfiguration[] {ref1, ref2}); setReferences(project1.getActiveBuildConfig(), new IBuildConfiguration[] {}); ContextBuilder.clearStats(); getWorkspace().build(new IBuildConfiguration[] {project0.getActiveBuildConfig()}, IncrementalProjectBuilder.FULL_BUILD, true, getMonitor()); assertTrue("1.0", ContextBuilder.checkValid()); IBuildContext context = ContextBuilder.getContext(project0.getActiveBuildConfig()); assertEquals("2.0", new IBuildConfiguration[] {project1.getActiveBuildConfig()}, context.getAllReferencedBuildConfigs()); assertEquals("2.1", 0, context.getAllReferencingBuildConfigs().length); assertEquals("2.2", new IBuildConfiguration[] {project0.getActiveBuildConfig()}, context.getRequestedConfigs()); context = ContextBuilder.getBuilder(project1.getActiveBuildConfig()).contextForLastBuild; assertEquals("3.0", 0, context.getAllReferencedBuildConfigs().length); assertEquals("3.1", new IBuildConfiguration[] {project0.getActiveBuildConfig()}, context.getAllReferencingBuildConfigs()); // Change the active configuration of project1, and test that two configurations are built ContextBuilder.clearStats(); IBuildConfiguration project1PreviousActive = project1.getActiveBuildConfig(); IBuildConfiguration project1NewActive = changeActiveBuildConfig(project1); getWorkspace().build(new IBuildConfiguration[] {project0.getActiveBuildConfig()}, IncrementalProjectBuilder.FULL_BUILD, true, getMonitor()); assertTrue("4.0", ContextBuilder.checkValid()); context = ContextBuilder.getContext(project0.getActiveBuildConfig()); assertEquals("4.1", new IBuildConfiguration[] {project1PreviousActive, project1NewActive}, context.getAllReferencedBuildConfigs()); assertEquals("4.2", 0, context.getAllReferencingBuildConfigs().length); assertEquals("4.3", new IBuildConfiguration[] {project0.getActiveBuildConfig()}, context.getRequestedConfigs()); } }