diff --git a/core/src/main/java/hudson/EnvVars.java b/core/src/main/java/hudson/EnvVars.java index 7fd7b9f7d1bb5266b1f4e633202d23995eaaf8d8..94a7c7b649965c4961a6d6a5bdc766e4e0fddfef 100644 --- a/core/src/main/java/hudson/EnvVars.java +++ b/core/src/main/java/hudson/EnvVars.java @@ -91,10 +91,15 @@ public class EnvVars extends TreeMap { put(key,value); } - public void overrideAll(Map all) { + /** + * Overrides all values in the map. See #override + * @return this + */ + public EnvVars overrideAll(Map all) { for (Map.Entry e : all.entrySet()) { override(e.getKey(),e.getValue()); } + return this; } /** @@ -129,9 +134,9 @@ public class EnvVars extends TreeMap { * @param channel * Can be null, in which case the map indicating "N/A" will be returned. */ - public static Map getRemote(VirtualChannel channel) throws IOException, InterruptedException { + public static EnvVars getRemote(VirtualChannel channel) throws IOException, InterruptedException { if(channel==null) - return Collections.singletonMap("N/A","N/A"); + return new EnvVars("N/A","N/A"); return new EnvVars(channel.call(new GetEnvVars())); } diff --git a/core/src/main/java/hudson/maven/MavenBuild.java b/core/src/main/java/hudson/maven/MavenBuild.java index 0796458d7c5cf229a67043ee97f8059714b82163..4f57c7dadd359ea65511d4da3758100ac3784737 100644 --- a/core/src/main/java/hudson/maven/MavenBuild.java +++ b/core/src/main/java/hudson/maven/MavenBuild.java @@ -25,6 +25,7 @@ package hudson.maven; import hudson.FilePath; import hudson.Util; +import hudson.EnvVars; import hudson.maven.agent.AbortException; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; @@ -454,8 +455,8 @@ public class MavenBuild extends AbstractBuild { if(debug) listener.getLogger().println("Reporters="+reporters); - Map envVars = getEnvVars(); - + EnvVars envVars = EnvVars.getRemote(launcher.getChannel()).overrideAll(getEnvVars()); + ProcessCache.MavenProcess process = mavenProcessCache.get(launcher.getChannel(), listener, new MavenProcessFactory(getParent().getParent(),launcher,envVars,null)); diff --git a/core/src/main/java/hudson/maven/MavenModuleSet.java b/core/src/main/java/hudson/maven/MavenModuleSet.java index 9dce8a3a93c6eea8b77736bd9091378f236b48d2..f9bb106d3d09c4afd86b3c74bfb1b68894b09219 100644 --- a/core/src/main/java/hudson/maven/MavenModuleSet.java +++ b/core/src/main/java/hudson/maven/MavenModuleSet.java @@ -470,6 +470,10 @@ public final class MavenModuleSet extends AbstractMavenProject asProject() { return this; } @@ -485,6 +489,10 @@ public final class MavenModuleSet extends AbstractMavenProject getMavenArgument(String shortForm, String longForm) { List args = new ArrayList(); boolean switchFound=false; @@ -549,6 +557,10 @@ public final class MavenModuleSet extends AbstractMavenProject envVars = getEnvVars(); ProcessCache.MavenProcess process = MavenBuild.mavenProcessCache.get(launcher.getChannel(), slistener, new MavenProcessFactory(project,launcher,envVars,pom.getParent())); @@ -360,7 +365,7 @@ public final class MavenModuleSetBuild extends AbstractBuild poms; try { diff --git a/core/src/main/java/hudson/maven/MavenProcessFactory.java b/core/src/main/java/hudson/maven/MavenProcessFactory.java index 271d6c6dfb28d5dc087bea984e05ff79b9247868..5e0acb364eb4973b30cf451301fa634dc5205b26 100644 --- a/core/src/main/java/hudson/maven/MavenProcessFactory.java +++ b/core/src/main/java/hudson/maven/MavenProcessFactory.java @@ -27,6 +27,7 @@ import hudson.FilePath; import hudson.Launcher; import hudson.Proc; import hudson.AbortException; +import hudson.EnvVars; import static hudson.Util.fixNull; import hudson.maven.agent.Main; import hudson.model.BuildListener; @@ -81,7 +82,7 @@ final class MavenProcessFactory implements ProcessCache.Factory { * Environment variables to be set to the maven process. * The same variables are exposed to the system property as well. */ - private final Map envVars; + private final EnvVars envVars; /** * Optional working directory. Because of the process reuse, we can't always guarantee @@ -93,7 +94,7 @@ final class MavenProcessFactory implements ProcessCache.Factory { */ private final FilePath workDir; - MavenProcessFactory(MavenModuleSet mms, Launcher launcher, Map envVars, FilePath workDir) { + MavenProcessFactory(MavenModuleSet mms, Launcher launcher, EnvVars envVars, FilePath workDir) { this.mms = mms; this.launcher = launcher; this.envVars = envVars; @@ -281,11 +282,12 @@ final class MavenProcessFactory implements ProcessCache.Factory { slaveRoot = getCurrentNode().getRootPath(); ArgumentListBuilder args = new ArgumentListBuilder(); - JDK jdk = mms.getJDK(); - if(jdk==null) + JDK jdk = getJava(); + if(jdk==null) { args.add("java"); - else - args.add(jdk.getJavaHome()+"/bin/java"); + } else { + args.add(jdk.getJavaHome()+"/bin/java"); // use JDK.getExecutable() here ? + } if(debugPort!=0) args.add("-Xrunjdwp:transport=dt_socket,server=y,address="+debugPort); @@ -320,22 +322,20 @@ final class MavenProcessFactory implements ProcessCache.Factory { } public String getMavenOpts() { - String opts = mms.getMavenOpts(); - if (opts == null) - return null; - - for (String key : envVars.keySet()) - opts = opts.replace("${" + key + "}", envVars.get(key)); - - return opts; + return envVars.expand(mms.getMavenOpts()); } public MavenInstallation getMavenInstallation() { - return mms.getMaven(); + MavenInstallation mi = mms.getMaven(); + if (mi != null) mi = mi.forNode(getCurrentNode()).forEnvironment(envVars); + return mi; + } public JDK getJava() { - return mms.getJDK(); + JDK jdk = mms.getJDK(); + if (jdk != null) jdk = jdk.forNode(getCurrentNode()).forEnvironment(envVars); + return jdk; } /** diff --git a/core/src/main/java/hudson/model/JDK.java b/core/src/main/java/hudson/model/JDK.java index dcdd26cefb73cf7e9107140f676b60d0a2260239..5e32505d03965c90716ffbdadcd3b88e12e44384 100644 --- a/core/src/main/java/hudson/model/JDK.java +++ b/core/src/main/java/hudson/model/JDK.java @@ -27,6 +27,7 @@ import hudson.util.StreamTaskListener; import hudson.util.NullStream; import hudson.Launcher; import hudson.Extension; +import hudson.EnvVars; import hudson.slaves.NodeSpecific; import hudson.tools.ToolInstallation; import hudson.tools.ToolDescriptor; @@ -42,7 +43,7 @@ import java.util.List; * * @author Kohsuke Kawaguchi */ -public final class JDK extends ToolInstallation implements NodeSpecific { +public final class JDK extends ToolInstallation implements NodeSpecific, EnvironmentSpecific { @Deprecated // kept for backward compatibility - use getHome() instead private String javaHome; @@ -104,6 +105,10 @@ public final class JDK extends ToolInstallation implements NodeSpecific { return new JDK(getName(),ToolLocationNodeProperty.getToolHome(node, this)); } + public JDK forEnvironment(EnvVars environment) { + return new JDK(getName(), environment.expand(getHome())); + } + /** * Checks if "java" is in PATH on the given node. * diff --git a/core/src/main/java/hudson/tasks/Maven.java b/core/src/main/java/hudson/tasks/Maven.java index cb6e7bf6e96393bc69b2abdb27f55705ba26169a..492d3deb676fe0572dc6defc7dc1e20bd1129c25 100644 --- a/core/src/main/java/hudson/tasks/Maven.java +++ b/core/src/main/java/hudson/tasks/Maven.java @@ -209,13 +209,11 @@ public class Maven extends Builder { ArgumentListBuilder args = new ArgumentListBuilder(); MavenInstallation mi = getMaven(); - if (mi != null) { - mi = mi.forNode(Computer.currentComputer().getNode()); - } if(mi==null) { String execName = proj.getWorkspace().act(new DecideDefaultMavenCommand(normalizedTarget)); args.add(execName); } else { + mi = mi.forNode(Computer.currentComputer().getNode()); mi = mi.forEnvironment(env); String exec = mi.getExecutable(launcher); if(exec==null) { diff --git a/test/src/test/java/hudson/matrix/MatrixProjectTest.java b/test/src/test/java/hudson/matrix/MatrixProjectTest.java index 97a065c0d9ca50ad42acf89d9911fd3cf48ffc21..33195edb6138a8cedbfc8ad4de16a949c5106bfb 100644 --- a/test/src/test/java/hudson/matrix/MatrixProjectTest.java +++ b/test/src/test/java/hudson/matrix/MatrixProjectTest.java @@ -42,7 +42,8 @@ public class MatrixProjectTest extends HudsonTestCase { */ public void testBuildAxisInAnt() throws Exception { MatrixProject p = createMatrixProject(); - p.getBuildersList().add(new Ant("-Dprop=${db} test",null,null,null,null)); + Ant.AntInstallation ant = configureDefaultAnt(); + p.getBuildersList().add(new Ant("-Dprop=${db} test",ant.getName(),null,null,null)); // we need a dummy build script that echos back our property p.setScm(new SingleFileSCM("build.xml","assertion ${prop}=${db}")); diff --git a/test/src/test/java/hudson/tasks/EnvVarsInConfigTasksTest.java b/test/src/test/java/hudson/tasks/EnvVarsInConfigTasksTest.java index f864cf0adba76407fda0f7d3435e973793581618..bbd5eea6429d74efe7f603736855fe4b43fc89ac 100644 --- a/test/src/test/java/hudson/tasks/EnvVarsInConfigTasksTest.java +++ b/test/src/test/java/hudson/tasks/EnvVarsInConfigTasksTest.java @@ -1,6 +1,8 @@ package hudson.tasks; import hudson.EnvVars; +import hudson.maven.MavenModuleSet; +import hudson.maven.MavenModuleSetBuild; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import hudson.model.JDK; @@ -37,18 +39,14 @@ public class EnvVarsInConfigTasksTest extends HudsonTestCase { hudson.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(varMaven); // Ant with a variable in its path - // TODO: create HudsonTestCase.configureDefaultAnt() - String guessedAntHome = guessAntHome(); - if (guessedAntHome != null) { - AntInstallation antInstallation = new AntInstallation("varAnt", - withVariable(guessedAntHome)); - hudson.getDescriptorByType(Ant.DescriptorImpl.class).setInstallations(antInstallation); - } + AntInstallation ant = configureDefaultAnt(); + AntInstallation antInstallation = new AntInstallation("varAnt", + withVariable(ant.getHome())); + hudson.getDescriptorByType(Ant.DescriptorImpl.class).setInstallations(antInstallation); - // createSlaves + // create slaves EnvVars additionalEnv = new EnvVars(DUMMY_LOCATION_VARNAME, ""); slaveEnv = createSlave(new Label("slaveEnv"), additionalEnv); - slaveRegular = createSlave(new Label("slaveRegular")); } @@ -172,18 +170,35 @@ public class EnvVarsInConfigTasksTest extends HudsonTestCase { assertFalse(buildLogEnv.contains(DUMMY_LOCATION_VARNAME)); } - public static String guessAntHome() { - String antHome = EnvVars.masterEnvVars.get("ANT_HOME"); - if (antHome != null) - return antHome; + public void testNativeMavenOnSlave() throws Exception { + MavenModuleSet project = createMavenProject(); + project.setJDK(hudson.getJDK("varJDK")); + project.setScm(new ExtractResourceSCM(getClass().getResource( + "/simple-projects.zip"))); - // will break if PATH variable is not found (e.g. case sensitivity) - String[] sysPath = EnvVars.masterEnvVars.get("PATH").split( - File.pathSeparator); - for (String p : sysPath) - if (new File(p, "ant").isFile() || new File(p, "ant.bat").isFile()) - return new File(p).getParent(); + project.setMaven("varMaven"); + project.setGoals("clean${" + DUMMY_LOCATION_VARNAME + "}"); - throw new RuntimeException("cannot find Apache Ant"); - } + // test the regular slave - variable not expanded + project.setAssignedLabel(slaveRegular.getSelfLabel()); + MavenModuleSetBuild build = project.scheduleBuild2(0).get(); + System.out.println(build.getDisplayName() + " completed"); + + assertBuildStatus(Result.FAILURE, build); + + String buildLogRegular = build.getLog(); + System.out.println(buildLogRegular); + + // test the slave with prepared environment + project.setAssignedLabel(slaveEnv.getSelfLabel()); + build = project.scheduleBuild2(0).get(); + System.out.println(build.getDisplayName() + " completed"); + + assertBuildStatusSuccess(build); + + // Check variable was expanded + String buildLogEnv = build.getLog(); + System.out.println(buildLogEnv); + assertFalse(buildLogEnv.contains(DUMMY_LOCATION_VARNAME)); + } } diff --git a/test/src/test/java/hudson/tasks/MavenTest.java b/test/src/test/java/hudson/tasks/MavenTest.java index 24f9cfa4e859a2220187b2a5bd494fdb7a3bf279..93b340c979ce44cf9b64a560d4871290ae447ae7 100644 --- a/test/src/test/java/hudson/tasks/MavenTest.java +++ b/test/src/test/java/hudson/tasks/MavenTest.java @@ -30,11 +30,25 @@ import hudson.model.JDK; import hudson.model.ParametersDefinitionProperty; import hudson.model.Result; import hudson.model.StringParameterDefinition; +import hudson.model.AbstractProject; +import hudson.model.Job; +import hudson.model.AbstractBuild; +import hudson.model.Run; +import hudson.model.Cause; +import hudson.model.Action; +import hudson.model.ParametersAction; +import hudson.model.StringParameterValue; +import hudson.model.Cause.LegacyCodeCause; +import hudson.model.listeners.RunListener; import hudson.slaves.EnvironmentVariablesNodeProperty; import hudson.slaves.EnvironmentVariablesNodeProperty.Entry; import hudson.tasks.Maven.MavenInstallation; +import hudson.remoting.AsyncFutureImpl; import java.util.Collections; +import java.util.concurrent.Future; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; import junit.framework.Assert; @@ -47,92 +61,90 @@ import com.gargoylesoftware.htmlunit.html.HtmlPage; * @author Kohsuke Kawaguchi */ public class MavenTest extends HudsonTestCase { - /** - * Tests the round-tripping of the configuration. - */ - public void testConfigRoundtrip() throws Exception { - hudson.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(); // reset - - FreeStyleProject p = createFreeStyleProject(); - p.getBuildersList().add(new Maven("a", null, "b.pom", "c=d", "-e")); - - WebClient webClient = new WebClient(); - HtmlPage page = webClient.getPage(p, "configure"); - - HtmlForm form = page.getFormByName("config"); - submit(form); - - Maven m = p.getBuildersList().get(Maven.class); - assertNotNull(m); - assertEquals("a", m.targets); - assertNull("found " + m.mavenName, m.mavenName); - assertEquals("b.pom", m.pom); - assertEquals("c=d", m.properties); - assertEquals("-e", m.jvmOptions); - } - - public void testWithNodeProperty() throws Exception { - MavenInstallation maven = configureDefaultMaven(); - String mavenHome = maven.getMavenHome(); - String mavenHomeVar = "${VAR_MAVEN}" + mavenHome.substring(3); - String mavenVar = mavenHome.substring(0, 3); - MavenInstallation varMaven = new MavenInstallation("varMaven", - mavenHomeVar); - hudson.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(maven, varMaven); - - JDK jdk = hudson.getJDK("default"); - String javaHome = jdk.getJavaHome(); - String javaHomeVar = "${VAR_JAVA}" + javaHome.substring(3); - String javaVar = javaHome.substring(0, 3); - JDK varJDK = new JDK("varJDK", javaHomeVar); - hudson.getJDKs().add(varJDK); - Hudson.getInstance().getNodeProperties().replaceBy( - Collections.singleton(new EnvironmentVariablesNodeProperty( - new Entry("VAR_MAVEN", mavenVar), new Entry("VAR_JAVA", - javaVar)))); - - FreeStyleProject project = createFreeStyleProject(); - project.getBuildersList().add(new Maven("--help", varMaven.getName())); - project.setJDK(varJDK); - - Build build = project.scheduleBuild2(0).get(); - - Assert.assertEquals(Result.SUCCESS, build.getResult()); - - } - - public void testWithParameter() throws Exception { - MavenInstallation maven = configureDefaultMaven(); - String mavenHome = maven.getMavenHome(); - String mavenHomeVar = "${VAR_MAVEN}" + mavenHome.substring(3); - String mavenVar = mavenHome.substring(0, 3); - MavenInstallation varMaven = new MavenInstallation("varMaven", - mavenHomeVar); - hudson.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(maven, varMaven); - - JDK jdk = hudson.getJDK("default"); - String javaHome = jdk.getJavaHome(); - String javaHomeVar = "${VAR_JAVA}" + javaHome.substring(3); - String javaVar = javaHome.substring(0, 3); - JDK varJDK = new JDK("varJDK", javaHomeVar); - hudson.getJDKs().add(varJDK); - - FreeStyleProject project = createFreeStyleProject(); - project.addProperty(new ParametersDefinitionProperty( - new StringParameterDefinition("VAR_MAVEN", "XXX"), - new StringParameterDefinition("VAR_JAVA", "XXX"))); - project.getBuildersList().add(new Maven("--help", varMaven.getName())); - project.setJDK(varJDK); - - WebClient webClient = new WebClient(); - webClient.getPage(project, "buildWithParameters?VAR_MAVEN=" + mavenVar - + "&VAR_JAVA=" + javaVar); - - Thread.sleep(2000); - - Build build = project.getLastBuild(); - - Assert.assertEquals(Result.SUCCESS, build.getResult()); - - } + /** + * Tests the round-tripping of the configuration. + */ + public void testConfigRoundtrip() throws Exception { + hudson.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(); // reset + + FreeStyleProject p = createFreeStyleProject(); + p.getBuildersList().add(new Maven("a", null, "b.pom", "c=d", "-e")); + + WebClient webClient = new WebClient(); + HtmlPage page = webClient.getPage(p, "configure"); + + HtmlForm form = page.getFormByName("config"); + submit(form); + + Maven m = p.getBuildersList().get(Maven.class); + assertNotNull(m); + assertEquals("a", m.targets); + assertNull("found " + m.mavenName, m.mavenName); + assertEquals("b.pom", m.pom); + assertEquals("c=d", m.properties); + assertEquals("-e", m.jvmOptions); + } + + public void testWithNodeProperty() throws Exception { + MavenInstallation maven = configureDefaultMaven(); + String mavenHome = maven.getMavenHome(); + String mavenHomeVar = "${VAR_MAVEN}" + mavenHome.substring(3); + String mavenVar = mavenHome.substring(0, 3); + MavenInstallation varMaven = new MavenInstallation("varMaven", + mavenHomeVar); + hudson.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(maven, varMaven); + + JDK jdk = hudson.getJDK("default"); + String javaHome = jdk.getJavaHome(); + String javaHomeVar = "${VAR_JAVA}" + javaHome.substring(3); + String javaVar = javaHome.substring(0, 3); + JDK varJDK = new JDK("varJDK", javaHomeVar); + hudson.getJDKs().add(varJDK); + Hudson.getInstance().getNodeProperties().replaceBy( + Collections.singleton(new EnvironmentVariablesNodeProperty( + new Entry("VAR_MAVEN", mavenVar), new Entry("VAR_JAVA", + javaVar)))); + + FreeStyleProject project = createFreeStyleProject(); + project.getBuildersList().add(new Maven("--help", varMaven.getName())); + project.setJDK(varJDK); + + Build build = project.scheduleBuild2(0).get(); + + Assert.assertEquals(Result.SUCCESS, build.getResult()); + + } + + public void testWithParameter() throws Exception { + MavenInstallation maven = configureDefaultMaven(); + String mavenHome = maven.getMavenHome(); + String mavenHomeVar = "${VAR_MAVEN}" + mavenHome.substring(3); + String mavenVar = mavenHome.substring(0, 3); + MavenInstallation varMaven = new MavenInstallation("varMaven", + mavenHomeVar); + hudson.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(maven, varMaven); + + JDK jdk = hudson.getJDK("default"); + String javaHome = jdk.getJavaHome(); + String javaHomeVar = "${VAR_JAVA}" + javaHome.substring(3); + String javaVar = javaHome.substring(0, 3); + JDK varJDK = new JDK("varJDK", javaHomeVar); + hudson.getJDKs().add(varJDK); + + FreeStyleProject project = createFreeStyleProject(); + project.addProperty(new ParametersDefinitionProperty( + new StringParameterDefinition("VAR_MAVEN", "XXX"), + new StringParameterDefinition("VAR_JAVA", "XXX"))); + project.getBuildersList().add(new Maven("--help", varMaven.getName())); + project.setJDK(varJDK); + + Build build = project.scheduleBuild2(0, new LegacyCodeCause(), + new ParametersAction( + new StringParameterValue("VAR_MAVEN", mavenVar), + new StringParameterValue("VAR_JAVA", javaVar))).get(); + + assertBuildStatusSuccess(build); + + } + }